看了你的源代码,这个单实例 HandleSingleInstance 里有些地方我还是没看懂,为什么要用 WaitForSingleObject 去等待一个已经存在的互斥体,超时后还换个名字自己再创建一个? 这是作者有什么特别的设计意图吗?下面是我连续启动软件多次后稳定下来的截图,明确说明这样设计是存在漏洞的。
![]()
if (GetLastError() == ERROR_ALREADY_EXISTS) {
WaitForSingleObject(hMutex, 3000);
wchar_t uniqueMutexName[128];
_snwprintf_s(uniqueMutexName, 128, L"CatimeMutex_%lu", GetTickCount());
*outMutex = CreateMutex(NULL, TRUE, uniqueMutexName);
return TRUE;
}
作者可能是担心 CatimeMutex 这个名字不够独特,万一别的软件也用了这个名字,会导致自己的程序被误判为重复实例,所以才设计了一套“名字不够独特就换一个”的兜底逻辑。但这个担忧其实没有必要,用 CreateMutex 做单实例是业界通用做法,加上作者名或产品名前缀 (如 vladelaina_CatimeMutex )就足以避免冲突,不需要在运行时动态改名。
而这里的问题在于:互斥体存在的意义是阻止第二个实例运行,但你的做法是等不到就换个名字继续创建,相当于自己把锁拆了。建议删掉 WaitForSingleObject 和 uniqueMutexName 这一整段,互斥体存在就直接返回 FALSE,让进程退出,不需要任何兜底,如果想在启动第二个实例的时候提醒用户,可以激活当前正在运行实例的窗口并弹出一个提示,这样就最好了。
祝你的软件越做越好!希望以上的建议能够给你一点启发。
