Windows下防止程序多开并在多开时弹出已运行的程序
1、功能说明
在Windows客户端开发时,往往需要禁止客户多开程序的情况,并且在客户再次双击启动图标时显示已启动的程序界面。故而需要下面的功能:
- 使用CreateMutex禁止程序多开;
- 若CreateMutex成功创建mutex则将当前程序pid存储在本地文件中;
- 若CreateMutex创建失败,表示程序已经启动,需要读取本地文件中的PID,通过该PID获取程序的窗口句柄,再通过设置该窗口句柄前置
2、代码实现
/**
GetWindowHandleByPID: 通过PID获取该程序的窗口句柄
*/
HWND GetWindowHandleByPID(DWORD dwProcessID)
{
HWND h = GetTopWindow(0);
while (h)
{
DWORD pid = 0;
DWORD dwThreadId = GetWindowThreadProcessId(h, &pid);
if (dwThreadId != 0)
{
if (pid == dwProcessID)
{
while (GetParent(h) != NULL)
{
h = GetParent(h);
}
return h;
}
}
h = GetNextWindow(h, GW_HWNDNEXT);
}
return NULL;
}
/**
SetForeWindow:将指定PID程序置为前置显示
*/
void SetForeWindow(DWORD pid)
{
HWND w = GetWindowHandleByPID(pid);
if (w != NULL)
{
ShowWindow(w, SW_SHOWMAXIMIZED);
SendMessage(w, WM_ACTIVATE, WA_ACTIVE, 0);
SetForegroundWindow(w);
}
}
/**
SaveCurrentPID:将当前启动的PID存储在本地文件下
*/
void SaveCurrentPID()
{
QDir dir(qApp->applicationDirPath());
// 这里的“currentfilepath”请自行修改
QString optFilePath = dir.absoluteFilePath(“currentfilepath”);
QFile file(optFilePath);
if (file.open(QIODevice::WriteOnly | QIODevice::Text))
{
QTextStream out(&file);
out << GetCurrentProcessId();
}
else
{
std::cout << "open file : " << optFilePath.toStdString().c_str() << " failed";
}
}
/**
ReadPID:读取SaveCurrentPID接口中的内容,获取已启动的程序的PID
*/
DWORD ReadPID()
{
QDir dir(qApp->applicationDirPath());
QString optFilePath = dir.absoluteFilePath(“currentfilepath”);
QFile file(optFilePath);
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream in(&file);
DWORD pid;
in >> pid;
return pid;
}
else
{
std::cout << "open file : " << optFilePath.toStdString().c_str() << " failed";
return 0;
}
}
/**
toBeContinue:用于判断当前程序是否继续向下执行还是前置已启动的程序
*/
bool toBeContinue()
{
HWND pMutex = CreateMutex(NULL,FALSE,L"YOURAPPLICATION");
if(GetLastError() == ERROR_ALREADY_EXISTS)
{
CloseHandle(pMutex);
pMutex = NULL;
DWORD pid = ReadPID();
SetForeWindow(pid);
return false;
}
SaveCurrentPID();
return true;
}
本文介绍了如何在Windows环境下防止程序多开,并在已有实例时将已运行的程序窗口置前。通过CreateMutex函数创建互斥量来检测程序状态,利用GetWindowHandleByPID获取窗口句柄,然后通过SetForeWindow设置窗口为前置。同时,程序会将PID保存到本地文件,以便读取并激活已运行实例。

446

被折叠的 条评论
为什么被折叠?



