zoukankan      html  css  js  c++  java
  • C++实现程序单实例运行的两种方式

    简介

    在我们编写程序的时候,经常会注意到的一个问题就是如何能够让程序只运行一个实例,确保不会让同一个程序多次运行,从而产生诸多相同进程,给我们的带来不便呢?那么常用的有以下四种方法,第一种方法是通过扫描进程列表比对进程名来检测,第二种方法是通过枚举程序窗口的方式,第三种方法是采用共享全局变量来实现,第四种方法是通过创建互斥体来实现。
    那么在这些方法中,第一种和第二种方法是有缺陷的,扫描进程列表比对进程名容易对相同进程名字的不同程序产生误报,枚举窗口不适用于无窗口程序且与扫描进程列表的方法也有相同的缺陷。所以本文笔者为大家介绍第三种方法与第四种方法的具体实现。

    代码实现

    1. 互斥体实现方式

    //////////////////////////////////////////////////////////////////
    //
    // FileName : SingleRunByMutex.cpp
    // Creator : PeterZheng
    // Date : 2019/2/16 11:21
    // Comment : 互斥体实现进程单实例运行
    //
    //////////////////////////////////////////////////////////////////
    
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <Windows.h>
    
    using namespace std;
    
    // 使用互斥体保证单体运行
    BOOL IsAlreadyRun()
    {
    	HANDLE hMutex = NULL;
    	hMutex = CreateMutex(NULL, FALSE, "MYFLAG");
    	if (hMutex != NULL)
    	{
    		if (ERROR_ALREADY_EXISTS == GetLastError())
    		{
    			ReleaseMutex(hMutex);
    			return TRUE;
    		}
    	}
    	return FALSE;
    }
    
    // 主函数
    int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
    {
    	if (IsAlreadyRun())
    	{
    		MessageBox(NULL, "This Program is already RUN !", "Tips", MB_OK);
    	}
    	else
    	{
    		MessageBox(NULL, "I am RUN !", "Tips", MB_OK);
    		Sleep(30000);
    	}
    	ExitProcess(0);
    	return 0;
    }
    

    2. 共享全局变量实现方式

    //////////////////////////////////////////////////////////////////
    //
    // FileName : SingleRunByShareSeg.cpp
    // Creator : PeterZheng
    // Date : 2019/2/16 11:40
    // Comment : 通过共享全局变量的方式实现进程单实例运行
    //
    //////////////////////////////////////////////////////////////////
    
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <Windows.h>
    
    using namespace std;
    
    // 创建共享内存段
    #pragma data_seg("sharedata")
    DWORD dwFlagId = 0xEE;
    #pragma data_seg()
    #pragma comment(linker, "/SECTION:sharedata,RWS")
    
    // 使用共享内存段保证单体运行
    BOOL IsAlreadyRun()
    {
    	if (dwFlagId == 0xEF)
    	{
    		return TRUE;
    	}
    	return FALSE;
    }
    
    // 主函数
    int APIENTRY WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
    {
    	if (IsAlreadyRun())
    	{
    		MessageBox(NULL, "This Program is already RUN !", "Tips", MB_OK);
    	}
    	else
    	{
    		MessageBox(NULL, "I am RUN !", "Tips", MB_OK);
    		dwFlagId = 0xEF;
    		Sleep(30000);
    	}
    	ExitProcess(0);
    	return 0;
    }
    
    
  • 相关阅读:
    VitrualBox无法创建64位虚拟机
    SharePoint2010安装全过程
    SharePoint 2010 集成Window Live 认证遇到的问题 part1
    sharepoint 2007 page
    解决sharepoint 2010浏览器在线浏览Word出错
    http://newoinc.wordpress.com/2010/07/09/webpartpropertypaneokcancelapplybuttonsdisplayissue/
    jquery ajax 实现从service读取数据,done
    刚好理解:TreeView设置checkbox事件__doPostBack()
    ASPAJAXExtSetup 安装说明(转)
    一个简单登陆框的变化+更新了如何连接sql数据库,获得数据集,比较两种方法(数据集和读数据)
  • 原文地址:https://www.cnblogs.com/csnd/p/12896995.html
Copyright © 2011-2022 走看看