use .NET to shutdown another app

B

Buddy Ackerman

I need to create a utility to shutdown another running application. I know you can get a Process object and execute the
Exit method but that only works for apps that have a main window, mine does not. So is there a way to shutdown a
running app (with no main window) from another app (without using Process.Kill).


--Buddy
 
D

Dave

Closing a MainWindow using the Process class will post a close message to the main window's message loop.

1. You can do this yourself using the windows API call: PostMessage or SendMessage.

2. If the application is not running a message loop, then you must kill the thread if it's not ready to stop on it's own.
Many applications will have a Quit method, or something similar, to shutdown the app gracefully. If it's COM visible, you can use
the Activator class to get the object and call it's "Quit/Close" method.

You'll be using interop for either of the above two solutions.
 
B

Buddy Ackerman

The application that I want to close is a .NET app. I'm unclear as to whether issuing a WM_QUIT message via the
SendMessage Win32 API is the same as using Process.Exit (which I've already tried and it doesn't work). I am assuming
that the reason using Process.Exit doesn't work is because my app doesn't startup from a form. It starts from a class
and after doing some startup tasks it calls application.run(mainForm), also this form is a set to a window type of
"tool" (uses SendMessage function to do this so the window is completely hidden while it runs in the tray area).

I was also wondering if there was a way for me to call the application's close method but I don't if that's doable. You
mention that "if it's COM visible" I could access it, however I'm assuing it is not since it's a .NET app.

Sure seems like there has to be a way of closing a running app than to have to Kill it.



--Buddy
 
D

Dave

Ok, I understand that it's a .NET app your trying to close.
I'm unclear as to whether issuing a WM_QUIT message via the SendMessage Win32 API is the same as using Process.Exit

Process.Exit does not exist. Do you mean Environment.Exit or Process.Kill?

They are all very different:

WM_QUIT informs the app to quit, but it requires a message loop and does not guarantee that the app will listen.

Process.Kill() method uses an unmanaged call into kernel32 to stop the application. This kills the threads and background threads
of the application. It does not close down the application gracefully.

Environment.Exit is the same as using the unmanaged ExitProcess function which gracefully shuts down an application.

If there is a message loop running on the main thread of your application, all 3 solutions will close your application if you are
not handling the WM_QUIT message yourself.
the reason using Process.Exit doesn't work is because my app doesn't startup from a form. It starts from a class and after doing
some startup tasks it calls application.run(mainForm),

The message loop must be started on the thread of the application's Main method. As long as you are not calling Application.Run on
a different thread, all 3 solutions above will close your app.
also this form is a set to a window type of "tool" (uses SendMessage function to do this so the window is completely hidden while
it runs in the tray area).

Just set the form's "ShowInTaskbar" property to "false" and override SetVisibleCore() with the following implementation:

public override void SetVisibleCore(bool Show)
{
if (Show)
return;

base.SetVisibleCore(Show);
}


With the code above, your form will never be visible.

I was also wondering if there was a way for me to call the application's close method but I don't if that's doable. You mention
that "if it's COM visible" I could access it, however I'm assuing it is not since it's a .NET app.

To call a method across process boundaries, you can use Remoting. That's a whole 'nother topic, although it's not too difficult to
implement :)
COM would work too event though it's a .NET app, but it's not nessecary with the Remoting framework which keeps things "managed".

There are a few things you can do to close your app from another process. If Envirnoment.Exit() is not working properly in your
situation, it's likely because the app is not tearing down nicely. Make sure you don't have any code in the Close override that
could cause a problem, just in case.

If the WM_QUIT message isn't doing the trick, I'd assume that your message loop is not on the main thread. I could be wrong about
this requirement, however.

GL
 
B

Buddy Ackerman

It appears that it's probably easiest to just kill the app. When I do that however the icon in the tray is still
visible. Is there a way to refresh the tray display so that icon disappears?


Thanks for all the info.



--Buddy
 
D

Dave

I believe this is a bug. I have not found a way to remove the icon manually when the process is not shutdown gracefully.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top