打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
多开限制的原理
分类: VC/C/C++ 2011-08-02 14:35 597人阅读 评论(0) 收藏 举报

1.创建新节法

        为程序加入一个全局变量,让这个全局变量可以被程序的多个实例所共享,每当程序实例运行时就对该全局变量进行修改。通过访问该全局变量,就可以知道有多少个实例在运行了。当然,为了系统的安全和稳定性,默认情况下是不允许这样做得。为了阻止这种事情的发生,系统使用了copy-on-write(写入时拷贝)机制,不过我们可以使用创建新节的方法来绕过它。

1.创建节

  1. #pragma data_seg("Shared")   
  2. BOOL bExist = FALSE; //已经初始化变量   
  3. int num; //未初始化变量  
  4. #pragma data_seg()   

注:在创建节的过程中,编译器只将已经初始化的变量放入新节中。

2.将初始化或未初始化的数据放入希望的任何节中  

  1. __declspec(allocate("Shared")) int num2 = 0; //添加初始化的变量   
  2. __declspec(allocate("Shared")) int num3; //添加未初始化的变量   

注:在向节中添加数据之前必须先创建该节。

3.设置节的属性

  1. #pragma comment(linker, "/Section:Shared,RWS")   

 注:节的属性包括RWS,其中R代表READ,W代表WEITE,S代表SHARED。

使用:

  1. #pragma data_seg("Shared")   
  2. HWND hWnd=NULL;  
  3. #pragma data_seg()   
  4. #pragma comment(linker, "/Section:Shared,RWS")   


初始化函数中:

  1. if (hWnd==NULL)  
  2.     {  
  3.         hWnd=m_hWnd;  
  4.     }  
  5.     else  
  6.     {  
  7.         AfxMessageBox(_T("只允许运行一个实例!"));  
  8.         ::SetForegroundWindow(hWnd);  
  9.         ExitProcess(0);  
  10.     }  


 2.互斥体法

缺点是无法激活旧窗口

  1. hObject=CreateMutex(NULL,FALSE,_T("互斥体"));  
  2. if (GetLastError()==ERROR_ALREADY_EXISTS)  
  3. {  
  4.     AfxMessageBox(_T("只允许运行一个实例!"));  
  5.     ExitProcess(0);  
  6. }  

3.查找窗口标题法

1.FindWindow

初始化函数中

  1.         HWND hWnd=::FindWindow(NULL,_T("FindWindow单实例"));  
  2. if (hWnd!=NULL)  
  3. {  
  4.     AfxMessageBox(_T("只允许运行一个实例!"));  
  5.     ::SetForegroundWindow(hWnd);  
  6.     ExitProcess(0);  
  7. }  
  8. SetWindowText(_T("FindWindow单实例"));  

2.EnumWindows

  1. BOOL   CALLBACK   MyEnumWndProc(HWND hwnd,LPARAM lParam)   
  2. {  
  3.     TCHAR szCaption[256]={0};  
  4.     GetWindowText(hwnd,szCaption,256);  
  5.     if (_tcscmp(_T("EnumWindows单实例"),szCaption)==0)  
  6.     {  
  7.         AfxMessageBox(_T("只允许运行一个实例!"));  
  8.         ::SetForegroundWindow(hwnd);  
  9.         ExitProcess(0);  
  10.     }  
  11.     return TRUE;  
  12. }   


初始化函数中

  1. EnumWindows(MyEnumWndProc,NULL);  
  2. SetWindowText(_T("EnumWindows单实例"));  


3.GetWindow

  1. TCHAR szCaption[MAX_PATH]={0};  
  2.     HWND hWnd=::GetWindow(::GetDesktopWindow(), GW_CHILD);  
  3.     while(hWnd!=NULL)  
  4.     {  
  5.         ::GetWindowText(hWnd,szCaption,MAX_PATH);  
  6.         if (_tcscmp(_T("GetWindow单实例"),szCaption)==0)  
  7.         {  
  8.             AfxMessageBox(_T("只允许运行一个实例!"));  
  9.             ::SetForegroundWindow(hWnd);  
  10.             ExitProcess(0);  
  11.         }  
  12.         hWnd=::GetWindow(hWnd, GW_HWNDNEXT);  
  13.     }  
  14.     SetWindowText(_T("GetWindow单实例"));  

 

4.枚举进程法

     1.定时器一直去监视有没有相同进程名字,发现则发送WM_CLOSE消息关闭窗口

     2.初始化时枚举进程,配合挂钩queryinfomation的内核函数,修改自己的进程名字

  

  

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
让程序只运行一个实例
VB 遍历窗口所有子窗体句柄
m_pMainWnd是MFC中的一个全局指针变量
Qt 笔记之全局变量的使用
RUBY中的变量(记录在此,避免忘记^
只让程序运行一次
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服