I wrote a program launching and monitoring and generally manage other programs. In the general case I prepare a System.Diagnostics.ProcessStartInfo and invoke Process.Start. Later I start one thread per program that's checking periodically the resulting Process object.
For testing propuses I configured my programm on my Win 7 machine to launch and monitor some typical Windows tools: Notepad, Paint and the Calculator. That all worked fine.
On a Windows 10 machine however the calculator behaves differently. The process started by Process.Start immediately terminates, and there is no calc.exe child to my launcher, but a win32calc.exe child to explorer.exe. child to a non existing process, the process my launcher created.
Why is that? How do I get a handle to that? What would be a strategy to monitor programs started by my launcher, even if they choose to abandon their parent?
A sort-of answer:
calc.exe launches the actuall process and then kills itself. Process groups could handle this: I could create a process group and monitor that.
However this was only a test and i monitor only applications that don't do that, I won't do that.
Related
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?
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.
I have an application that is automatically shut down when a certain event occurs.
When the application is shut down this way the very last thing my application does is to tell Windows to shut down as well.
The shutdown of Windows is done by calling the following:
private void OnProcessExit(object sender, EventArgs e)
{
//If class level flag set shut down Windows with a delay of xx seconds
if (shutdownWindowsOnExit)
System.Diagnostics.Process.Start("shutdown", "/s /t 30");
}
The user must be able to cancel the shutdown of Windows after my application has shut down, which is why the delay of 30 seconds is defined.
To accomplish this I just placed a regular shortcut on the desktop, which then called the following when pressed (cancels Windows shutdown):
C:\Windows\System32\shutdown.exe /a
What I want is to get rid of the shortcut and implement the canceling code in something that appears (for the user) to belong to my application (that has just been closed).
I have considered to simply create a small separate application which would consist of a form with a button stating "Press here to cancel Windows shutdown".
I could then start this small application from my main application right after calling
System.Diagnostics.Process.Start("shutdown", "/s /t 30");
This way I would be very sure that my main application was safely shutdown, and that only the small auxilary application would be terminated by Windows upon Windows shutdown.
I know that one can comprise two projects in one solution in Visual Studio, but it feels a bit overkill to create a separate project (with settings.settings file, app.config file, version control etc.) to create this little auxilary program.
My question now is:
Can I in some way code and compile this separate form to a separate .exe file within my existing project in Visual Studio, without the need of two complete separate projects in one solution.
Thanks for any help in advance!
Why not do the following flow :
Perform all needed shutdown processes (minus killing the app),
Close the main form and open new form with a timer and a cancel button
When timer is up kill the application and shutdown windows
If the user cancels kill the application but do not shutdown windows
when terminating the application ensure no background threads are still running to avoid
"The application was not shut down properly"
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.
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.