Share via


NotifyIcon still in system tray when a process is killed from another application

Question

Wednesday, October 21, 2009 6:01 PM

Hello MSDN Forums,

I have an update utility that is responsible for copying updated assemblies from a shared folder on the customers server into the application directory when it detects a new update.

However in some cases the customer has add on interfaces that are running (TCP Listener Programs to communicate with 3rd party programs about inventory quantities) in the background.  These listener programs also reference the assemblies I am trying to update.  Obviously without killing these processes the update would fail because the files are in use.

So I did the following:

            try
            {
                Process[] cnh_process = Process.GetProcessesByName("cnhic_mxc");
                if (cnh_process.Length > 0)
                    cnh_process[0].Kill();
            }
            catch
            {

            }

And then I restart the process after copying the files using:

            try
            {
                Process p = new Process();
                p.StartInfo.FileName = prefs.WorkingDirectory + "cnhic_mxc.exe";
                p.Start();
            }
            catch
            {

            }

This works except for the fact that the Notify Icons in the System Tray are not removed when the processes are killed so when I start them again it creates a second icon.  So far I have read ways using the Win32 API and P/Invoke to try to work around it but this seems messy at best.

Is there a better, managed way to close an application that is running to get Windows to remove the system tray icon?

Thanks,

Jeremie Grund

All replies (4)

Wednesday, October 21, 2009 6:15 PM ✅Answered

Jeremie,

Typically, if you Kill the process, it just isn't notifying the system tray to redraw.

Try moving your mouse over the icon - normally, the system tray will realize the application is no longer valid, and the icon will disappear.

If this is the case, it's tricky.  You can potentially use P/Invoke to try to send a redraw message to the system tray, but that's problematic at best.  The better option is to try to come up with a way to close your application more elegantly than using Process.Kill();

If the process you are shutting down is doing what it should, you should be able to use Process.Close(); instead of Process.Kill();  This will send a close notification to the process's main window, which should tell it to shut down cleanly.  The process would then remove it's icon appropriately, avoiding this issue.

Reed Copsey, Jr. - http://reedcopsey.com


Wednesday, October 21, 2009 11:16 PM ✅Answered | 1 vote

Process.Close() is not a method to close or terminate the associated process.  Process.Close() is just a synonym of IDisposable.Dispose().  The Close() method frees system resources associated with the process object and makes no attempt to close or terminate the associated running process.

Your only option here is to find a way to simulate the action an end-user would take to exit the process.  If the process has a main window, you can use the CloseMainWindow() method to try to close it,  or maybe the process responds to a command line switch, or maybe it can be managed via a named pipe.  Your best bet would be to contact the supplier of the application to find out if there is a way to accomplish what you seek.MCP


Wednesday, October 21, 2009 8:56 PM

Thanks for the information Reed,

However if I try to change it to Close() rather then Kill() I find that the TCP Listeners are not actually closed and I get an IOException when trying to copy the files.

What is required for an application to cleanly accept the Close method?

Thanks,

Jeremie Grund


Thursday, October 22, 2009 12:21 AM

Yes, good point webJose!  I meant to suggest CloseMainWindow(), not Close().  I often mix that one up, since "closing" a process just seems like the appropriate thing to do.

Reed Copsey, Jr. - http://reedcopsey.com