WinForm Application -> End Process -> FormClosing() & FormClosed() events Not Fired - c#

I have a started win-form application with some codes in FormClosing() & FormClosed() events.
With another application i want to forcibly close that first application like this :
string procId = proc.Id.ToString();
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = "taskkill.exe";
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.Arguments = "/f /t /pid " + procId;
Process.Start(startInfo);
When i want for forcibly close first application by those codes or using with Task Manager -> End Process , FormClosing() & FormClosed() events are not fired.
How can i force those events to fire in every situation or what is the solution?

See Prevent C# app from process kill.
You cannot prevent your app's process being terminated, and you won't get an event it is being terminated.
So you must cater for the case where a process didn't clean up nicely at shutdown. For that matter, you need to do that anyway, what if the machine BSODs while your app is running? You can never assume the previous instance completed successfully.
It looks like your app closes some data file upon shutdown, so that the next time the program runs it can read the file again. If that is the case, you could write some "dirty flag" in or near the file and clean the file up on startup if it is flagged.
As explained in How does task manager kill my program? and MSDN: Terminating a Process (Windows):
Note that you cannot intercept or react upon TerminateProcess. Your process will die and there is nothing you can do before that happens.
If a process is terminated by TerminateProcess, all threads of the process are terminated immediately with no chance to run additional code. This means that the thread does not execute code in termination handler blocks.

Related

Process.WaitForExit() waits on command window instead of actual application

I want the following code to run different applications and after they have openend additional tasks.
However some applications keep an command window open whilst others do not.
e.g. outlook.exe runs just fine,
ProcessStartInfo startInfo = new ProcessStartInfo("C:\\Program Files\\Microsoft Office\\root\\Office16\\OUTLOOK.EXE");
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
But when running Visual Studio Code, the command window stays active in the background;
ProcessStartInfo startInfo = new ProcessStartInfo("C:\\Program Files (x86)\\Microsoft VS Code\\Code.exe");
Process process = new Process();
process.StartInfo = startInfo;
process.Start();
process.WaitForExit();
It seems the loaded application process is the command window and not Visual Studio Code. So the command window disappears when I remove the WaitForExit(); But then i do not know when the application has loaded.
Is there another way to know if Visual Studio Code is fully loaded?
Process.WaitForExit() waits until the process you started has actually exited (as the name suggests). If this returns while the application you started is still visible, this is because the process you started is not used. For example, an existing instance of the Outlook process that is already running might be used.
If you want to wait for the process you start to be ready to accept user input, use Process.WaitForInputIdle().
Use WaitForInputIdle() to force the processing of your application to wait until the message loop has returned to the idle state. When a process with a user interface is executing, its message loop executes every time a Windows message is sent to the process by the operating system. The process then returns to the message loop. A process is said to be in an idle state when it is waiting for messages inside of a message loop. This state is useful, for example, when your application needs to wait for a starting process to finish creating its main window before the application communicates with that window.

Pass cmd argument to running process when shutting down windows service

I am creating a windowservice that starts a process where I pass multiple cmd arguments in the StartInfo.Arguments. That works fine as expected.
The problem is that when i stop the windowsservice, I need to tell the running program to shut down gracefully before the windows service stops. Because if I just kill the process the program does not save the collected data. The program that I run is the Process Monitor and it accepts the following command "/terminate".
How can I pass the /terminate argument before my windows service stops?
There is a couple of ways you can approach this solution but you can signal the process, and based on what you send with this signal it should execute its 'clean-up' code. Once it's finished, the process that spawned it should be signalled that it finished the cleanup code and can then shutdown. This of course assumes that you wrote the code for both the Window service and the process being spawned.
You can try Named pipes (https://learn.microsoft.com/en-us/dotnet/standard/io/how-to-use-named-pipes-for-network-interprocess-communication)
I managed to find a solution. In the OnStop() method in the service, I needed to create a new instance of the Process Monitor and pass the /Terminate argument:
Process process = new Process();
process.FileName = "\Procmon.exe" ;
process.StartInfo.Arguments = "/AcceptEula /Terminate";
process.Start();
With that it stoppes all the Process Monitor instances gracefully.

Can't close down a process in C#

I am running an executable that opens a windows form from a webform. In visual studio the winform program runs a method and then closes the windows form correctly and shuts down the program. But when I run the same file as an executable it keeps the windows form open. I can see that this executable process is still running as SmartSheetAPI.exe.
When I check in properties the name of the file is "SmartSheetAPI.exe". If I end this process in the task manager it shuts down the windows form so I know that is the issue. However, I have tried using the below code on the webform to kill the process but again it doesn't work.
Process process = new Process();
process.StartInfo.FileName = #"P:\Visual Studio 2013\Projects\Smartsheet\SmartsheetAPI\obj\Debug\SmartSheetAPI.exe";
process.Start();
foreach (var processes in Process.GetProcessesByName("SmartSheetAPI.exe"))
{
process.Kill();
}
Does anyone know how to shut this thing down. As I say it works well in the SmartSheetAPI program in visual studio but doesn't shutdown the window as an executable. I just need to shut down this process once it has run the method.
EDIT:
The process that isn't closing is the vshost.exe and as such it is keep my application from closing for some reason (i.e. the windows form remains open). If I process.kill() this everything shuts down as required. However, the problem is that when I run the executable of that file the windows form stays open but I can't find the vshost.exe running to close it? I have disabled it and now the process that won't close is the SmartSheetAPI.exe file which is the program I am currently running. I just want to exit out of this program, but nothing I try seems to work.
After calling the Kill method, call the WaitForExit method to wait for the process to exit, or check the HasExited property to determine if the process has exited.
Process process = new Process();
process.StartInfo.FileName = #"P:\Visual Studio 2013\Projects\Smartsheet\SmartsheetAPI\obj\Debug\SmartSheetAPI.exe";
process.Start();
// do some stuff while process is alive ...
process.Kill();
process.WaitForExit();
// do stuff after the process has been killed ...
For more details see here: http://msdn.microsoft.com/en-us/library/system.diagnostics.process.kill(v=vs.110).aspx
If your process cannot be killed it is probably waiting for something else. You might want to investigate that rather than forcing your application to be terminated.

Kill processes that I'm monitoring if the main application is closed

I have an application that launches another program and monitors it. When the program closes, my application also closes.
However, if I close my application first, the other program is still running.
ProcessStartInfo procInfo = new ProcessStartInfo("myProg.exe");
Process proc = new Process();
proc.StartInfo = procInfo;
proc.Start();
while (!proc.HasExited)
{
// do stuff
}
// On proc exit, my application is also done
How do I make sure that if I close my monitoring app, any processes that are being monitored are also killed?
So for example suppose MyApp is monitoring Notepad.
If I close MyApp, Notepad should also be closed.
Since this is a console application, capturing the "Exit" event is a bit trickier than forms. Take a look at this thread, I have it bookmarked because I was wondering the same thing as you a long time ago and it's handy to keep this around.
At that end of your program call:
if (!proc.HasExited)
proc.CloseMainWindow();
... to close the other process's window.

What Does No such interface supported Mean

I am getting an exception on my server side code, which is serving up a silverlight app,
Win32Exception - No such interface supported
Our server side C# code starts up a separate process for a short task because of a third party dll not being thread safe. So the error above occurs in part of the code like this,
Process process = new Process();
ProcessStartInfo processStartInfo = new ProcessStartInfo();
processStartInfo.CreateNoWindow = true;
processStartInfo.WindowStyle = ProcessWindowStyle.Hidden;
processStartInfo.FileName =
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin", "PreviewGenerator.exe");
process.StartInfo = processStartInfo;
process.Start(); // THIS IS WHERE THE EXCEPTION OCCURS
process.WaitForExit();
The PreviewGenerator.exe process does not start when it is not working, the exception occurs where the comment is above.
UPDATE:
I have run process monitor on the IIS server when the issue occurs. This shows that the w3wp process does this,
Thread Create
Access the file PreviewGenerator.exe
Hive unloaded (this is the registry)
Thread Exit
And it does this before calling the other process. If I compare this with a the process monitor log when it is working it does this,
Thread Create
Access the file PreviewGenerator.exe
Process Start
Does heaps of stuff with PreviewGenerator.exe including reading / writing / registry, etc.
Process Exit
Hive unloaded
Thread Exit
But process monitor does not show any information as to why the first case doesn't work.
Is there a way I can see why the thread exits prematurely?
Also I think this problem relates to when my server is being loaded up more, and much more memory is being used. How can I prove this?
I had a similar issue, I used
processStartInfo.UseShellExecute = false;
and that fixed it for me.
http://www.progtown.com/topic31343-process-start-processstartinfo-startinfo.html
I found the best thing to do was to create a separate app pool for my application in IIS and set an upper limit for the amount of RAM it could use. Also I found it useful to turn on the 'Generate Recycle Event Log Entry' items under the app pool settings.
You can then go to the system event log and filter out the items with a source of 'WAS' to understand what is going on in the app pools, when they are restarting and when they stop from being idle etc.
I think the main problem in our case is that the IIS box was running out of memory. Tuning the app pools and adding some extra RAM seems to have solved it.

Categories

Resources