先留着以后有用。

让程序只运行一个实例的四种方法 综述:让一个程序只运行一个实例的方法有多种,但是原理都类似,也就是在程序创建前,有窗口的程序在窗口创建前,检查系统中是否已经设置了某些特定标志了,如果有说明已经有一个实例在运行了,则当前程序通知用户怎样怎样,然后程序退出,当然方法有这么多,各自也就有自己的优缺点了。<注意下面的程序都是分块拷贝的>

方法一:
我用得做多的方法是创建互斥体Mutex,使用Mutex代码比较简洁,但是此时不能取得已经启动的实例窗口局柄,因此无法激活已经启动的实例窗口,代码如下:
// -------------------------------------------------------------------------
// 函数  : CreateSendingWNDList
// 功能  : 创建互斥量,用于保证只启动一个进程
// 返回值 : int
//            成功   0
//     失败   -1
//     存在进程实例 1
// 附注  :
// -------------------------------------------------------------------------
int CreateSendingWNDList(const TCHAR *pstrKSCoreAppName)
{
 //-------防止多次起动---------- 
 HANDLE hMutex = ::CreateMutex(0, true, pstrKSCoreAppName);
 int nRet = 0;
 if (hMutex)
 {
  if(GetLastError() == ERROR_ALREADY_EXISTS)
  {
   nRet = 1;
  }
  else
  {
   nRet = 0;
  }
 }
 else
 {
  nRet = -1;
 }

return nRet;
}

// 在创建窗口前调用下面代码
switch(CreateSendingWNDList(g_strKSCoreAppName))
{
case 0:
 // 正常启动
 // TODO……

break; 
case 1: 
 // 已存在进程,退出
 {
  ::MessageBox(NULL, TEXT("已经有一个实例在运行了。"), TEXT("注意"), MB_OK);
 }

case -1:// 无法创建,退出
default:
 return FALSE;
}

方法二:
一般来说,使程序只运行一个实例的最简单的方法当然是使用FindWindow()查找主窗口,如果主窗口已经存在了,当然说明已经有一个实例运行了。代码如下:
// 这种方法有缺陷,窗口名字改变之后就再也找不到了,FindWindow()的参数ClassName和Caption比较难取得。
HWND hWnd = FindWindow(NULL, TEXT("SingleInstanceFW"));
if(IsWindow(hWnd))
{
 ::MessageBox(NULL, TEXT("已经有一个实例在运行了。"), TEXT("注意"), MB_OK);
 ::ShowWindow(hWnd, SW_NORMAL);     // 显示
 ::SetForegroundWindow(hWnd);       // 激活
 return FALSE;
}

方法三:

这种方法相比上面两种方法,避免上面两种方法的缺点,通过SetProp()为程序主窗口设置一个特殊的Property,然后在启动时遍历所有的窗口,找出包含着个Property的窗口局柄

。【这个附加的窗口属性在窗口销毁时也应该销毁】这个方法的缺点就是代码比较多一点,如下:

// 声明全局的 属性 名和 属性值
TCHAR g_strKSCoreAppName[] = _T("AFX_KSInstall_CPP__12036F8B_8301_46e2_ADC5_A14A44A85877__");
HANDLE g_hValue = (HANDLE)1022;

// 定义枚举窗口回调函数
BOOL CALLBACK EnumWndProc(HWND hwnd, LPARAM lParam)
{
 //TCHAR str[200] = {0};
 //::GetWindowText(hwnd, str, 200);
 HANDLE h = GetProp(hwnd, g_strKSCoreAppName);
 if(h == g_hValue)
 {
  *(HWND*)lParam = hwnd;
  return FALSE;
 }
 return TRUE;
}

// 主窗口创建前判断
HWND oldHWnd = NULL;
::EnumWindows(EnumWndProc,(LPARAM)&oldHWnd);    //枚举所有运行的窗口
if (oldHWnd != NULL)
{
 ::MessageBox(NULL, TEXT("已经有一个实例在运行了。"), TEXT("注意"), MB_OK);

::ShowWindow(oldHWnd, SW_NORMAL);     // 显示
 ::SetForegroundWindow(oldHWnd);       // 激活
 return FALSE;
}

// 主窗口创建后设置,为窗口附加一个属性
::SetProp(m_hWnd, g_strKSCoreAppName, g_hValue);

// 主窗口退出时移除该附加属性
::RemoveProp(m_hWnd, g_strKSCoreAppName);

方法四:

上面的方法二和方法三都有一个弊病,不知道大家发现没,那就是依赖于窗口的存在,没有窗口的程序怎么办了,用方法一是可以的,不过方法一不太适合即时修改状态,譬如我想提供选项给用户,可以即时修改是否允许多实例,像KMP就提供了即时修改是否允许多实例,使用全局变量是一个比较好的解决方案,使用全局共享变量的方法则主要是在VC框架程序中通过编译器来实现的。通过#pragma data_seg预编译指令创建一个新节,在此节中可用volatile关键字定义一个变量,而且必须对其进行初始化。Volatile关键字指定了变量可以为外部进程访问。最后,为了使该变量能够在进程互斥过程中发挥作用,还要将其设置为共享变量,同时允许具有读、写访问权限。这可以通过#pragma comment预编译指令来通知编译器。下面给出使用了全局变量的进程互斥代码清单:

#pragma data_seg("Shared")
int volatile g_lAppInstance = 0;
#pragma data_seg()
#pragma comment(linker,"/section:Shared,RWS")

if (0 == g_lAppInstance)
{
 g_lAppInstance = 1;
}
else if (1 == g_lAppInstance)
{
 ::MessageBox(NULL, TEXT("已经有一个实例在运行了。"), TEXT("注意"), MB_OK);
 return FALSE;
}
else
{
 // 直接启动
}

【注意,代码应该放在程序的入口处】

其实上面的方法可以两种进行组合来实现一些比较特殊的需求,具体怎样就自己去想了。

藏经阁18839资源网www.18839.com

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/magictong/archive/2008/12/25/3603015.aspx

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/xtremesoft/archive/2009/10/26/4729081.aspx

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/xtremesoft/archive/2009/10/26/4729081.aspx

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/xtremesoft/archive/2009/10/26/4729081.aspx

转:让程序只运行一个实例的四种方法相关推荐

  1. 解决C#程序只允许运行一个实例的几种方法详解

    解决C#程序只允许运行一个实例的几种方法详解 参考文章: (1)解决C#程序只允许运行一个实例的几种方法详解 (2)https://www.cnblogs.com/randyzhuwei/p/5403 ...

  2. 让Java程序只运行一个实例

    一个程序可以在内存里面存在多个运行实例,比如,你可以打开多个微软的Word程序.但是,有些时候我们需要控制程序运行的实例只有一个,也就是说,该程序同一时刻在内存里面运行的只有一个实例.这样当这个程序在 ...

  3. Qt应用程序只运行一个实例

    在实际应用中,我们经常需要让应用程序只有一个实例,再打开新的文档或者页面时,只是替换现在的窗口或者新打开一个标签,而不是重新启动一次应用程序.Qt中是否可以做到这样呢,答案是肯定的,因为Qt本身可以直 ...

  4. delphi 只允许运行一个实例的三种方法《转》

    一.创建互斥对象 在工程project1.dpr中创建互斥对象 Program project1UsesWindows,Form,FrmMain in 'FrmMain.pas' {MainForm} ...

  5. 只运行一个实例的方法

    在VC++ 中编程中,只运行一个实例的方法主要有两类: 1 遍历当前的所有窗口,查找相同的实例.为了便于查找,一般要事先设一个查找标志. 2 利用系统提供的互斥对象或信标,直接让系统抑制重复的实例. ...

  6. 限制程序只打开一个实例(转载)

    当我们在做一些管理平台类的程序(比如Windows的任务管理器)时,往往需要限制程序只能打开一个实例.解决这个问题的大致思路很简单,无非是在程序打开的时候判断一下是否有与自己相同的进程开着,如果有,则 ...

  7. 只运行一个实例的写法

    有时我们需要只允许运行应用程序的一个实例,当进程启动时,如果发现应用程序的一个实例在运行,就自动停止运行.我们通常通过Mutex互斥体在Main函数中实现,通常的写法是: [STAThread] st ...

  8. 运行jar应用程序引用其他jar包的四种方法

    http://longdick.iteye.com/blog/332580 大家都知道一个java应用项目可以打包成一个jar,当然你必须指定一个拥有main函数的main class作为你这个jar ...

  9. 让你的程序只能运行一个实例

        先说一个循环系统进程的方法吧,             //首先取得你的程序当前进程             Process current = Process.GetCurrentProce ...

最新文章

  1. 经典C语言程序100例之九六
  2. C/C++ strict-aliasing
  3. 负载均衡层设计方案(2)——Nginx安装
  4. Java编写学生类student程序_编写一个JAVA程序片断定义一个表示学生的类student.docx...
  5. 【中台实践】滴滴大数据研发中台的最佳实践.pdf(附下载链接)
  6. 小米11和vivox60买哪个?
  7. c语言数组和字符串编程题,C语言中的字符数组和字符串详解
  8. nvm装node npm
  9. c语言sobel边缘检测,C/C++ OpenCV之Sobel边缘检测
  10. swing禁用最大化、去掉java图标、设置窗口为中央显示
  11. 《Nature》论文插图复刻第3期—面积图(Part2-100)
  12. 如何回答面试官“你为什么从上家公司离职”?
  13. php执行fastlane,fastlane使用说明
  14. spire.doc操作word文档工具类(自用)
  15. 男性软件测试师容易找到女朋友吗?
  16. [附源码]计算机毕业设计Python+uniapp作业批改系统APP4238p(程序+lw+APP+远程部署)
  17. MATLAB----绘制三维曲线
  18. avahi-daemon启动失败-解决方法-linux
  19. SPSS进行数据分析的一般步骤
  20. camstar portal 7全屏显示

热门文章

  1. ggspatial | ggplot2的地图制作拓展包(1):如何添加指北针和比例尺
  2. sf | 空间矢量对象的属性连接方法
  3. java io字符流_Java IO流字符流简介及基本使用
  4. 面试官通过21天步数考察候选人诚意,结果拒了清华生收了三本生
  5. 软件测试工作都干些什么?
  6. 大学生学java要去培训机构吗?
  7. 控制服务器系统设计,基于 DNS 技术的顶管机远程控制系统设计与实现
  8. php小程序的wxparse.js是什么,微信小程序如何解析HTML富文本(使用wxParse解析富文本的demo)...
  9. @service注解_SpringBoot最最最常用的注解梳理
  10. 左移寄存器vhdl_VHDL实验代码:8位移位寄存器