确定是否有多个同一进程的实例在运行?

时间:2015-11-25 21:42:12

标签: .net vb.net process mutex multiple-instances

我救出了这个VB6风格的代码片段,意图重构/更新但后来我发现它没有按预期工作。

代码应该可以随时轻松确定是否有多个同一进程的实例在运行:

Public Declare Function CreateMutexA Lib "Kernel32.dll" (
        ByVal lpSecurityAttributes As Integer,
        ByVal bInitialOwner As Boolean,
        ByVal lpName As String) As Integer

Public Declare Function GetLastError Lib "Kernel32.dll" () As Integer

Public Function My_Application_Is_Already_Running() As Boolean

    ' Attempt to create defualt mutex owned by process
    CreateMutexA(0, True, Process.GetCurrentProcess().MainModule.ModuleName.ToString)
    Return (GetLastError() = 183) ' 183 = ERROR_ALREADY_EXISTS

End Function

如果我只有一个实例在运行,那么它会返回False,如果我启动同一个进程的两个实例,那么该函数会按预期返回True,问题是当其中一个实例关闭/消失,函数仍然返回True

如何修复上面的代码或使用正确的方法执行此操作?

我的目的是让一个合适的辅助函数可以随时从任何应用程序调用,不要硬编码信号量/互斥算法,该算法仅适用于某些特定环境下的某个特定项目等...应该是一个抽象,以避免做任何事情,而不是调用函数来获得结果,就像上面的函数(错误)一样。

更新

我试过这个:

Public NotInheritable Class AppUtil

        Private Shared created As Boolean = False
        Private Shared waitHandle As New EventWaitHandle(initialState:=False,
                                                         mode:=EventResetMode.ManualReset,
                                                         name:="AppUtil#IsRunningAnyOtherInstance",
                                                         createdNew:=created)

        Public Shared Function IsRunningAnyOtherInstance() As Boolean

                Return Not created

        End Function

End Class

在Form中按钮的事件处理程序中,我有这个调用:

MsgBox(AppUtil.IsRunningAnyOtherInstance)

编译解决方案后,我启动了应用程序的两个实例,第一个实例返回False,而较新的实例返回True。两者都应该返回True,因为有2个实例打开,当关闭其中一个表单时,它应该返回False(因为只剩下一个实例打开)。

PS:考虑到 AppUtil 类不可实现。

3 个答案:

答案 0 :(得分:1)

现在它变得容易多了。

这将返回被调用的进程数" svchost"到控制台 - 你可以想出重置吗? :0)

请注意,您搜索的名称没有扩展名。此外 - 它返回所有用户的所有进程的结果。

Console.WriteLine(Process.GetProcessesByName(" SVCHOST"。)计数)

答案 1 :(得分:1)

有很多方法可以实现这一目标,在C#您可以使用MutexSemaphore甚至Windows Events,例如:

private static EventWaitHandle _handle;

bool created ;
_handle = new EventWaitHandle (false, EventResetMode.ManualReset, "my program#startup", out created) ;
if (created)
{
    StartApp();
}
else 
{
    Exit();
}

更多信息HERE

另一种方法是:

  string procName = Process.GetCurrentProcess().ProcessName;
  if (Process.GetProcessesByName(procName).Length == 1)
  {
      // do whatever //
  }

答案 2 :(得分:1)

我认为最简单的方法是使用Mutex类:

        bool isFirstInstance = false;
        Mutex mutex = new Mutex(true, "MyUniqueAppKeyOrGuid", out isFirstInstance);

第一个实例将变量isFirstInstance设置为true - 所有下一个实例都将其设置为false