我正在开发一个包含两部分的应用程序:
1) 从系统托盘运行的 WPF 应用程序。它确实有一个 GUI 窗口,可以通过右键单击系统托盘图标并在上下文菜单上选择一个选项来调出,但它并不经常需要,并且该应用程序将在大多数情况下从系统托盘运行时间。此外,我更改了 MainWindow 的 Closing() 事件,以便在用户尝试关闭应用程序时将其最小化。
2) 在不显示控制台的情况下运行的控制台应用程序,其目的是轮询另一个应用程序的启动/关闭。一旦启动/关闭其他应用程序,控制台应用程序也会启动/关闭 WPF 应用程序。(请不要告诉我使用 Windows 服务来执行此操作。我之前已经探索过该路线。由于多种原因,它对我不起作用,我不会在此列出)。
问题:我无法从控制台应用程序关闭 WPF 应用程序。我正在做的事情如下。首先,我获得了我的 WPF 应用程序的流程:
Process AppProcess = Process.GetProcessById((int)AppID);
在此之后,我尝试了很多选项,如下所示:
1) 杀死进程:AppProcess.Kill();
这是唯一有效的,但非常不雅。它还会使 SysTray 图标未处理,因此是不可接受的。
2) AppProcess.Close();
根本不起作用,我不知道为什么。
3) AppProcess.Dispose();
根本不起作用,我不知道为什么。
4) AppProcess.CloseMainWindow();
这仅在用户保持 WPF 应用程序的 GUI 处于打开状态时才有效,正如我之前提到的,这种情况很少见。所以,通常这也不起作用。(你可能会说我已经破解了 Closing() 事件以防止关闭窗口。别担心,我已经采取了适当的措施来处理它。我已经提供了其他措施来关闭应用程序。有一个布尔变量决定是否取消关闭操作。)
5) 将自定义/标准消息传递到 WPF 应用程序的主窗口。
这也仅在 WPF 应用程序的主窗口 (GUI) 打开时才有效,否则它不会收到消息。
所以,总而言之,没有一种方法是有效的。我需要一种可靠的方法来从控制台应用程序中优雅地关闭 WPF 应用程序。请提出一些建议。
我目前的做法如下:
在控制台应用程序中:
const uint WM_CUSTOMCLOSE = 0xFE;
IntPtr hWnd = AppProcess.MainWindowHandle;
SendMessage(hWnd, WM_CUSTOMCLOSE, 0, 0);
在 WPF 应用程序中:
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;
}