2013-06-25 69 views
0

我正在开发一个包含2个部分的应用程序:如何从C#控制台应用程序关闭在系统托盘中运行的WPF应用程序?

1)从系统托盘运行的WPF应用程序。它有一个GUI窗口,可以通过右键单击sys托盘图标&在上下文菜单中选择一个选项,但它不是非常频繁地需要&应用程序将从系统托盘运行大部分时间。此外,我更改了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; 
} 
+0

你的“当前方式”有什么问题?任何IPC都会(管道,udp,...)。 – JeffRSon

+0

主要问题是什么? –

+0

问题如上所述:WPF应用程序未关闭。使用我目前的方式,它只会在桌面上出现图形用户界面时关闭。但是,如果应用程序正在从系统托盘运行,就像90%的时间,它不会关闭。 – CodeLotus

回答

0

好吧,我发现了一种关闭WPF应用程序。它没有收到消息的原因是,由于某种原因,当WPF应用程序从系统托盘运行时,AppProcess.MainWindowHandle没有给出WPF应用程序主窗口的句柄。

因此,我使用在Win32 API中找到的user32.dll:FindWindow()方法来查找WPF应用程序的主窗口。之后,当我将自定义消息传递给它时,WPF应用程序正常关闭。

0

使用IPC作为JeffRSon建议。当两个进程位于同一台机器上时,MSMQ是一种非常简单有效的方法。

定义您的WPF应用程序的一个队列,当它启动时,不管是否显示UI,都让它监听队列。控制台应用程序可以通过关闭应用程序消息向队列发送消息。您必须定义数据合同。你可以参考:

http://www.codeproject.com/Articles/3944/Programming-MSMQ-in-NET-Part-1

+0

这似乎是一种很好的方法,但在实现这一点之前,是否有其他方式可以实现这一点,而不需要实现新的功能?即使它不涉及消息传递。 – CodeLotus

相关问题