How to determine if a process is associated with a System.Diagnostics.Process object?

For a specific System.Diagnostics.Process that has been assigned values ​​to its .FileName and .Arguments , which is the best way to determine if this is:

  • ever issued the command .Start() or
  • is currently associated with the process in general?

If .Start() has never been .CloseMainWindow() , calling .CloseMainWindow() throws an InvalidOperationException, which I would like to avoid.

+4
source share
3 answers

Have you tried checking Process.Id and one of the Exit properties?

Link

In response to the comments on the posters: may you have to wrap the attempt / trick, and the exception is not the one started? It's not beautiful!

+2
source

If you close the process by calling .CloseMainWindow() , moving the call to the try / catch block is the right thing.

Do it:

 try { process.CloseMainWindow() } catch (InvalidOperationException) { // purposely do nothing here - the process exited before we told it to. } 

This is due to the fact that checking the properties of the process before closing the process creates a race condition: both checking the properties and calling .CloseMainWindow() participate in races to see which ones can finish first.

Consider this series of events:

  • Process is running
  • Your code calls process.HasExited and gets false
  • The process ends independently, upon completion
  • Since the second step returned false , your code calls process.CloseMainWindow() and gets an InvalidOperationException: Process has exited, so the requested information is not available.

No amount of acceleration of your code, neither the use of locks, nor any other strategy can guarantee that the process will not exit after your if . There is always a race condition. Use try/catch instead.

If you need to keep track of whether a process has been started, you might want to wrap the process in its class. You can use the lock when the process starts and set the boolean flag to indicate that it was running.

 class ProcessWrapper { public HasStarted; public ProcessWrapper(Process p, ProcessStartInfo psi) { // do argument and filename validation etc. here lock(HasStarted) { p.Start(psi); HasStarted = true; } } } 
+2
source

You can try and check

 process.StartTime & process.HasExited process.Handle 

or maybe use

 process.WaitForExit 
-1
source

Source: https://habr.com/ru/post/1310439/


All Articles