您的位置:首页 > 编程语言 > C语言/C++

如何限制到 Visual C++ 中的一个实例的 32 位应用程序

2013-04-19 11:13 555 查看
注意Microsoft
Visual c + + 2005年、 Microsoft Visual c + +.net 2003年和 Microsoft Visual c + +.net 2002年支持托管的代码模型所提供的 Microsoft.net 框架和非托管本机 Windows 代码模型。本文中的信息仅适用于非托管的 Visual c + + 代码。




概要

本文讨论如何限制到一个实例的应用程序。在本文中使用的方法不依赖于任何创建的窗口。因此,可以使用该方法来限制应用程序可以在 Visual C++ 中开发的一个实例。这包括控制台应用程序、 WinCE 应用程序、 对话框框基于应用程序、 应用程序没有图形用户界面,以及其他应用程序。


回到顶端
 | 提供反馈




更多信息

在本文中使用的方法是 MSDN 中描述的 WinMain 主题下的一个。它使用CreateMutex函数来创建命名的互斥体,可以跨进程进行检查。而不是复制的每个应用程序,您将使用作为单一实例相同的代码,您必须具有该代码是在 c + + 包装类中,您可以在每个应用程序之间重复使用。

若要使用此功能,请按照下列步骤操作:
创建新的头文件的名称 LimitSingleInstance.h,并将其添加到您的项目。
将下面的代码复制到 LimitSingleInstance.h 文件中,并保存该文件:


#ifndef LimitSingleInstance_H
#define LimitSingleInstance_H

#include <windows.h>

//This code is from Q243953 in case you lose the article and wonder
//where this code came from.
class CLimitSingleInstance
{
protected:
DWORD  m_dwLastError;
HANDLE m_hMutex;

public:
CLimitSingleInstance(TCHAR *strMutexName)
{
//Make sure that you use a name that is unique for this application otherwise
//two apps may think they are the same if they are using same name for
//3rd parm to CreateMutex
m_hMutex = CreateMutex(NULL, FALSE, strMutexName); //do early
m_dwLastError = GetLastError(); //save for use later...
}

~CLimitSingleInstance()
{
if (m_hMutex)  //Do not forget to close handles.
{
CloseHandle(m_hMutex); //Do as late as possible.
m_hMutex = NULL; //Good habit to be in.
}
}

BOOL IsAnotherInstanceRunning()
{
return (ERROR_ALREADY_EXISTS == m_dwLastError);
}
};
#endif


注意在 Visual C++ 2005 中,您必须添加公共语言运行时支持的编译器选项 (/ clr:oldSyntax) 才能成功编译上面的代码示例。若要添加公共语言运行时支持的编译器选项,请按照下列步骤操作:
单击 项目,,然后再单击 ProjectName 属性。 

注意ProjectName 是项目的名称的占位符。
展开 配置属性,然后单击 常规。
在右窗格中单击以选中 公共语言运行库支持、 $ 旧语法 (/ clr:oldSyntax) 在 支持公共语言运行库 中项目设置。
单击 应用,然后单击 确定。
有关公共语言运行时支持的编译器选项的详细信息,请访问下面的 Microsoft 开发人员网络 (MSDN) Web 站点:
http://msdn2.microsoft.com/en-us/library/k8d11d4s.aspx

#include LimitSingleInstance.h 文件的入口点的程序所在的位置。如果这是在 MFC 应用程序中使用,则该应用程序的InitInstance()函数所在位置的文件。在
Win32 SDK 应用程序中,它是WinMain()函数所在的位置。在控制台应用程序中,它是main ()函数所在的位置。


#include "LimitSingleInstance.H"


创建入口点函数之前的CLimitSingleInstance类的全局实例。如果这使用 MFC 应用程序中,创建在InitInstance()函数前的实例。
全局CLimitSingleInstance实例的构造函数传递一个唯一的名称。建议您首先使用唯一的名称,以便进行重复检查时,另一个应用程序可能正在使用此文章将不会发生冲突。获取一个唯一的名称,没有任何人都有一种简便方法是使用
GUIDGEN 工具。若要访问工具,单击开始,单击运行,然后键入GUIDGEN。如果由于某种原因您不具有该工具,该工具作为
MSDN 中的示例。类型GUIDGEN在 MSDN 索引来查找它。请确保您使用的注册表格式选项的 GUIDGEN 工具。


#include "LimitSingleInstance.H"// The one and only CLimitSingleInstance object.
// Change what is passed to constructor. GUIDGEN Tool may be of help.
CLimitSingleInstance g_SingleInstanceObj(TEXT("Global\\{719967F0-DCC6-49b5-9C61-DE91175C3187}"));


在您的输入点函数、 CLimitSingleInstance类的全局实例上调用IsAnotherInstanceRunning()方法和检查返回值。如果该函数返回 TRUE,则返回从入口点函数。否则,请继续执行情况正常。

在 MFC 应用程序,您可以执行类似于以下内容:


#include "LimitSingleInstance.H"// The one and only CLimitSingleInstance object.
CLimitSingleInstance g_SingleInstanceObj(TEXT("Global\\{05CA3573-B449-4e0b-83F5-7FD612E378E9}"));

BOOL CSingleInstDlg5App::InitInstance()
{
if (g_SingleInstanceObj.IsAnotherInstanceRunning())
return FALSE;

//Rest of code.
}


在控制台应用程序中,您可以执行类似于以下内容:


#include "LimitSingleInstance.H"// The one and only CLimitSingleInstance object.
CLimitSingleInstance g_SingleInstanceObj(TEXT("Global\\{9DA0BEED-7248-450a-B27C-C0409BDC377D}"));

int main(int argc, char* argv[])
{
if (g_SingleInstanceObj.IsAnotherInstanceRunning())
return 0;
//Rest of code.
}


在 Win32 SDK 应用程序中,您可以执行类似操作如下:


#include "LimitSingleInstance.H"// The one and only CLimitSingleInstance object.
CLimitSingleInstance g_SingleInstanceObj(TEXT("Global\\{2194ABA1-BFFA-4e6b-8C26-D191BB16F9E6}"));

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int cmdShow)
{
if (g_SingleInstanceObj.IsAnotherInstanceRunning())
return FALSE;
//Rest of code.
}


执行以下步骤后,应用程序将不允许多个实例同时保持活动状态。

注意当终端服务下运行时,不会添加 Global\ 将保证每个终端服务会话一个实例。


CLimitSingleInstance g_SingleInstanceObj(TEXT("{719967F0-DCC6-49b5-9C61-DE91175C3187}"));


添加"Global\"将能保证没有只有一台计算机上的应用程序的一个实例。这适用于是否正在运行终端服务。

转自:http://support.microsoft.com/kb/243953




概要

本文讨论如何限制到一个实例的应用程序。在本文中使用的方法不依赖于任何创建的窗口。因此,可以使用该方法来限制应用程序可以在 Visual C++ 中开发的一个实例。这包括控制台应用程序、 WinCE 应用程序、 对话框框基于应用程序、 应用程序没有图形用户界面,以及其他应用程序。


回到顶端
 | 提供反馈




更多信息

在本文中使用的方法是 MSDN 中描述的 WinMain 主题下的一个。它使用CreateMutex函数来创建命名的互斥体,可以跨进程进行检查。而不是复制的每个应用程序,您将使用作为单一实例相同的代码,您必须具有该代码是在 c + + 包装类中,您可以在每个应用程序之间重复使用。

若要使用此功能,请按照下列步骤操作:
创建新的头文件的名称 LimitSingleInstance.h,并将其添加到您的项目。
将下面的代码复制到 LimitSingleInstance.h 文件中,并保存该文件:


#ifndef LimitSingleInstance_H
#define LimitSingleInstance_H

#include <windows.h>

//This code is from Q243953 in case you lose the article and wonder
//where this code came from.
class CLimitSingleInstance
{
protected:
DWORD  m_dwLastError;
HANDLE m_hMutex;

public:
CLimitSingleInstance(TCHAR *strMutexName)
{
//Make sure that you use a name that is unique for this application otherwise
//two apps may think they are the same if they are using same name for
//3rd parm to CreateMutex
m_hMutex = CreateMutex(NULL, FALSE, strMutexName); //do early
m_dwLastError = GetLastError(); //save for use later...
}

~CLimitSingleInstance()
{
if (m_hMutex)  //Do not forget to close handles.
{
CloseHandle(m_hMutex); //Do as late as possible.
m_hMutex = NULL; //Good habit to be in.
}
}

BOOL IsAnotherInstanceRunning()
{
return (ERROR_ALREADY_EXISTS == m_dwLastError);
}
};
#endif


注意在 Visual C++ 2005 中,您必须添加公共语言运行时支持的编译器选项 (/ clr:oldSyntax) 才能成功编译上面的代码示例。若要添加公共语言运行时支持的编译器选项,请按照下列步骤操作:
单击 项目,,然后再单击 ProjectName 属性。 

注意ProjectName 是项目的名称的占位符。
展开 配置属性,然后单击 常规
在右窗格中单击以选中 公共语言运行库支持、 $ 旧语法 (/ clr:oldSyntax) 在 支持公共语言运行库 中项目设置。
单击 应用,然后单击 确定
有关公共语言运行时支持的编译器选项的详细信息,请访问下面的 Microsoft 开发人员网络 (MSDN) Web 站点:
http://msdn2.microsoft.com/en-us/library/k8d11d4s.aspx

#include LimitSingleInstance.h 文件的入口点的程序所在的位置。如果这是在 MFC 应用程序中使用,则该应用程序的InitInstance()函数所在位置的文件。在
Win32 SDK 应用程序中,它是WinMain()函数所在的位置。在控制台应用程序中,它是main ()函数所在的位置。


#include "LimitSingleInstance.H"


创建入口点函数之前的CLimitSingleInstance类的全局实例。如果这使用 MFC 应用程序中,创建在InitInstance()函数前的实例。
全局CLimitSingleInstance实例的构造函数传递一个唯一的名称。建议您首先使用唯一的名称,以便进行重复检查时,另一个应用程序可能正在使用此文章将不会发生冲突。获取一个唯一的名称,没有任何人都有一种简便方法是使用
GUIDGEN 工具。若要访问工具,单击开始,单击运行,然后键入GUIDGEN。如果由于某种原因您不具有该工具,该工具作为 MSDN
中的示例。类型GUIDGEN在 MSDN 索引来查找它。请确保您使用的注册表格式选项的 GUIDGEN 工具。


#include "LimitSingleInstance.H"// The one and only CLimitSingleInstance object.
// Change what is passed to constructor. GUIDGEN Tool may be of help.
CLimitSingleInstance g_SingleInstanceObj(TEXT("Global\\{719967F0-DCC6-49b5-9C61-DE91175C3187}"));


在您的输入点函数、 CLimitSingleInstance类的全局实例上调用IsAnotherInstanceRunning()方法和检查返回值。如果该函数返回 TRUE,则返回从入口点函数。否则,请继续执行情况正常。

在 MFC 应用程序,您可以执行类似于以下内容:


#include "LimitSingleInstance.H"// The one and only CLimitSingleInstance object.
CLimitSingleInstance g_SingleInstanceObj(TEXT("Global\\{05CA3573-B449-4e0b-83F5-7FD612E378E9}"));

BOOL CSingleInstDlg5App::InitInstance()
{
if (g_SingleInstanceObj.IsAnotherInstanceRunning())
return FALSE;

//Rest of code.
}


在控制台应用程序中,您可以执行类似于以下内容:


#include "LimitSingleInstance.H"// The one and only CLimitSingleInstance object.
CLimitSingleInstance g_SingleInstanceObj(TEXT("Global\\{9DA0BEED-7248-450a-B27C-C0409BDC377D}"));

int main(int argc, char* argv[])
{
if (g_SingleInstanceObj.IsAnotherInstanceRunning())
return 0;
//Rest of code.
}


在 Win32 SDK 应用程序中,您可以执行类似操作如下:


#include "LimitSingleInstance.H"// The one and only CLimitSingleInstance object.
CLimitSingleInstance g_SingleInstanceObj(TEXT("Global\\{2194ABA1-BFFA-4e6b-8C26-D191BB16F9E6}"));

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int cmdShow)
{
if (g_SingleInstanceObj.IsAnotherInstanceRunning())
return FALSE;
//Rest of code.
}


执行以下步骤后,应用程序将不允许多个实例同时保持活动状态。

注意当终端服务下运行时,不会添加 Global\ 将保证每个终端服务会话一个实例。


CLimitSingleInstance g_SingleInstanceObj(TEXT("{719967F0-DCC6-49b5-9C61-DE91175C3187}"));


添加"Global\"将能保证没有只有一台计算机上的应用程序的一个实例。这适用于是否正在运行终端服务。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: