有人可以告诉我如何在MFC中创建最多N个应用程序实例吗?
此外,如果N个实例正在运行,并且一个实例关闭,则可以创建一个新实例(但任何时候都不能运行N个实例)。
提前谢谢你。 一个。
答案 0 :(得分:1)
您可以创建一个最多可以输入n个流程实例的全局信号量。进程的第n + 1个实例将无法进入信号量。当然,您应该为锁定操作选择一个短暂的超时,这样您就可以向用户提供有意义的反馈。
对于信号量内容,您可以查看MSDN。
答案 1 :(得分:0)
我会使用锁定文件。在CMyApp::InitInstance()
添加:
CString Path;
// better get the path to the global app data or local user app data folder,
// depending on if you want to allow the three instances machine-wide or per user.
// Windows' file system virtualization will make GetModuleFileName() per user:
DWORD dw = GetModuleFileName(m_hInstance,
Path.GetBuffer(MAX_PATH), MAX_PATH);
Path.ReleaseBuffer();
// strip "exe" from filename and replace it with "lock"
Path = Path.Left(Path.GetLength()-3) + T("lock");
int i;
// better have the locking file in your class and do a clean Close on ExitInstance()!
CFile *pLockingFile = NULL;
for (i = 0; i < 3; i++) // restrict to three instances
{
CString Counter;
Counter.Format(T("%d"), i);
TRY
{
pLockingFile = new CFile(Path + Counter,
CFile::modeCreate|CFile::modeWrite|CFile::shareExclusive);
pLockingFile.Close();
break; // got an instance slot
}
CATCH( CFileException, e )
{
// maybe do something else here, if file open fails
}
END_CATCH
if (i >= 3)
return TRUE; // close instance, no slot available
}
编辑:要在机器范围内锁定软件,请使用以下功能检索公共应用程序文件夹,而不是调用GetModuleFileName()
。
#pragma warning(disable: 4996) // no risk, no fun
BOOL GetCommonAppDataPath(char *path)
{
*path = '\0';
if (SHGetSpecialFolderPath(NULL, path, CSIDL_COMMON_APPDATA, TRUE))
{
strcat(path, T("\\MyApplication")); // usually found under C:\ProgramData\MyApplication
DWORD dwFileStat = GetFileAttributes(path);
if (dwFileStat == 0xffffffff) // no MyApplication directory yet?
CreateDirectory(path, NULL); // create it
dwFileStat = GetFileAttributes(path); // 2nd try, just to be sure
if (dwFileStat == 0xffffffff || !(dwFileStat & FILE_ATTRIBUTE_DIRECTORY))
return FALSE;
return TRUE;
}
return FALSE;
}
注意:这只适用于Vista。如果您有XP,写入全局目录是一项简单的任务,例如C:\ WINDOWS \ TEMP。我把这个函数放在一个helper dll中我只在操作系统是Vista或更高版本时加载。否则,由于系统dll中未解析的引用,您的软件将无法启动。