我救出了这个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 类不可实现。
答案 0 :(得分:1)
现在它变得容易多了。
这将返回被调用的进程数" svchost"到控制台 - 你可以想出重置吗? :0)
请注意,您搜索的名称没有扩展名。此外 - 它返回所有用户的所有进程的结果。
Console.WriteLine(Process.GetProcessesByName(" SVCHOST"。)计数)
答案 1 :(得分:1)
有很多方法可以实现这一目标,在C#
您可以使用Mutex
,Semaphore
甚至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
。