Detect a process exit in C# - c#

I've an application which does
Process.Start()
to start another application 'firefox.exe'. I want to wait till that application ends (process dies) and continue my execution (example: Show a messagebox). There may be multiple instances of the application 'firefox.exe' running at the same time.
I have try WaitForExit and HasExited, but it return true right after firefox process start, so that the Messagebox show immediately.
How can i Show the messagebox in this situtation.
Update 1:
I tried this:
Process browser = new Process();
browser= Process.Start(#"dist\bin\firefox.exe");
browser.StartInfo.UseShellExecute = false;
browser.WaitForExit();
MessageBox.Show("AAAA!!!");
and HasExited similarly with EventRaising.
Update 2:
I have tried with many Simple Program like Notepad.exe, cmd.exe... All of them worked well. I think that Firefox call another process before running the main process and closing the original process. How can i bypass this problem.

If you can be certain that no firefox instance is already running you can simply use Process.GetProcessesByName("firefox"); and use WaitForExit on these processes.
If you want to handle multiple concurrent firefox instances you have a bit of a problem since firefox manages multiple processes in its own special ways. When you start firefox it might just ask the existing firefox process to create a new window and then quit. So you would need to detect new windows and monitor when this window is closed. I do not think there is any way to accomplish what you want simply by waiting on processes, at least not without cooperation by the program.
In the end I would try to do whatever you are trying to accomplish some other way. Perhaps you can host a webcontrol inside the application? Or perhaps embed a copy of Firefox Portable or some other stand alone browser in your application and start that instead?

Related

C# - Open an app as second process in the Task Manager

I want to open an different app and to appears like it's an process of the app itself and don't appear as a different one in the task manager processes list.
Something like:
Can Process.Start() do it?
Solved!
Well it seems that always when an app starts a process, the main app it'll be its parent. I didn't knew that :)
Using Process.Start with a ProcessStartInfo and ensuring UseShellExecute is false should probably do it. However, the process being launched may do something that breaks this behavior. It could, for example, just be a stub launcher that starts another process then quits.

Right way to run, kill and keep process running

In my application, which using another application (run in tray) to print receipts I need to do those three things:
Open process when on mainApplication startup
Close process when mainApplication closing or changing any information about printer
Keep process alive, if it get any error
First point is quiet easy, I just simply
Process.Start("_ReceiptPrinter.exe");
And process working ;)
But now, the two other issues:
Closing process. I've tried this code:
Process[] allProcs = Process.GetProcesses();
foreach (Process proc in allProcs)
{
ProcessThreadCollection myThreads = proc.Threads;
if (proc.ProcessName == "_ReceiptPrinter")
{
proc.Close();
}
}
Unfortunately, I can still see icon in tray, and process is still running.
Keep process alive. My main application is in WPF, that one from tray is written on WinForms. Maybe there is any way to handle ANY WinForm application exit event (well, any, but not this one, which just simply close it from another application), and reopen it?
proc.Close() asks it to close but there is no guarantee. Use:
proc.Kill();
The reason you still see a tray icon is that the icons are cached by an external process (windows explorer.)
The reason process.Close() does not close the application is because the application is not processing window messages (as this call simulates a WM_CLOSE request, per classic Windows API.)
The proper way to close the application is process.Close, not process.Kill(), further, as part of app/window close you need to unregister any tray icons you've registered with the system. This way any normal closure of your application will properly clean-up the tray.
Further, you can use a "critical finalizer" which would be guaranteed to run before application exit, except in total catastrophe scenarios.

Handling a forced exit

Is there any good way to handle a forced exit in C#?
I have a formless C# application that talks to an LCD over serial. Once the application is running, the only way to kill it is with task manager. The trouble with this is that the program needs to turn the LCD off when it is done, and it doesn't look as if my Application.ApplicationExit event is ever fired in this condition.
Any ideas?
Once the application is running, the only way to kill it is with task manager.
My big idea would be to change this.
Stick an icon in the notification area that the user can use to shut your app down properly, or set it up so that running the app again will instead shut down an already-running instance if one exists, or any other way that sounds like a good idea.
Requiring a user to use Task Manager to shut down your application screams poor design.
Write a code in your program loop (with a timer perhaps) to read a file or a registry key. For example if a file at C:\YOURPROGRAM\CLOSEME contains text "closeme", close your program gracefully. Write another program that write that C:\YOURPROGRAM\CLOSEME file. So, whenever you want to shutdown your program, don't use taskmanager, instead, open second program.
Some options:
Write a separate process with a GUI that can start and stop the main process. For example, when you install the Apache web server on Windows the server itself is installed as a service. It can be started and stopped from the system services management panel, but it also comes with a "monitor" process that sits in the notification area, tells you whether Apache is running and lets you start or stop it manually.
If it's acceptable for your use-case, make the application a console application. You can register a handler for when the user presses CTRL+C (see Console.CancelKeyPress) that performs your cleanup before your process exits. This still won't let you handle someone killing the process from Task Manager, but it's very easy to do and might be good enough depending on your situation.

Starting and stopping firefox from c#

When I start
/Applications/Firefox.app/Contents/MacOS/firefox-bin
on MacOSX using Process.Start() using Mono, the id of the process that gets returned does not match the process that firefox ends up running under.
It looks like firefox quickly decides to start another process, and kill the current one.
This makes it difficult to stop firefox, and to detect if it is still running. I've tried starting firefox using the -no-remote flag, to no avail.
Is there a way to start firefox in such a way that it doesn't do this "I'll quickly make a new process for you" dance?
The situation can somewhat be detected by making sure Firefox keeps on running for at least 3 seconds after its start, and when it does not, scan for other firefox processes. However, this technique is shaky at best, as on slow days it might take a bit more than 3 seconds, and then all tests depending on this behaviour fail.
It turns out, that this behaviour only happens when asking firefox to start a specific profile using -P MyProfile. (Which I need to do, as I need to start firefox with specific proxyserver settings) If I start firefox "normally" it does stick to its process.
When using mozilla programmatically / embedding in other apps you should use the provided components:
"The right way" as recommended by mozilla ...
https://developer.mozilla.org/en/XPCOM
"The easy way", general consensus from Mozilla dev guys ...
http://www.iol.ie/~locka/mozilla/control.htm
Need to "execute processes", simply instantiate an instance of the component and talk to that, you should then have everything you need.
However ...
If you really do insist on looking after the actual process for a firefox instance, you may want to call
Process.Start("...\firefox.exe");
Then try this (i believe this works on MAC OS too) ...
C#/mono: get list of child processes on Windows and Linux
The basic idea / thought pattern being that if it is in fact executing another process right away you should be able to find that as would be a "child" process instead of being just one from a list in the "task list" / process manager for the machine.
In case you are ok with the detection of Firefox process itself but don't know when you should start the detection, you can use the Process.Exited event. Don't forget to set EnableRaisingEvents first.
I suggest taking a different approach: list all running processes, find Firefox, get it's process ID and (optional) see if it is the one you started.
I'm not sure if there's a platform-independent way to accomplish this. On Linux, you can call "ps -ef" to list them, on Windows it's called "tasklist".
I don't have a Mac, so I can't be sure, but if it's anything like Linux the firefox 'binary' is actually a shell script which sets up a bunch of required environment variables and checks if firefox is already running (if it is, it will try and add a new tab to the existing instance, as far as I know).
You may be able to capture the new PID within the script, although if you update it do beware of it being overwritten during upgrades.

How can I recover a reference to a process that has been relaunched?

Using Process.Start, I am starting various IE8 and Firefox (3.5) processes which I keep a Process instance for.
A little while later in the application, I'll use the Process instances' MainWindowHandle property to target the window for use with some platform API functions via P/Invoke.
However, both IE8 and Firefox will kill the second process I start, then restart it using the first. This means that my Process instance now refers to a closed process, and so HasExited is true and MainWindowHandle is equal to IntPtr.Zero.
Here's an example of what happens (I'm using IE8 for this example):
Process.Start is called with "iexplore.exe"
Process starts and continues running
Process.Start is called again with "iexplore.exe"
First process continues running, but the second is killed immediately
Another iexplore process is started (presumably by the first iexplore process).
During this time, the user sees the second IE window only after the second process is killed and restarted.
I understand why these browsers behave this way, but it does create a problem for me if I want to control the created process later on.
Has anyone come across this problem before? How would you recommend getting a reference to the process back? I thought about using GetProcessesByName and iterating through their window titles, but unfortunately the titles may be the same as the first process launched.
Note: IE8 was the first version of IE to use process separation and so only IE8 behaves this way, I don't have this problem with IE7, unfortuantely I need IE8 support as well.
I have used the Running Object Table (ROT) in the past to find a specific process and control it.
http://www.codeproject.com/KB/COM/ROTStuff.aspx

Categories

Resources