【问题标题】:How to gracefully end a process without using CloseMainWindow如何在不使用 CloseMainWindow 的情况下优雅地结束进程
【发布时间】:2018-08-13 05:11:01
【问题描述】:

有没有办法在不使用Process.CloseMainWindow() 的情况下优雅地结束进程?

我想要结束的列表中有一堆进程。该进程应该在没有Process.Kill() 的情况下结束,以确保他们也清理并结束他们的子进程。 我尝试了CloseMainWindow,但不幸的是,它会让我的进程弹出一个消息框,上面写着“你真的要结束程序吗?”[是][否]我想避免。

进程有一个WM_QUERYENDSESSION 的消息处理程序,但是当我尝试向进程发送WM_QUERYENDSESSION 消息时,它没有反应。它只是对WM_QUIT 做出反应,但行为看起来像调用Process.Kill() 时的行为。

我还没有找到合适的解决方案。希望我没有忽略这里的事情......

【问题讨论】:

  • 您是否能够与您的进程通信并告诉它们结束?这将是我能想到的最干净的解决方案。
  • 根据您得出的结论,发送WM_QUERYENDSESSION 消息是个好主意?也不清楚,当调用Process.CloseMainWindow 时会弹出什么消息。此外,为进程存储的“主窗口”只是一个猜测。很可能是错误的窗口。
  • 您应该研究与您的应用程序的通信协议。通过您描述事物的方式,您似乎拥有两者的源代码。查看Inter Process Communication (IPC),我会建议Named Pipe Thread (NPT),因为我个人觉得它更干净,更容易实现。我使用 NPT 并将自定义 c# 对象传输到另一个应用程序,我可以在另一端读回它。
  • @Sefe 我有一些管道用于与子进程通信,但我无法想象没有解决方案可以从主进程结束它而不完全杀死它或“按下 X 按钮”。
  • 有了编辑,解决方法就简单多了:去掉“你真的要结束程序吗”提示。用户只需按下 [Alt]+[F4],或单击关闭按钮。不要让他们两次回答同一个问题。

标签: c# winapi process


【解决方案1】:

发送WM_CLOSE 消息与单击窗口上的关闭按钮几乎相同。应用程序将能够阻止此请求或显示“保存更改”确认对话框。

除此之外,您可能会丢失数据。 WM_QUIT 不是您应该发送的。

WM_QUERYENDSESSION 是一个查询,您可以先发送它,然后再发送WM_ENDSESSION,但并非所有应用程序都会处理这些消息。

Win32 没有主窗口属性,它是一个 .NET 概念。

如果您打算在完成所有操作后再次重新启动这些应用程序,那么您应该考虑的另一件事是重新启动管理器功能。

【讨论】:

  • 我想避免“点击关闭按钮”或WM_CLOSE 因为弹出窗口生成。
  • WM_CLOSE 和重启管理器是停止应用程序的唯一干净方法。伪造结束会话可能会起作用,或者应用程序可能会丢失其未保存的数据,或者它可能会忽略会话通知并期望 Windows 终止该进程。
  • @Retnuoc:如果你想阻止你的代码弹出对话框,你将不得不实现自定义逻辑来做到这一点,并采取适当的步骤(例如自动保存未保存的更改)。
  • @Anders Restart manager 实际上是“伪造”WM_QUERYENDSESSIONWM_ENDSESSION (Guidelines for Applications) 但使用它可能更安全,因为可以指定只关闭选择了 Restart Manager 的应用程序。
【解决方案2】:

过了一会儿,我承认这个明确的问题似乎没有真正的答案。

由于我控制了这两个部分,我刚刚删除了“你真的要退出吗?”像IInspectable 假设那样弹出并通过打开的管道向子进程发送一条消息,例如Sefe 假设。

【讨论】:

    猜你喜欢
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    • 2012-03-27
    • 2016-01-18
    • 2013-02-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-17
    相关资源
    最近更新 更多