这是我的问题:我需要关闭的过程,已经在运行,从C#程序。 问题是,这一进程现在运行为一个图标(最小化到任务栏),并且除非用户打开它至少一次(这永远不会在无人值守的机器发生),它永远不会有一个主窗口。
我有另一项要求是,应用程序被关闭不杀死 。 我需要它来写它的内存缓冲区写入磁盘 - 和杀害它会导致数据丢失。
这是我试过到目前为止:
foreach (Process proc in Process.GetProcesses())
{
if (proc.ProcessName.ToLower().StartsWith("myapp"))
{
if (proc.MainWindowHandle.ToInt32() != 0)
{
proc.CloseMainWindow();
proc.Close();
//proc.Kill(); <--- not good!
}
}
}
我已经添加了if语句,发现,MainWindowHandle == 0时在窗口最小化后。 卸下如果没有帮助。 无论是CloseMainWindow()还是关闭()工作。 杀()的做法,但如上面提到的-这不是我所需要的。
任何想法将被接受,包括使用晦涩难懂的Win32 API函数:)
这应该工作:
[DllImport("user32.dll", CharSet=CharSet.Auto)]
private static extern IntPtr FindWindow(string className, string windowName);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);
private const int WM_CLOSE = 0x10;
private const int WM_QUIT = 0x12;
public void SearchAndDestroy(string windowName)
{
IntPtr hWnd = FindWindow(null, windowName);
if (hWnd == IntPtr.Zero)
throw new Exception("Couldn't find window!");
SendMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}
由于某些窗口不响应WM_CLOSE
, WM_QUIT
可能要代替它。 这些声明应在32位和64位工作。
如果是在任务栏上,它就会有一个窗口。 还是你的意思,它在任务栏通知区域(也称为系统托盘)? 在这种情况下,它仍然将有一个窗口。
Win32应用程序真的没有一个“主窗口”,除了按照惯例(主窗口是响应WM_DESTROY调用PostQuitMessage,导致消息循环退出的一个)。
随着程序的运行,运行间谍++。 要查找所有进程所拥有的窗口,你应该选择间谍 - 从主菜单>进程。 这将显示进程树。 从那里,你可以深入到线,再到窗口。 这会告诉你该进程有哪些窗口。 记下的窗口类和标题。 有了这些,你可以使用FindWindow函数(或EnumWindows的)找到在未来的窗口句柄。
随着窗口的句柄,您可以发送WM_CLOSE或WM_SYSCOMMAND / SC_CLOSE(相当于点击窗口标题中的“X”)的消息。 这应该会导致程序很好地关闭。
请注意,我从一个Win32点的观点在这里谈论。 您可能需要使用的P / Invoke或其他技巧来得到这个从.NET程序中工作。
这里有一些答复和澄清:
rpetrich:想你的方法之前,问题是,我不知道窗口名称,它不同于用户到用户,版本的升级-仅仅是exe文件名保持不变。 我只有进程名。 正如你可以在代码中看到的过程中MainWindowHandle以上为0。
罗杰 :是的,我确实意味着任务栏通知区域-感谢澄清。 我需要调用PostQuitMessage。 我只是不知道怎么回事,只给出一个PROCESSS,而不是一个窗口。
克雷格 :我很乐意说明情况:应用程序有一个命令行界面,允许你指定决定它会做何将它保存结果的参数。 在任务栏通知,但一旦它的运行,只有这样,才能阻止它和得到的结果是右键单击它是选择“退出”。
现在,我的用户希望脚本/批处理应用程序。 他们有绝对的一批开始就没有问题(只指定的exe和名称和一堆标志),但后来就死了正在运行的进程。 假设没有一个会改变的过程中提供了一个API运行时停止它(这是相当大),我需要一种方法来人为地将其关闭。
同样,在无人值守的电脑,启动过程中的脚本可以通过任务调度和操作控制程序启动,但没有办法关闭下跌过程。
希望澄清我的情况,并再次感谢大家谁是试图帮助!
问题阐明你为什么要尝试这样的:如果在过程中唯一的用户界面的系统托盘图标,你为什么要杀死并离开,但运行的进程? 用户如何将访问过程? 而如果机器是“无人值守”,为什么用托盘图标关心自己?