"Gracefully"杀死进程

34

目前我正在使用Process.Kill()来终止一个进程。不过,是否有一种方法,而不仅仅是立即终止它,可以向该进程发送一条消息指示其关闭,以便它可以优雅地清理和关闭。基本上,我正在寻找等同于单击右上角的红色X,我相信这会发送一个请求关闭应用程序的消息。


这个问题已经被问过了,并且在这里接受了一个答案:https://dev59.com/enI95IYBdhLWcg3w_zas - David
@David Stratton 发现得好,确实思路相同,但是这个问题特别询问托管代码(见标签[c#]和[.net]),而在另一个问题中还没有答案。 - lc.
@David Stratton - 这个问题是关于使用C#的托管代码进行优雅关闭的,你提供的链接是关于win32的,而且答案需要pInvokes。完全不同。 - Oded
@David Stratton Ic 是对的。我在寻找一种用托管的 C# 来完成这个操作的方法。他完美地回答了我的问题。 - Icemanind
啊,抱歉.. 我的思维过程是... 这将通过使用PInvoke从.Net代码工作.. 你可以使用PInvoke从.Net调用任何Win32 API函数。不过,如果您正在寻找“纯”托管代码,我也能理解。 - David
3个回答

41

如果进程具有Windows界面(如您所指红色“X”),您可以尝试使用 Process.CloseMainWindow()。如果失败,您可以回退到 Process.Kill()


简单易懂。 - jeff
能否从 shell 运行类似这样的东西?我有一个非常长的进程,可能需要在中途关闭一些进程。 - SJ10
系统托盘中的后台服务或进程没有主窗口怎么办?真的没有优雅的方式来关闭它们吗? - Ajedi32
1
@Ajedi32 我恐怕你是对的。CloseMainWindow 的文档甚至说“Kill 是终止没有图形界面的进程的唯一方法。”如果它在系统托盘中,那可能算作一个窗口,你可以尝试向它发送消息。不过我还没有尝试过。如果它是一个“右键单击关闭”类型的东西,你也可以使用 Spy++ 来查看手动优雅地关闭时生成了哪些消息,并尝试将相同的消息发送到进程中以模拟手动关闭——这更像是一个宏而不是其他任何东西。 - lc.

7

杀死进程可能不够优雅,也许你可以发信号让其自杀。

  • SendMessage(发送消息)
  • NamedPipes(命名管道)
  • Named Mutex(命名互斥量)
  • Sockets(套接字)

4

这取决于您要终止的进程。如在相关页面Process.Kill中所述,“Kill是唯一终止没有图形界面的进程的方法。”如果有图形窗口,则使用lc提供的答案;Process.CloseMainWindow类似于您提到的红色X。


这似乎难以置信。所以,如果我在任务管理器中停止后台服务,或者通过右键单击托盘图标并单击“关闭”,Windows会立即终止该进程,因为它没有主窗口?这肯定不是我的经验。 - Ajedi32

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接