彻底关闭通过另一个启动的应用程序的最佳方法

Posted

技术标签:

【中文标题】彻底关闭通过另一个启动的应用程序的最佳方法【英文标题】:Best method to cleanly shut down an application launched via another 【发布时间】:2010-05-13 21:55:12 【问题描述】:

我找不到任何接近的答案,所以我正在咨询 SO 用户的体验:

场景:

我有两个小型 C# winforms 应用程序,其中一个充当服务器或主机,另一个充当客户端。它们通过 SQL Server 共享配置设置方面的数据。

我目前正在通过Process.Start() 从服务器应用程序启动客户端应用程序(只需要定期运行)并通过Process.CloseMainWindow() 终止它(在进程列表中找到它之后)。

虽然看起来很干净,但我想知道是否有更好的方法。

问题:

指示客户端应用程序关闭的最佳方式是:

继续使用 Process.CloseMainWindow()? 在应用程序之间实现 WCF? (我需要有关如何执行此操作的帮助。) 在 SQL 中设置客户端应用程序检查的变量? 其他方式?

【问题讨论】:

Process.CloseMainWindow() 似乎足够好(关闭主窗口将退出大多数应用程序)。但是为什么不记得你开始的过程,例如在类字段或局部变量中而不是在进程列表中搜索? 那将是一个进步!当我启动它时,我只是调用 Process.Start("app.exe") 但 .Start() 不返回进程 ID。我如何最好地记住以后终止的过程? 只需存储Process.Start 返回的Process 或创建一个新的Process 实例,如此处示例中所述:msdn.microsoft.com/en-us/library/e8zac0ca%28VS.90%29.aspx 谢谢 0xA3 - 工作得很好。 【参考方案1】:

鉴于Process.Start(string)

与进程资源关联的新Process 组件,如果没有启动进程资源(例如,如果重用现有进程),则为 null。

Process myProcess = Process.Start("client.exe");

然后您可以使用此值调用CloseMainWindow

myProcess.CloseMainWindow();

唯一不返回Process 组件的重载是parameterless method。

(顺便说一句,直到我发布此答案后,我才阅读有关该问题的 cmets)

【讨论】:

【参考方案2】:
其他方式?

您可以使用.Net Remoting。

但是,您可能应该改用 WCF。

【讨论】:

我认为这是一个有效的答案,但我还想补充一点,Microsoft 建议使用 WCF 而不是 Remoting,请参阅 ***.com/questions/1294494/… 和 msdn.microsoft.com/en-us/library/72x4h507%28VS.85%29.aspx。 这么简单的一点信息,WCF对我来说似乎很复杂,也许是矫枉过正;另一方面,.NET 远程处理似乎更容易(到目前为止),尽管我不喜欢使用“即将淘汰”的东西的想法。 我意识到 WCF 是一个更好的选择。我只是提出另一种选择。 也许我应该问一个关于 WCF 的单独问题:是否可以单独在两个 winforms 应用程序之间进行设置?并感谢您提供信息。【参考方案3】:

鉴于 Process.CloseMainWindow() 工作表明两个程序在同一台机器上运行。鉴于真正的服务无法启动桌面上可见的程序,这表明您的服务器程序作为普通用户应用程序运行。

现在拥有单独的程序不再有意义。只需让服务器创建一个可见窗口。交互是微不足道的,因为一切都在一个程序中运行并且可以访问该程序的所有状态。

如果服务器处理妨碍了客户端窗口保持活动,则在线程上显示该窗口。这个助手类完成了工作:

using System;
using System.Threading;
using System.Windows.Forms;

static class ClientView 
    private static Form mView;

    public static void Start(Form view) 
        if (Busy) throw new InvalidOperationException("View already running");
        mView = view;
        mView.FormClosed += (o, e) =>  mView = null; 
        Thread t = new Thread(() => Application.Run(view));
        t.SetApartmentState(ApartmentState.STA);
        t.Start();
    
    public static void Stop() 
        if (Busy) mView.Invoke(new MethodInvoker(() => mView.Close()));
    
    public static bool Busy  get  return mView != null;  

示例用法:

ClientView.Start(new ClientForm());

【讨论】:

我有一些理由让它们成为单独的应用程序,但这是一个有效且有用的想法。

以上是关于彻底关闭通过另一个启动的应用程序的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

等待另一个应用程序窗口

关闭 OSGi 容器的最佳方法(特别是 Equinox)

linux环境中关闭tomcat,通过shutdown.sh无法彻底关闭--线程池

在 ASP.NET 上启动维护过程的最佳实践是啥 [关闭]

c#从Windows服务启动应用程序的最佳方式

对 Rails Web 应用程序进行压力测试的最佳方法? [关闭]