社区
进程/线程/DLL
帖子详情
防止打开多个exe
lonelyrains
2010-11-19 03:44:14
编写了一个小应用程序,采用MFC工程,生成了exe文件。
代码中应添加什么内容,使得只允许打开一个exe例程。且在此点击该exe的图标时,已运行的该exe的实例放到桌面的顶端?
学MFC不久,请大家给些方法。方法越多越好!
...全文
987
45
打赏
收藏
防止打开多个exe
编写了一个小应用程序,采用MFC工程,生成了exe文件。 代码中应添加什么内容,使得只允许打开一个exe例程。且在此点击该exe的图标时,已运行的该exe的实例放到桌面的顶端? 学MFC不久,请大家给些方法。方法越多越好!
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
45 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
MYNAMELIULI
2010-12-28
打赏
举报
回复
楼上的答得都不错.
chzhn
2010-12-28
打赏
举报
回复
[Quote=引用 22 楼 freecodeman 的回复:]
问以上各楼,,如何 破解CreateMutex的方法,,,
使得可多开??
[/Quote]
如果在调试器里面调试的时候很简单,bp OpenMutexA(W),然后在返回的位置修改标志位达到跳转的目的,如果没有使用调试器,可以使用全局Hook IAT(导入表)的方法,修改OpenMutex函数结束的位置,比较当前进程名,如果是的话,修改标志位,然后返回。
青稞
2010-12-28
打赏
举报
回复
9楼的正解。。
创建互斥,然后判定该内核对象是否已经存在。。
如果已经存在,则Findwindow,把已经运行的窗口重新激活,显示在前面
//检测软件是否重复启动
BOOL ConsoleApp::IsRepeatRun()
{
BOOL bRet = FALSE;
m_hMutex = CreateMutex(NULL, FALSE, _T("AAAA"));
try
{
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
CloseHandle(m_hMutex);
CWnd *pWndPrev = NULL;
CWnd *pWndChild = NULL;
pWndPrev = CWnd::FindWindow(NULL, _T("什么窗口"));
if (pWndPrev != NULL)
{
if (pWndPrev->IsIconic() == TRUE)
{
pWndPrev->ShowWindow(SW_RESTORE);
}
pWndChild = pWndPrev->GetLastActivePopup();
if (pWndChild != NULL)
{
pWndChild->SetForegroundWindow();
}
}
return TRUE;
}
}
catch (CException *e)
{
TCHAR szErr[255] = {0};
e->GetErrorMessage(szErr, 255);
MessageBox(NULL, szErr, _T("系统提示"), MB_OK | MB_ICONERROR);
return TRUE;
}
return bRet;
}
SiGoYi
2010-12-28
打赏
举报
回复
按上述做法如果程序非正常结束,不能把互斥对象释放是不是就会有问题。
个人感觉还是在每次启动时枚举一下进程名要好一些。
当然如果有人用黑客手段的话,那怎么也防不了。总有比你高的人。
chzhn
2010-12-28
打赏
举报
回复
还可以以独占文件的方法,感觉这个方法破解起来反而比较难,程序启动的时候以独占的方式打开一个特殊的重要文件(文件句柄直到程序退出才关闭),并使用该文件的数据,就像Windows的储巢文件一样。
jamseyang
2010-12-27
打赏
举报
回复
[Quote=引用 26 楼 coding_hello 的回复:]
CreateMutex啊,典型用法。命名对象前面加上Global\前缀,就可以全局唯一了。
不加前缀的话,换个桌面,比如远程桌面登录过来,就又能启动。
[/Quote]
现在才知道^_^
rolax
2010-12-22
打赏
举报
回复
创建互斥对象
wnx_u
2010-12-22
打赏
举报
回复
WinMain函数的第二个参数就是该程序的前一个进程句柄,第二个问题,只要发个消息把该窗口显示出来就可以了啊,很简单的啊
iamzxx
2010-12-21
打赏
举报
回复
CreateMutex啊,典型用法。命名对象前面加上Global\前缀,就可以全局唯一了。
不加前缀的话,换个桌面,比如远程桌面登录过来,就又能启动。
-------
谢谢了,我这阵正为这个烦恼呢!!
wangbo56916860
2010-12-20
打赏
举报
回复
命名空间 mutex 可能会导致DOS 得非法攻击
bulerain
2010-12-15
打赏
举报
回复
看看msdn的CreateMutex的说明:createfile然后lockfile,那么第一个进程creatfile的时候就不能lockfile了,这样来判断是否存在了一个实例。
mtj530
2010-12-15
打赏
举报
回复
楼上的答得都不错.
panasonic0804
2010-12-14
打赏
举报
回复
信号量的用法先学习了。
Simao
2010-12-14
打赏
举报
回复
学习学习了
xiaohuh421
2010-12-14
打赏
举报
回复
SEM_OBJECT TEXT("C_MAIN_OBJECT")
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam )
{
//TCHAR buf[100]={0};
//GetWindowText(hwnd,buf,100);
//OutputDebugString(buf);
if(::GetProp(hwnd,SEM_OBJECT))//遍历窗口,得到有SEM_OBJECT标记的窗口,
{
::ShowWindow(hwnd,SW_RESTORE);//显示这个窗口
::SetForegroundWindow(hwnd);//前台显示.
return FALSE;
}
return TRUE;
}
BOOL IsExeExist()
{
//让本程序只远行一个实例
//方法1
/*HANDLE hEvent = OpenEvent(EVENT_ALL_ACCESS,TRUE,SEM_OBJECT);
if(NULL != hEvent)
{
//TCHAR buf[MAX_PATH]={0};
//GetModuleFileName(NULL,buf,MAX_PATH);
//CCheckObject ch;
//DWORD dwThreadId=ch.GetThreadId(PathFindFileName(buf));
//EnumThreadWindows(dwThreadId,EnumThreadWndProc,NULL);
CloseHandle(hEvent);
//OutputDebugString(TEXT("该程序已经在运行,不能打开另一个副本!"));
return TRUE;
}
m_hEvent = CreateEvent(NULL,TRUE,TRUE,SEM_OBJECT);*/
//方法2
HANDLE hSem=CreateSemaphore(NULL,1,1,SEM_OBJECT);//创建这个标记
if(hSem)
{
if(ERROR_ALREADY_EXISTS==GetLastError())//如果是已经存在,则说明程序已经运行过.
{
EnumWindows(EnumWindowsProc,NULL);//枚举哪个窗口有这个标记
return TRUE;
}
}
return FALSE;
}
BOOL chSetProp(HWND hWnd)
{
if(hWnd)
{
if(::SetProp(hWnd,SEM_OBJECT,(HANDLE)112233))//设置某个窗口拥有这个标记,
{ //第三个参数可以不管.
m_hWnd=hWnd;
return TRUE;
}
}
return FALSE;
}
调用方法:
if(IsExist()==FALSE)//是否存在
{
chSetProp(hWnd);不存在则把当前窗口设置拥有这个标记.
}
sd666850
2010-12-14
打赏
举报
回复
方法很多啊,CreateSemaphore我就知道这一个
xuting0
2010-12-14
打赏
举报
回复
CreatMutex()创建命名对象
if(ERROR_ALREADY_EXISTS == GetLastError())
{
AfxMessageBox("已经运行");
return;
}
Lingxy
2010-12-10
打赏
举报
回复
////////// 该方法运行一个实例并激活该程序
// 用应用程序名创建信号量
HANDLE hSem = CreateSemaphore(NULL, 1, 1, m_pszExeName);
// 信号量已存在? 信号量存在,则程序已有一个实例运行
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
// 关闭信号量句柄
CloseHandle(hSem);
// 寻找先前实例的主窗口
HWND hWndPrevious = ::GetWindow(::GetDesktopWindow(), GW_CHILD);
while (::IsWindow(hWndPrevious))
{
// 检查窗口是否有预设的标记? 有,则是我们寻找的主窗
if (::GetProp(hWndPrevious, m_pszExeName))
{
//::SendMessage(hWndPrevious,::RegisterWindowMessage(_T("RestoreWindow")),0,0);
// 主窗口已最小化,则恢复其大小
if (::IsIconic(hWndPrevious))
::ShowWindow(hWndPrevious, SW_RESTORE);
// 将主窗激活
::SetForegroundWindow(hWndPrevious);
// 退出本实例
return FALSE;
}//if (::GetProp(hWndPrevious, m_pszExeName)){
// 继续寻找下一个窗口
hWndPrevious = ::GetWindow(hWndPrevious, GW_HWNDNEXT);
}//while (::IsWindow(hWndPrevious)){
// 若运行到此,说明没有执行 While 中的 return FALSE,即:
// 前一实例已存在,但找不到其主窗。 可能出错了
return FALSE; // 退出本实例
}//if (GetLastError() == ERROR_ALREADY_EXISTS)
//////////////////////////////end
cmlr_
2010-12-02
打赏
举报
回复
[Quote=引用 26 楼 coding_hello 的回复:]
CreateMutex啊,典型用法。命名对象前面加上Global\前缀,就可以全局唯一了。
不加前缀的话,换个桌面,比如远程桌面登录过来,就又能启动。
[/Quote]
啊,还有这一说,不错,学习了
野男孩
2010-12-01
打赏
举报
回复
CreateMutex啊,典型用法。命名对象前面加上Global\前缀,就可以全局唯一了。
不加前缀的话,换个桌面,比如远程桌面登录过来,就又能启动。
加载更多回复(23)
MFC开发之
exe
避免多开,只能
打开
一个
exe
方法
在InitInstance()函数中添加: CreateMutex(NULL, TRUE, TEXT("主界面标题名称")); //避免程序的多开 xxxx为信号量的名字 可随意 if (GetLastError() == ERROR_ALREADY_EXISTS) { CWnd* cwnd = CWnd::FindWindow(NULL, TEXT("主界面标题名称"));//wi...
Unity中
防止
多个
客户端同时
打开
在游戏开发中,我们通常会为了
防止
用户同时
打开
多个
端口,进行一些处理。大概的逻辑就是,首先判断有没有端口已经
打开
,如果有,则关闭将要
打开
的端口,如果没有,则
打开
端口。这里只是在Window下进行的操作,下面是具体实现: 【AppleScript】 #if UNITY_STANDALONE_WIN using System; using System.Diagnostics; using S
Unity 打包
exe
防止
用一个
exe
多次启动
通过C#调用的window中自带的动态库,来
防止
exe
重复启动,仅供小白参考using System;using System.Runtime.InteropServices;using System.Threading;using UnityEngine;public class
Exe
_control : MonoBehaviour{ public string m_WindowClas...
MFC
防止
同一个
exe
应用程序多次启动
// 唯一的一个 CLoaderApp 对象 CLoaderApp theApp; // CLoaderApp 初始化 BOOL CModelDownLoaderApp::InitInstance() { // 如果一个运行在 Windows XP 上的应用程序清单指定要 // 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式, //则需要 InitCommonControlsEx()。否则,将无法创建窗口。 INITCOMMONCONTROLSEX InitCtrls;
Windows下C++
防止
进程多开
1. 概念
防止
进程多开,一般是特指
防止
同一个
exe
进程重复
打开
。为什么要
防止
进程多开呢? 功能设计上不让用户
打开
两次,如各种游戏客户端。
防止
多进程对资源访问的冲突。如当前进程对某文件可能在进行写读操作,再
打开
新进程时可能的写读操作会导致出现文件访问异常甚至崩溃。 2. 方法 网上很多资料推荐利用遍历窗口来判断,如果找到对应的窗口则认为进程已经
打开
。这种方法其实存在很大的风险。 窗口创建的过程中可能因为系统消息阻塞导致创建很慢,那么在窗口创建过程中再
打开
进程,并通过遍历窗口来判断则可能失败。 窗口关
进程/线程/DLL
15,467
社区成员
49,171
社区内容
发帖
与我相关
我的任务
进程/线程/DLL
VC/MFC 进程/线程/DLL
复制链接
扫一扫
分享
社区描述
VC/MFC 进程/线程/DLL
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章