转载:http://blog.sina.com.cn/s/blog_4b44e1c00100bh69.html

进程的互斥运行:CreateMutex函数实现只运行一个程序实例

  正常情况下,一个进程的运行一般是不会影响到其他正在运行的进程的。但是对于某些有特殊要求的如以独占方式使用串行口等硬件设备的程序就要求在其进程运行期间不允许其他试图使用此端口设备的程序运行的,而且此类程序通常也不允许运行同一个程序的多个实例。这就引出了进程互斥的问题。

  实现进程互斥的核心思想比较简单:进程在启动时首先检查当前系统是否已经存在有此进程的实例,如果没有,进程将成功创建并设置标识实例已经存在的标记。此后再创建进程时将会通过该标记而知晓其实例已经存在,从而保证进程在系统中只能存在一个实例。具体可以采取内存映射文件、有名事件量、有名互斥量以及全局共享变量等多种方法来实现。下面就分别对其中具有代表性的有名互斥量和全局共享变量这两种方法进行介绍:

// 创建互斥量
 HANDLE m_hMutex = CreateMutex(NULL, FALSE, "Sample07");
 // 检查错误代码

// 如果程序已经存在并且正在运行
 if (GetLastError() == ERROR_ALREADY_EXISTS)

{
   // 如果已有互斥量存在则释放句柄并复位互斥量
  CloseHandle(m_hMutex);
  m_hMutex = NULL;
  // 程序退出
  return FALSE;
 }

  上面这段代码演示了有名互斥量在进程互斥中的用法。代码的核心是CreateMutex()对有名互斥量的创建。CreateMutex()函数可用来创建一个有名或无名的互斥量对象,其函数原型为:

HANDLE CreateMutex(
  LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全属性的指针
  BOOL bInitialOwner, // 初始化互斥对象的所有者
  LPCTSTR lpName // 指向互斥对象名的指针
  );

  如果函数成功执行,将返回一个互斥量对象的句柄。如果在CreateMutex()执行前已经存在有相同名字的互斥量,函数将返回这个已经存在互斥量的句柄,并且可以通过GetLastError()得到错误代码ERROR_ALREADY_EXIST。可见,通过对错误代码ERROR_ALREADY_EXIST的检测可以实现CreateMutex()对进程的互斥。

建立互斥体,用来同步。如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体。  
  参数  
  lpMutexAttributes    
  指向一个SECURITY_ATTRIBUTES结构的指针,这个结构决定互斥体句柄是否被子进程继承。     
  bInitialOwner 
  布尔类型,决定互斥体的创建者是否为拥有者  
  lpName    
  指向互斥体名字字符串的指针。互斥体可以有名字。  
  互斥体的好处是可以在进程间共享

将 CreateMutex 代码加到  ****App::InitInstance() 函数中即可实现只运行一个实例的效果。

以上文章转载自:我的程序员生涯 http://steveq.blog.sohu.com/71112121.html

通过上面文章我们知道:使用CreateMutex可以防止一个实例多次运行。

下面介绍如何实现当再次运行程序时如何激活已经运行的程序,比如此程序只是已被最小化。

方法如下:

 BOOL C**App::InitInstance()
{ //创建进程互斥体Sample07
m_hMutex = CreateMutex(NULL,TRUE,_T("Sample07")); if (m_hMutex == NULL)
{
return FALSE;
} //如果程序已经存在并且正在运行
if (GetLastError() == ERROR_ALREADY_EXISTS)
{ HWND hProgramWnd = ::FindWindow(NULL,L"Sample07");
if (hProgramWnd)
{
WINDOWPLACEMENT* pWndpl = NULL; WINDOWPLACEMENT wpm;
pWndpl =&wpm;
GetWindowPlacement(hProgramWnd,&wpm);
if (pWndpl)
{
//将运行的程序窗口还原成正常状态
pWndpl->showCmd = SW_SHOWNORMAL;
::SetWindowPlacement(hProgramWnd,pWndpl);
SetWindowPos(hProgramWnd,HWND_NOTOPMOST,,,,,SWP_NOSIZE|SWP_NOMOVE);
FlashWindow(hProgramWnd,TRUE);//任务栏图标闪烁
} }
//关闭进程互斥体 CloseHandle(m_hMutex);
m_hMutex = NULL;
return FALSE;
}
}

VC 实现程序只运行一个实例,并激活已运行的程序的更多相关文章

  1. Delphi实现程序只运行一次并激活已打开的程序

    我们的程序有时候只允许运行一次,并且最好的情况是,如果程序第二次运行,就激活原来的程序.网上有很多的方法实现程序只运行一次,但对于激活原来的窗口却都不怎么好.关键就在于激活原来的程序,一般的做法是在工 ...

  2. [Winform]只允许运行一个exe,如果已运行则将窗口置前

    摘要 接着介绍项目中用到的一些方法,在winform中,打好包,有时并不允许运行多个客户端,要保证只有一个客户端运行.如果已经运行了,则弹出已运行的窗口,使其展示. 方法 判断是否有相同的进程 /// ...

  3. WinForm判断程序是否已经在运行,且只允许运行一个实例

    我们开发WinFrom程序,很多时候都希望程序只有一个实例在运行,避免运行多个同样的程序,一是没有意义,二是容易出错. 为了更便于使用,笔者整理了一段自己用的代码,可以判断程序是否在运行,只运行一个实 ...

  4. C#[Win32&WinCE&WM]应用程序只能运行一个实例:MutexHelper

    前言 在开发应用程序时,通常只让程序运行一个实例.所以,就要判断程序是否已经运行. 下面是我自己在项目中使用到,封装好的帮助类.有 普通的 C# 应用程序 和 Windows CE 和 Windows ...

  5. Oracle 远程访问配置 在 Windows Forms 和 WPF 应用中使用 FontAwesome 图标 C#反序列化XML异常:在 XML文档(0, 0)中有一个错误“缺少根元素” C#[Win32&WinCE&WM]应用程序只能运行一个实例:MutexHelper Decimal类型截取保留N位小数向上取, Decimal类型截取保留N位小数并且不进行四舍五入操作

    Oracle 远程访问配置   服务端配置 如果不想自己写,可以通过 Net Manager 来配置. 以下配置文件中的 localhost 改为 ip 地址,否则,远程不能访问. 1.网络监听配置 ...

  6. vc++高级班之窗口篇[4]---让程序只运行一个实例

      大家都看过或者使用过类似只运行一个实例的程序,比如:QQ游戏.部分浏览器 等等! 让一个程序只运行一个实例的方法有多种,但是原理都类似,也就是在程序创建后,有窗口的程序在窗口创建前, 检查系统中是 ...

  7. [VC]在VC++中实现让程序只运行一个实例的方法且实现该实例

    方法一: 有时候在开发应用程序时,希望控制程序运行唯一的实例.例如,最常用的mp3播放软 件Winamp,由于它需要独占计算机中的音频设备,因此该程序只允许自身运行唯一的一个例程.在Visual C+ ...

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

    解决C#程序只允许运行一个实例的几种方法详解 本篇文章是对C#中程序只允许运行一个实例的几种方法进行了详细的分析介绍,需要的朋友参考下 本文和大家讲一下如何使用C#来创建系统中只能有该程序的一个实例运 ...

  9. C#程序只允许运行一个实例的解决方案

    最近在做winform的程序中,需要只能打开一个程序,如果已经存在,则激活该程序的窗口,并显示在最前端.在网上google了一哈,找到了很多的解决方案.这里我整理了3种方案,并经过了测试,现和朋友们分 ...

随机推荐

  1. iTop4412开发板+虚拟机+tftp服务

    感觉好坑啊 利用路由器+2根网线+tftp服务 首先是开发板,主机,虚拟机相互之间能ping通(坑), 关闭主机防火墙,防止被强 关闭虚拟机防火墙 虚拟机装上tftpd服务端(通过网上教程嘛) 是不是 ...

  2. IDEA 社区版集成TOMCAT

    直接在POM.XML中添加以下内容 <plugin>    <groupId>org.apache.tomcat.maven</groupId>    <ar ...

  3. Win10系统C盘空间不足怎么安全清理?

    我们在使用电脑时,系统经常会产生许多垃圾文件,占用磁盘存储空间.在Win10系统中,我们可以通过清理系统盘的临时文件来释放一些存储空间.下面好系统U盘启动就来告诉你具体的方法步骤. Win10系统C盘 ...

  4. Pycharm Community 配置 Django 开发环境

    1. 安装数据库可视化工具 Database Navigator 2. 括号匹配高亮工具 HighlightBracketPair (...) Web 开发放弃 Pycharm Community 版 ...

  5. CF 976F 递增容量最大流

    给你一个二分图 要求你求出对于k=[0~Mindegree] 每个点的度数至少为k所需要的最少边数 并输出方案 如果是单个询问的话 直接跑一个下界网络流即可 但是有多个询问 重建图强行跑不行 反过来考 ...

  6. django 发送邮件功能

    setting.py # 邮件配置 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.e ...

  7. Android之Json

    Servlet部分 public class JasonAction extends HttpServlet { private JsonService service; public void do ...

  8. MNPR--造福人类的人值得被感激

    https://artineering.io/research/MNPR/ https://mnpr.artineering.io https://pdfs.semanticscholar.org/0 ...

  9. css 过渡效果

    来自 https://www.w3school.com.cn/cssref/pr_transition-timing-function.asp css <!DOCTYPE html> &l ...

  10. 1 Java面向对象

    0 工具 在分析面向对象时最好采用UML图进行分析设计 1 Java面向对象的特点 java采用面向对象的方法设计程序主要体现在:对象有属性和方法,事件的发生是对象间的信息交互产生的即程序中的get ...