【问题标题】:Ensuring a single instance of an application using WINAPI?确保使用 WINAPI 的应用程序的单个实例?
【发布时间】:2012-03-15 19:12:26
【问题描述】:

当有人拒绝将此代码作为running only a single instance of an application 的解决方案而没有说明他们这样做的原因时,我感到好奇。

 int hWnd = FindWindow(null, "My Application Title");
 if (hWnd > 0) //If found
 {
     Process.GetCurrentProcess().WaitForExit(600);
     try
     {
        SetForegroundWindow(hWnd); //Activate it
        ShowWindow(hWnd, 9);
        Process.GetCurrentProcess().Kill();
     }
     catch (Exception ex)
     {
        //write to log
     }
 }

 //Import the FindWindow API to find our window
 [DllImport("User32.dll")]
 public static extern int FindWindow(String ClassName, String WindowName);
 //Import the SetForeground API to activate it
 [DllImport("User32.dll")]
 public static extern IntPtr SetForegroundWindow(int hWnd);
 //Import the ShowWindow API to show it
 [DllImport("User32.dll")]
 public static extern bool ShowWindow(int hWnd, int nCmdShow);

有人可以向我解释这种方法的缺点吗?谢谢。

【问题讨论】:

  • Process.GetCurrentProcess().WaitForExit ... 什么?
  • @SLaks:只是为了测试其他实例是否正在关闭。
  • @opatachibueze:嗯?不,它没有。
  • @SLaks:哦,天哪。我现在看到了...忘记了 showwindow 和 setforegroundwindow 返回 bool,因此尝试捕获。这很有趣,虽然我写了很长时间。

标签: c# winapi mutex


【解决方案1】:

因为如果应用程序启动两次(意外单击),则测试会在一小段时间内失败。两个实例都可以启动,但都没有创建窗口。

【讨论】:

  • 嗯,有点道理。这可能发生在速度非常慢的 PC 上,我同意。
  • 在任何机器上,只是不是你的:)。您正在明确添加很少发生的竞争条件,因此应用程序将慢慢成为“您需要非常小心地启动,否则重新启动机器并重试的应用程序”。您将无法在自己的机器上找到原因,当您观看时,它永远不会发生......
  • lol @AlexeiLevenkov 有趣的是,我以前也有过类似的用户讲述体验。
【解决方案2】:

据我所知,它的缺点是对于应该是一个简单的解决方案来说过于复杂。您不需要破解 Windows api 来强制使用单个 api 实例。我猜这就是你被否决的原因。

如果您点击 Uwe 答案中的链接,您将看到您可以保留在托管代码中,这应该是您的默认设置,除非出于某种原因您必须深入挖掘。

【讨论】:

  • 使用WINAPI究竟有什么轻微错误?我看不出有什么问题。
  • 我使用 Windows API 没有问题,但是您可以使用托管包装器。我只想说,非托管代码更危险,需要更多小心,那么为什么要冒险呢?
猜你喜欢
  • 2010-09-18
  • 2018-02-26
  • 1970-01-01
  • 2023-03-25
  • 2021-03-28
  • 1970-01-01
  • 1970-01-01
  • 2010-10-23
相关资源
最近更新 更多