13

I'm trying to Close a process within C# but how do I check if is open first? Users asked for this feature and some of them will be still using the close button of the other process.

So, right now works fine:

Process.GetProcessesByName("ProcessName")[0].CloseMainWindow(); 

Now, how do I check first that it exists, this doesn't work:

if ( Process.GetProcessesByName("ProcessName")[0] != null ) {...} 
0

6 Answers 6

20

Try this to avoid the race condition in which a process closes after the first call to GetProcessesByName:

Process[] processes = Process.GetProcessesByName("ProcessName"); if (processes.Length > 0) processes[0].CloseMainWindow(); 
Sign up to request clarification or add additional context in comments.

Comments

9

If you're planning to deploy this application on a wide range of machines, you will want to know that this code can sometimes fail.

The Process class in .NET is based on Windows performance counters, which on some machines can be disabled through the registry. When this happens, the call to the Process.GetProcessesByName method will throw an exception.

I think this situation is typical for machines with various "clean up / performance tuning" applications which, among other stuff, disable the performance counters in order to supposedly improve the machine's performance.

In the past this has repeatedly caused me pain with some percentage of my customers' client machines, which led me to explore other (if somewhat limited or cumbersome) alternatives, like making calls to Win API directly using PInvoke to iterate over the processes.

Another possible solution would be to ensure that your installer or application enables performance counters, or at least knows how to deal with them being disabled.

2 Comments

Thanks for the advise Ran, I appreciate the time you are saving me.
For this project, I'll be better only catching the exception. I'm pretty sure in some labs performance counters are disabled and it won't be a good idea to mess with the admin decisions. Thanks again.
6

How about

if (Process.GetProcessesByName("ProcessName").Length > 0) {...} 

2 Comments

I think a race condition may be hiding inside that elipsis!
@Jeffrey L Whitledge: Good catch. My focus was too narrow.
4

You could also just loop, which works fine if there aren't any.

foreach(Process p in Process.GetProcessesByName("ProcessName")) { p.CloseMainWindow(); } 

Comments

2
Process.GetProcessesByName("ProcessName").FirstOrDefault() != null 

5 Comments

Thank you Jani, I'll prefer the Andy advise, because it doesn't use linq
@romkyns using (var process = Process.GetProcessesByName("").FirstOrDefault()) { if(process !=null) { } } make even more sense :-)
@Jani if that was humor then I didn't get it, sorry :)
@romkyns No it's not totally joke, maybe you need the reference to the process you're looking for so I think this approach is actually fits.
@Jani ok got it. FirstOrDefault makes sense in that context, but your answer alone really made me wonder why not just use "Any".
1

You could use GetProcessesByName like so:

foreach(var application in Process.GetProcessesByName("ApplicationName")) { application.CloseMainWindow(); } 

If you meant to kill the application, then you could do this instead:

foreach(var application in Process.GetProcessesByName("ApplicationName")) { application.Kill(); } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.