Windows防止程序多开并在多开时弹出已运行程序

本文介绍了如何在Windows环境下防止程序多开,并在已有实例时将已运行的程序窗口置前。通过CreateMutex函数创建互斥量来检测程序状态,利用GetWindowHandleByPID获取窗口句柄,然后通过SetForeWindow设置窗口为前置。同时,程序会将PID保存到本地文件,以便读取并激活已运行实例。

Windows下防止程序多开并在多开时弹出已运行的程序

1、功能说明

在Windows客户端开发时,往往需要禁止客户多开程序的情况,并且在客户再次双击启动图标时显示已启动的程序界面。故而需要下面的功能:

  1. 使用CreateMutex禁止程序多开;
  2. 若CreateMutex成功创建mutex则将当前程序pid存储在本地文件中;
  3. 若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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值