I'm developing an application which has 2 parts:
1) A WPF application which runs from the system tray. It does have a GUI window, which can be brought up by right-clicking the sys-tray icon & choosing an option on the context menu, but it is not needed very frequently & the app will run from the sys-tray most of the time. Moreover, I've changed the Closing() event of the MainWindow, so as to minimize the app, if the user tries to close it.
2) A console application which runs without displaying a console & its purpose is to poll for launch/close of another application. As soon as the other application is launched/closed, the console application launches/closes the WPF application too. (Please don't tell me to do this using a Windows Service. I've already explored the route before. It doesn't work for me due to several reasons, which I won't enlist here).
PROBLEM: I am not able to close the WPF application from the console application. What I'm doing is as follows. First I obtain the process for my WPF application:
Process AppProcess = Process.GetProcessById((int)AppID);
After this I've tried a lot of options as follows:
1) Killing the process: AppProcess.Kill();
This is the only one which worked, but is very unelegant. It also leaves the SysTray icon undisposed, so it is not acceptable.
2) AppProcess.Close();
Doesn't work at all & I don't know why.
3) AppProcess.Dispose();
Doesn't work at all & I don't know why.
4) AppProcess.CloseMainWindow();
This only works if the user has kept the GUI of the WPF app opened, which is very rarely the case as I mentioned before. So, normally this also doesn't work. (You might say that I've hacked the Closing() event to prevent closing the window. Don't worry I've taken appropriate care to handle that. I've provided other measures to close the app. There is a boolean variable which decides whether the Closing action is to be cancelled or not.)
5) Passing custom/standard message to the WPF Application's main window.
This also works only if the main window (GUI) of the WPF app is open, else it doesn't receive the message.
So, all in all, no method is working. I need a reliable method to close the WPF app gracefully from the console app. Please suggest something.
The current way I'm doing it is as follows:
In the Console App:
const uint WM_CUSTOMCLOSE = 0xFE;
IntPtr hWnd = AppProcess.MainWindowHandle;
SendMessage(hWnd, WM_CUSTOMCLOSE, 0, 0);
In the WPF app:
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
source.AddHook(WndProc);
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if(msg == 0xFE)
{
ExitFlag = true; //Exitflag is checked later to decide whether closing is to be cancelled.
this.Close();
}
return IntPtr.Zero;
}