C
C#2y ago
Core Dream

❔ Enumerating Running Processes

I am missing something, besides brain cells but what should I be returning if I want a ComboBox to have the list of Windows processes?
internal class ProcessHelpers
{
public static List<string> RunningProcessList = new();

public static string GetRunningProcesses()
{
Process[] processes = Process.GetProcesses().Where(p => (long)p.MainWindowHandle != 0).ToArray();

foreach (Process process in processes)
{
RunningProcessList.Add(process.ProcessName);
}

return List<string> RunningProcessList;
}
}
internal class ProcessHelpers
{
public static List<string> RunningProcessList = new();

public static string GetRunningProcesses()
{
Process[] processes = Process.GetProcesses().Where(p => (long)p.MainWindowHandle != 0).ToArray();

foreach (Process process in processes)
{
RunningProcessList.Add(process.ProcessName);
}

return List<string> RunningProcessList;
}
}
83 Replies
ero
ero2y ago
there is so much wrong here
Core Dream
Core DreamOP2y ago
? I thought List<T> would be good here, maybe not. Was making a task manager kind of thing for a tech app
Servator
Servator2y ago
I would pass Processes to List instead of string then use comboBox.DisplayMember to show ProcessName
Core Dream
Core DreamOP2y ago
What do you mean?
Servator
Servator2y ago
1 sec let me show you
Core Dream
Core DreamOP2y ago
I do have a List ok
ero
ero2y ago
you're using a GetX() method instead of a property; you're just constantly adding more things to the RunningProcessList without ever clearing it; you're not disposing the processes!!; your return syntax is completely gibberish; the above leads me to believe you're not even using a proper IDE, or have never done any kind of c# tutorial
Core Dream
Core DreamOP2y ago
I was following a tutorial on YT
ero
ero2y ago
your return type is also string, when RunningProcessList is a List<string>
Core Dream
Core DreamOP2y ago
as usual, should of used ChatGPT instead lol
ero
ero2y ago
jesus christ no also it's "should have"
Core Dream
Core DreamOP2y ago
it did help me solve a issue 2 days ago 🙂 w/o googling for 40 hrs sec i will check ms's site for process examples
Servator
Servator2y ago
comboBox1.DataSource = Process.GetProcesses();

comboBox1.DisplayMember = "ProcessName";
comboBox1.DataSource = Process.GetProcesses();

comboBox1.DisplayMember = "ProcessName";
It just works
Core Dream
Core DreamOP2y ago
Oh, that's ALL I needed? 😂
ero
ero2y ago
internal static class ProcessHelpers
{
public static List<string> RunningProcesses
{
get
{
var ret = new List<string>();
var processes = Process.GetProcesses().Where(p => p.MainWindowHandle != 0 && !p.HasExited);

foreach (var process in processes)
{
ret.Add(process.ProcessName);
process.Dispose();
}

return ret;
}
}
}
internal static class ProcessHelpers
{
public static List<string> RunningProcesses
{
get
{
var ret = new List<string>();
var processes = Process.GetProcesses().Where(p => p.MainWindowHandle != 0 && !p.HasExited);

foreach (var process in processes)
{
ret.Add(process.ProcessName);
process.Dispose();
}

return ret;
}
}
}
Servator
Servator2y ago
Core Dream
Core DreamOP2y ago
ah the getter/setter stuff 🙂
ero
ero2y ago
you need to dispose of the processes
Core Dream
Core DreamOP2y ago
Wait so which one do I need now?
ero
ero2y ago
otherwise you're building up more and more memory
Core Dream
Core DreamOP2y ago
Hmm makes sense, garbage collection Ero's is easier, 2 lines 🙂 I will try both ways and see what one is effective , since i probably will grab the id too
Servator
Servator2y ago
Using Property is okay but only returning ProcessName doesn't make sense Using DisplayMember and ValueMember is better
Core Dream
Core DreamOP2y ago
Yes, I need ID too ok so use yours? i dont wanna have another stackoverflow day heh the large example doesnt work
Servator
Servator2y ago
Core Dream
Core DreamOP2y ago
Operator '!=' cannot be applied to operands of type 'IntPtr' and 'int'
Servator
Servator2y ago
Servator
Servator2y ago
Servator
Servator2y ago
See I can get id Because i pass Process itself
Core Dream
Core DreamOP2y ago
Wait so do I use the example they gave but use DataSource and MemberName?
ero
ero2y ago
no, you would have to do it a bit differently
Core Dream
Core DreamOP2y ago
What would I need to change?
public static List<string> RunningProcess

{
get
{
var ret = new List<string>();
var processes = Process.GetProcesses().Where(p => p.MainWindowHandle != 0 && !p.HasExited);

foreach ( var process in processes )
{
ret.Add(process.ProcessName);
process.Dispose();
}

return ret;
}
}
public static List<string> RunningProcess

{
get
{
var ret = new List<string>();
var processes = Process.GetProcesses().Where(p => p.MainWindowHandle != 0 && !p.HasExited);

foreach ( var process in processes )
{
ret.Add(process.ProcessName);
process.Dispose();
}

return ret;
}
}
class side
ero
ero2y ago
internal static class ProcessHelpers
{
private static readonly List<Process> _processCache = new(16);

public static List<Process> RunningProcesses
{
get
{
foreach (var process in _processCache)
{
process.Dispose();
}

_processCache.Clear();

var processes = Process.GetProcesses().Where(p => p.MainWindowHandle != 0 && !p.HasExited);
foreach (var process in processes)
{
_processCache.Add(process);
}

return _processCache;
}
}
}
internal static class ProcessHelpers
{
private static readonly List<Process> _processCache = new(16);

public static List<Process> RunningProcesses
{
get
{
foreach (var process in _processCache)
{
process.Dispose();
}

_processCache.Clear();

var processes = Process.GetProcesses().Where(p => p.MainWindowHandle != 0 && !p.HasExited);
foreach (var process in processes)
{
_processCache.Add(process);
}

return _processCache;
}
}
}
something like this it's not that pretty, but you have to dispose of the process objects
Core Dream
Core DreamOP2y ago
yes the example has that now var processes = Process.GetProcesses().Where(p => p.MainWindowHandle != 0 && !p.HasExited); this isnt going to work with IntPtr/int CS0019 Operator '!=' cannot be applied to operands of type 'IntPtr' and 'int'
ero
ero2y ago
yes it is, on .net 7, which you should be using
Core Dream
Core DreamOP2y ago
Why 7? I'm on 6
Servator
Servator2y ago
comboBox1.DataSource = Process.GetProcesses()
.Where(p => p.MainWindowHandle != IntPtr.Zero)
.ToArray();

comboBox1.DisplayMember = "ProcessName";
comboBox1.DataSource = Process.GetProcesses()
.Where(p => p.MainWindowHandle != IntPtr.Zero)
.ToArray();

comboBox1.DisplayMember = "ProcessName";
ero
ero2y ago
because it's the most up to date...?
Servator
Servator2y ago
Use IntPtr.Zero
MODiX
MODiX2y ago
Ero#1111
REPL Result: Success
IntPtr.Zero == 0
IntPtr.Zero == 0
Result: bool
True
True
Compile: 406.433ms | Execution: 28.379ms | React with ❌ to remove this embed.
Core Dream
Core DreamOP2y ago
Yes but I need yo support Windows 7 still for some legacy people
ero
ero2y ago
no you don't
Core Dream
Core DreamOP2y ago
ty
ero
ero2y ago
also???? .net 7 definitely works on win7
Core Dream
Core DreamOP2y ago
oh ok .net 7 it is how do I add it? I'm on VS 2022 Community
ero
ero2y ago
should just be in the installer
ero
ero2y ago
Core Dream
Core DreamOP2y ago
ty Wonder why VS 2022 is still Preview , or is that still a thing?
ero
ero2y ago
the preview is always gonna be ahead of stable preview and stable are different builds basically
Core Dream
Core DreamOP2y ago
I don't need to keep 2019 still right? I got both
ero
ero2y ago
nah you can uninstall that
Core Dream
Core DreamOP2y ago
ok as long as 2022 is stable enough then, np I have to relearn .NET now, 7 is new
ero
ero2y ago
there is basically no difference
Core Dream
Core DreamOP2y ago
Ah, just a new # then What is a good video tutorial to watch these days without selling my kidney? Tim Corey is cool but I don't have a job atm.
ero
ero2y ago
no clue. i've never used any tutorials
Core Dream
Core DreamOP2y ago
I appreciate the help regardless @Ero and @Samarichitane, thanks. 🙂 Updating VS 2022 and will remove 2019 too
Servator
Servator2y ago
You can use
.Where(p => p.MainWindowHandle is not (nint)0);
.Where(p => p.MainWindowHandle is not (nint)0);
too
Core Dream
Core DreamOP2y ago
that would make sense, its similar to != 0 so i can understand it welp, time to learn .net 7 and WPF im happy to see WPF has the new tech where you can have source generators now makes stuff easier
jcotton42
jcotton422y ago
props like this are generally considered to be quite smelly it should be a method
ero
ero2y ago
why would that be? new list every time? too much work for 1 unit?
jcotton42
jcotton422y ago
stare do not do this getting a prop should not have side effects
ero
ero2y ago
what side effects would this possibly have?
jcotton42
jcotton422y ago
prop gets should be cheap, side-effect free, and the same value as last time unless something caused it to change diposing the processes returned by the last get of the prop
ero
ero2y ago
i don't get how that's bad
jcotton42
jcotton422y ago
you're also returning a private list, allowing it to be fucked with
ero
ero2y ago
i mean the whole class is internal i expect it to only be used by people who know what they're doing
jcotton42
jcotton422y ago
var procs = RunningProcesses;
// somewhere else
var procs2 = RunningProcesses;
// oops procs is now silently invalid, have fun debugging that
var procs = RunningProcesses;
// somewhere else
var procs2 = RunningProcesses;
// oops procs is now silently invalid, have fun debugging that
ero
ero2y ago
return it .AsReadOnly() for all i care
jcotton42
jcotton422y ago
doesn't matter code should be resilient
ero
ero2y ago
can't argue with that still just don't deem it a big deal is all
jcotton42
jcotton422y ago
it's bad code this would not pass even the thinnest of code reviews when I do a get on a property, I do not expect it to have surprising side effects
Mayor McCheese
get should have zero side effects plus; there is an expectation of immediacy on a get
Servator
Servator2y ago
What if with expression bodied property ?
jcotton42
jcotton422y ago
that's not any different
public string Foo { get { return "blah"; } }
public string Foo { get { return "blah"; } }
is the same as
public string Foo => "blah";
public string Foo => "blah";
Servator
Servator2y ago
i guess u r right
clxs
clxs2y ago
It would be less bad if you only disposed the processes which needed it, there's not much point of a cache if the entire thing is invalidated every use. Note, you don't really need to Dispose them. The finalizer will do that on GC. It's good to do so, but you won't leak if not
ero
ero2y ago
well, the idea i got from this was that yes, the whole point is that it will get invalidated every use; every time it gets called, it needs to re-get the processes, in case there are new ones, or ones that closed.
clxs
clxs2y ago
If you wanted to be really safe a solution would be to wrap it in your own disposable container. Notepad code following
class DisposableList<T> : List<T>, IDisposable where T : IDisposable
{
DisposableList(){}
DisposableList(IEnumerable<T> items)
: base(items)
{
}

void Dispose() => this.ForEach(i => i?.Dispose());
}

DisposableList<Process> RunningProcesses => new(Process.GetProcesses());

using var processes = RunningProcesses;
class DisposableList<T> : List<T>, IDisposable where T : IDisposable
{
DisposableList(){}
DisposableList(IEnumerable<T> items)
: base(items)
{
}

void Dispose() => this.ForEach(i => i?.Dispose());
}

DisposableList<Process> RunningProcesses => new(Process.GetProcesses());

using var processes = RunningProcesses;
Imo that's just overkill though
Core Dream
Core DreamOP2y ago
oh :x no idea what half the stuff is, like DisposibleList, must be new for 7 but will check it out
clxs
clxs2y ago
Its my own class, I define it in that block
Core Dream
Core DreamOP2y ago
Can I borrow it? Will add credit.
clxs
clxs2y ago
Sure, but please dont credit it's not great lul
Core Dream
Core DreamOP2y ago
What is great anymore? LUL many changes in programming and now there's AI taking jobs lol
Accord
Accord2y ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server