下面是我编写DLL时dllmain中的代码。
#include "stdafx.h"
HANDLE hMutex = NULL;
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
{
hMutex = CreateMutex(NULL, FALSE, _T("GLock"));
if (!hMutex)
{
MessageBox(NULL, _T("Create mutex error!"), _T("Error"), MB_OK);
return FALSE;
}
DWORD dwWait = WaitForSingleObject(hMutex, 0);
switch (dwWait)
{
case WAIT_OBJECT_0:
break;
case WAIT_TIMEOUT:
{
MessageBox(NULL, _T("The program is running!"), _T("Warning"), MB_OK);
return FALSE;
}
case WAIT_FAILED:
{
MessageBox(NULL, _T("Failed to get mutex!"), _T("Error"), MB_OK);
return FALSE;
}
}
/// 校验audit文件
char tip[255] = { 0 };
if (checkAuditFile(tip) == 0)
{
CString tipErr(tip);
MessageBox(NULL, tipErr, _T("Error"), MB_OK);
return FALSE;
}
break;
}
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
{
if (hMutex)
{
ReleaseSemaphore(hMutex, 1, NULL);
CloseHandle(hMutex);
hMutex = NULL;
}
break;
}
}
return TRUE;
}
本意是,我写的dll不能被两个程序同时调用,也不能在一个程序中,同时使用dll的两个函数。
就是上面的加解密功能,点击加密按钮后,如果再点击解密按钮,dll提示程序正在运行,不能进行解密。同理,解密时也不能点击加密。
还有就是开两个上面的程序,一个点击加密后,另一个立即点击解密,这时dll要弹出提示程序正在运行。
不要说控制加密按钮点击后设置界面不可用,因为这只是个测试程序,是我自己写的,别人调用我的dll程序我都不知道别人的程序啥样。
本来,我写的这个测试程序中,点击加密或解密,然后再Loadlibrary,再获取函数进行加解密,这样做没有啥异常,满足我的本意。但是我修改了测试程序,在构造函数中加载了dll,获取了函数句柄。然后运行点击打开文件按钮时就弹出了程序正在运行的提示:
而且关了之后又继续弹了13次,才出来文件对话框。
所以这是怎么回事呢?如果上面代码不对该怎么实现我的本意呢?
1.ReleaseSemaphore应该换成ReleaseMutex
2.你的mutex是在公共命名空间,也就是说会变成全局只能创建一个,任何进程加载后实际上用的都是一个内核对象,实际上这个mutex处于allreadycreate,所以其他进程加载dll后属于openmutex,并且你释放代码写在了dll卸载后,所以只要有一个进程加载了dll,其他进程都无法获取到锁了,你的wait时间写的是等待0秒,所以其他进程都等于走进了超时逻辑
如果你想细分mutex可以参考我这个文章,https://blog.csdn.net/slslslyxz/article/details/112154474