I have a windows service (Serv.exe) running as LocalSystem, at a certain point it wants to show the logged-on user that it is processing data, therefore I CreateProcessAsUser(Display.exe) which is a C# Windows Form that display information (this all works perfectly fine).

Now, when the Service is finished I want to close Display.exe - from reading around there are 2 general options. Either kill the process (which works fine in my case, but is not recommended) or use the myProcess.CloseMainWindow(); which I am currently trying to implement.

Here is my code:

Process[] myProcesses;
                myProcesses = Process.GetProcessesByName("Display");
                foreach (Process myProcess in myProcesses)
                {
                    if (myProcess.MainWindowHandle == IntPtr.Zero)
                    {
                        myProcess.Kill();
                    }
                    else
                    {
                        myProcess.CloseMainWindow();
                    }
                }

Now, Display is simply a C# Windows Form application, I can see it on screen and my code is able to find the process (as killing it works fine) - but why is myProcess.MainWindowHandle == IntPtr.Zero? I've tried adding 15 second sleep (incase the form was still loading) but it made no difference.

Is there something I need to implement in Display.exe itself to process the .CloseMainWindow()? Can this have something to do with the fact that my Service (Serv.exe) running as LocalSystem is trying to get the MainWindowHandle for a process running under a different user?

Any help would be appreciated.
Thanks,

Recommended Answers

All 3 Replies

Calling CloseMainWindow will essentially send a Close request message to the running application, whereby it is up to that application to handle the event--This is the most graceful approach because it allows the application to perform it's normal process termination. It should be followed by a call to Close to perform resource cleanup.

// Close process by sending a close message to its main window.
            myProcess.CloseMainWindow();
            // Free resources associated with process.
            myProcess.Close();

Calling Kill will terminate the process, but at the risk of losing any unsaved data or even corrupting data if in progress of writing. I believe that allocated resources my also not be freed. You can call Kill if the above recommended close fails.

As far as the MainWindowHandle, I'm not sure why are you are doing that.

Also, take a look at this article: Make Your Application Shutdown Aware. If you implement graceful handling of a close request in your process, you should have not problems when you want to shut it down from your service.

Cheers!

Calling CloseMainWindow will essentially send a Close request message to the running application, whereby it is up to that application to handle the event--This is the most graceful approach because it allows the application to perform it's normal process termination. It should be followed by a call to Close to perform resource cleanup.

// Close process by sending a close message to its main window.
            myProcess.CloseMainWindow();
            // Free resources associated with process.
            myProcess.Close();

Calling Kill will terminate the process, but at the risk of losing any unsaved data or even corrupting data if in progress of writing. I believe that allocated resources my also not be freed. You can call Kill if the above recommended close fails.

As far as the MainWindowHandle, I'm not sure why are you are doing that.

Also, take a look at this article: Make Your Application Shutdown Aware. If you implement graceful handling of a close request in your process, you should have not problems when you want to shut it down from your service.

Cheers!

Here is a suggestion based on my understanding:

Process[] myProcesses;
            myProcesses = Process.GetProcessesByName("Display");
            foreach (Process myProcess in myProcesses)
            {
                // gracefully request close of main window
                if (myProcess.CloseMainWindow()) // NOTE: can only use Kill for Console app
                    myProcess.Close();

                // then if it did not and you still want to force it...
                if (!myProcess.HasExited)
                    myProcess.Kill();
            }

I had tried simply calling CloseMainWindow() directly before and nothing was happening - so I did some more reading and people started mentioning that if .MainWindowHandle() == 0 then CloseMainWindow() would not work.

In my case, simply calling CloseMainWindow() fails and .Close() is never run (and I wait 30 seconds to ensure it is in progress) - the call simply does nothing. So I checked the MainWindowHandle and it is = 0 which brought me to beleive that I was unable to get the handle.

A friend of mine mentioned that it might be because I am doing this as a server under LocalSystem and not under the user who is actually running the application - any clues?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.