以对话框程序Demo为例:
1、在CDemoApp类中添加成员变量:HANDLE \r\nm_hMutex;
2、重载CWinApp::InitInstance 和 CWinApp::ExitInstance,代码如下:
BOOL CDemoApp::InitInstance()
{
//创建互斥量
/*执行成功,就返回互斥体对象的句柄;零表示出错。会设置GetLastError。即使返回的是一个有效句柄,但倘若指定的名字已经存在,GetLastError也会设为ERROR_ALREADY_EXISTS
*/
m_hMutex = ::CreateMutexW(NULL,FALSE,_T("Demo"));
//判断互斥量是否存在
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
HANDLE SnapShot;
SHFILEINFO shSmall;
//PROCESSENTRY32进程快照的结构体
PROCESSENTRY32 ProcessInfo;
BOOL Status;
int m_nProcess = 0;
//创建进程快照(TH32CS_SNAPPROCESS表示创建所有进程的快照)
SnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
//实例化后使用Process32First获取第一个快照的进程前必做的初始化操作
ProcessInfo.dwSize = sizeof(ProcessInfo);
//获取第一个进程句柄
Status = Process32First(SnapShot, &ProcessInfo);
while ( Status )
{
m_nProcess++;
////调用SHGetFileInfo()可以由psfi参数得到文件的图标句柄
SHGetFileInfo(ProcessInfo.szExeFile, 0, &shSmall, sizeof(shSmall), SHGFI_ICON|SHGFI_SMALLICON);
//比较当前进程的可执行文件名称和传递进来的文件名称是否相同
if ( strcmp(ProcessInfo.szExeFile, "Demo.exe") == 0 )
{
//打开一个已存在的进程对象,并返回进程的句柄
HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE,ProcessInfo.th32ProcessID);
/*用来终止或者说杀死一个进程,它不会留给进程及其所有线程清理的时*,系统会马上终止(杀死)这个进程的所有线程,致使进程终止。在使用此函数前我们*须要调用OpenProcess函数来获得我们要终止(杀死)进程的句柄,并且要获得进程的*ROCESS_TERMINATE权限。
*/
TerminateProcess(hProcess, 1);
break;
}
else
{
//获取下一个进程句柄
Status=Process32Next(SnapShot, &ProcessInfo);
}
}
AfxMessageBox(_T("应用程序已经运行!"));
return false;
}
else
{
AfxMessageBox(_T("应用程序第一次运行"));
}
//.....
return FALSE ;
}
int CDemoApp::ExitInstance()
{
// TODO: 在此添加专用代码和/或调用基类
if(m_hMutex != NULL)
{
CloseHandle(m_hMutex);//关闭句柄
}
return CWinApp::ExitInstance();
}
注意:本文归作者所有,未经作者允许,不得转载