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;
    }
    
    
  • 相关阅读:
    Enterprise Library Step By Step系列(一):配置应用程序块——入门篇
    Enterprise Library Step By Step系列(八):日志和监测应用程序块——进阶篇
    在ASP.NET页面中冻结DataGrid的列或头部
    数据库设计技巧系列(五)——各种小技巧
    用任务计划实现数据库的异地备份
    如何更好的与人沟通?[图]
    在Asp.net中如何用SQLDMO来获取SQL Server中的对象信息
    SQL Server 2012 Express LocalDB
    Clay: 创建和使用深层次对象图
    VS 2012 的 单元测试 和 测试资源管理器
  • 原文地址:https://www.cnblogs.com/csnd/p/12896995.html
Copyright © 2011-2022 走看看