0

I'm trying to open a file through my app, and monitor when the users closes the app. I'm using the below to open a file, and monitor when it closes:

Dim NewProcess As New Process
NewProcess.EnableRaisingEvents = True
AddHandler NewProcess.Exited, AddressOf Process_Exited
NewProcess.StartInfo.FileName = "c:\test.txt"
NewProcess.Start()

Private Sub Process_Exited(sender As Object, e As EventArgs)
Console.WriteLine("App Exited @ " & DateTime.Now)
End Sub

The above works properly for eg txt files opened in notepad. But when trying for other kind of files, eg. a .png file, the process is started and disposed immediately, while not even triggering the Process_Exited sub. As far as I can tell, it calls another process (which opens the file) and kills itself immediately. The new process is not a child process of the original, it's an entirely separate process.

How can I get the new process(processes) and check if they have closed? I would like to avoid getting a collection of processes before and after calling process.start, I think that it will not work properly if a random other process starts at the exact same time.

A workaround I tried was to open the application directly, using process.start(pathtoexe, pathtofile), but this can be problematic on its own, as I have to manually read the associated application from the registry, separate any default arguments the shell may be passing to the application, and inject them in front of the path to the file, hoping that the application accepts a filepath as a parameter.

Any suggestions? Thanks in advance

drakoniko
  • 1
  • 2
  • You are correct, when you use Process.Start() to open the application associated to a file extension, the actual Process may be run by a stub or rundll32.exe or the new Process is terminated immediately and associated with an existing Process (e.g., the MS Office Applications). You can find a description of a workaound here: [Process.Start a file without Extension](https://stackoverflow.com/a/47763682/7444103). – Jimi Jan 13 '21 at 14:24
  • Since you're probably starting processes that *show something* (hence, have a Window, you could use UI Automation). The WindowOpened and WindowClosed events of the WindowPattern notify you when a Window in the System is opened and closed. An example here: [Add an event to all Forms in a Project](https://stackoverflow.com/a/51505218/7444103). That sample code is kept somewhat *generic* on purpose. It can actually detect any Window that is opened in the System, so it needs very few changes to make it detect any of the Windows you care about (Console apps also have a Window). – Jimi Jan 13 '21 at 14:24
  • Hi Jimi, thanks for your suggestions. Using UI Automation to get new Windows (forms) will have the same problem as reading all processes: it does not account for any rogue processes/windows that might open in the meantime. While it's most certainly a viable workaround, I don't really want to use it. Using the other workaround you suggested (in Process.Start a file without Extension) is kinda over my head. I explored a similar approach but proved problematic (eg I have an application which is called as such ""C:\Program Files (x86)\Dia\bin\dia-win-remote.exe" diaw.exe --integrated %1") – drakoniko Jan 13 '21 at 15:34
  • UI Automation's Window Pattern doesn't work with processes, it works with Windows. It doesn't matter if the starting process is closed after a new Window is opened, since you only care about the Window, not the Process that owns it or starts it. UI Automation raises an event when a Window is opened or closed. If you want to know about the Process that owns the Window you care about, you can ask the AutomationElement that is passed as argument to the Events. – Jimi Jan 13 '21 at 15:35

0 Answers0