【问题标题】:C# application close the first instance of itselfC# 应用程序关闭自身的第一个实例
【发布时间】:2012-11-12 16:19:17
【问题描述】:

我知道如何确保我一次只运行一个应用程序实例: How to check if another instance of the application is running

但是...我怎样才能确保当第二个实例启动时,第一个实例将被关闭(而不是仅仅退出通常完成的第二个实例)。最好等待它完全关闭。

如果同时启动了 2 个以上的实例,则应该只允许最后一个实例“存活”。

我明白了(谢谢你所有的答案)。我的解决方案如下:

        #region Kill other running processes of this application
        List<Process> processes = Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).ToList();
        if (processes.Count > 1)
        {
            processes.Sort((x, y) => DateTime.Compare(x.StartTime, y.StartTime));
            for (int i = 0; i < processes.Count - 1; i++)
            {
                processes[i].CloseMainWindow();
                processes[i].WaitForExit();
            }
        }
        #endregion

        Console.WriteLine(string.Format("{0}:{1}", DateTime.Now.Minute, DateTime.Now.Second));
        Console.ReadLine();

【问题讨论】:

  • 找到另一个实例进程ID并杀死它?
  • 这不是一个真正的答案,但我不会做你想做的事。例如,如果您的第一个实例中有未保存的内容,而您打开了第二个,则关闭它时可能会丢失数据。在处理 Singleton 时,当有一个打开的实例时,首选的行为是避免另一个实例,而不是关闭实例 1 并打开实例 2
  • 在第二个实例启动时按名称获取进程并杀死所有具有该名称的进程
  • 为什么是最后一个?这是否意味着您可能会丢失数据?为什么不聚焦/激活原件?您在此处的回复可能会告知我们的答案。
  • 为什么不只是有一个容器来实例化您想要的对象,并记住它创建的所有对象,并且每当创建新对象时,它都会终止旧对象......和验证他们自己清理...

标签: c# .net


【解决方案1】:

您可以使用 Microsoft.VisualBasic.dll 的WindowsFormsApplicationBase 类。

StartupNextInstance 事件在创建另一个实例时在第一个应用程序中引发。在这种情况下,您可以终止当前进程。

 Process.GetCurrentProcess().Kill();

这将确保新实例处于活动状态,而之前的实例已关闭。

【讨论】:

  • 答案标记为 C#。这里的视觉基本参考是什么?我们都知道这些项目已经在互联网上的许多图书馆或您提到的图书馆中实施。但是这里的问题是关于该逻辑的实现,而不是使用它。但是,您的回答似乎还不够逻辑。
  • 谁投了-1?澄清你的推​​理。 @Mohammad Goundarzi -> Microsoft.VisualBasic.dll 表示该库由 Visual Basic 团队提供,它并没有说它只能在 VB 中使用。它是 .NET 库(在 C# 中也广泛使用),并使用远程处理作为进程之间的底层进程间通信。
  • @Mohammad Goundarzi -> 对我来说,问题似乎只保留最后一个实例,并关闭所有前一个实例。与我指定的完全一样。不多不少。你怎么判断答案不够充分?您是否尝试过,或者有什么不清楚的地方?这当然来自互联网,但经过试验和测试(由 MSFT 团队提供,也由我为我的项目提供)
  • 答案很简单,提问者没有要求任何已实施的解决方案库。但是,正如我已经提到的,您作为一个傻瓜对我来说还不够清楚!那么对于其他不了解并寻求帮助的人来说,您的答案怎么可能就足够了?顺便说一句,如果我对你投反对票是错误的,请不要担心,因为看到你答案的其他人会自动投赞成票。干杯
  • VB 库和 Visual Basic 团队的库之间存在差异。该库是 .NET 库而不是 Visual Basic 库(不适用于 VB6/VBA)
【解决方案2】:

我认为您自己对逻辑有点困惑。顺便说一下,你应该使用一些项目来做这样的事情:

1-System.Diagnostics.Process.WaitForExit

针对特定流程实例调用该方法,可以在调用"Kill""Shutdown"方法后等到流程完全退出。如果它是 Windows 应用程序,它将关闭进程中的主窗口。对于有一些退出确认框的应用程序,它将等待用户确认或取消对话框(例如当您的应用程序已经打开而您的窗口正在关闭时)。

2-System.Diagnostics.Process.ExitCode

如果你想访问你发送给进程的存在消息的结果,你应该在调用"WaitForExit"函数之后调用这个属性的值。我想你可以使用这个属性来查明第一个进程是否退出以及第二个进程的退出原因。

3- public static int Main

因为您需要从进程外部访问退出代码,您应该将"Main" 方法的返回值更改为int。这样,您可以在第一个进程中返回一个值,并在第二个进程中通过"ExitCode" 属性访问它。如果在您的情况下很难在 "Main" 函数中返回值,您可以通过调用第 4 项来传递退出代码。

4- System.Windows.Application.Shutdown(在.NET中退出

调用此方法与返回 "Main" 函数中的值完全相同。

5-System.Diagnostics.Process.GetProcessesByName

毕竟调用这个静态方法就可以得到指定名字的所有进程。

希望对您有所帮助。我只是试图尽可能简单地解释一切。这些都是您可以用来实现逻辑的工具。如果您知道 .NET 为您提供的这些能力,剩下的事情就会变得如此简单。

毕竟,正如我已经忘记说的那样,如果你有兴趣做正确的事情,在我看来,正如我的经验所表明的那样,有一种技术专为这种逻辑而设计。

6- .NET 进程间通信或 IPC (a sample on code) (introduction on codeguru)

IPC 基于 .NET 远程处理(我个人认为 .NET 中最有趣的讨论)但不管名称如何,它不仅用于远程通信。远程处理有很多部分,其中包括进程间通信 (IPC)。这很难,但如果你问我,这是最好的方法。

干杯

【讨论】:

  • 谢谢。这真的帮助了我。就一个问题。在我的解决方案中,我在 for 循环中有“processes.Count - 1”。但由于某种原因,它不会杀死当前进程(这很好)。但我不明白为什么。不应该是“processes.Count - 2”吗?
  • 很高兴听到它很有用。通过使用 processes.Count - 1 或简单地说 someArray.Count - 1 您指的是数组的最后一项,您必须确保数组至少有存储在其中的一项。简单地说 -2 指的是 最后一项之前的一项,它会导致您检查其他一些约束以防止引发未处理的异常。尝试像在现实世界中一样简单地分析一切。希望能帮助到你。干杯。
  • 很抱歉,因为我使用了
  • 我没有看到代码,但你提到的完全正确。 @Napoleon 我可以请你帮个忙吗?请看一下 Tilak 的答案,看看是否有用投票给他。我确实对答案投了反对票,因为我有我的理由,我认为他对此很生气。谢谢身体。 ;)
【解决方案3】:

可能有一种更好的方法可以做到这一点,涉及进程和事件之间的其他相互通信,但这里有一个不需要研究的基本方法(至少对我而言)

当一个进程启动时,创建一个文件(可能带有时间戳)以表明它是否已启动。

让原始进程定期检查文件,如果看到更新的时间戳则停止它

【讨论】:

  • 进程内消息传递是一件好事。我自己试过很多次。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多