// Singleton.h #pragma once class CSingleton { public: CSingleton(LPCTSTR lpszBoundary = _T("MyAppBoundary"), LPCTSTR lpszNamespace = _T("MyAppNamespace")); virtual ~CSingleton(void); public: BOOL IsInstanceExist(LPCTSTR lpszMutex); private: void DUMPINFO(LPCTSTR lpszFormat, ...); private: HANDLE m_hSingleton; HANDLE m_hBoundary; HANDLE m_hNamespace; BOOL m_bNamespaceOpen; }; // Singleton.cpp #include "stdafx.h" #include "Singleton.h" #include <sddl.h> #pragma comment(lib, "Advapi32.lib") #define MAX_BUFFER_LENGTH (1024) CSingleton::CSingleton(LPCTSTR lpszBoundary, LPCTSTR lpszNamespace) : m_hSingleton(NULL), m_hBoundary(NULL), m_hNamespace(NULL), m_bNamespaceOpen(FALSE) { // Create the boundary descriptor if(lpszBoundary && _tcslen(lpszBoundary)) { m_hBoundary = CreateBoundaryDescriptor(lpszBoundary, 0); if(NULL == m_hBoundary) { DUMPINFO(_T("CreateBoundaryDescriptor failed, error code : %d\r\n"), GetLastError()); return ; } } if(NULL == m_hBoundary) { DUMPINFO(_T("m_hBoundarg is NULL\r\n")); return ; } // Create SID corresponding to the local Adminstrator group BYTE bySID[SECURITY_MAX_SID_SIZE] = {0}; PSID pSID = bySID; DWORD dwSize = sizeof(bySID); if(!CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, pSID, &dwSize)) { DUMPINFO(_T("CreateWellKnownSid failed, error code : %d\r\n"), GetLastError()); return ; } // Associate the local admin SID to the boundary descriptor if(!AddSIDToBoundaryDescriptor(&m_hBoundary, pSID)) { DUMPINFO(_T("AddSIDToBoundaryDescriptor failed, error code : %d\r\n"), GetLastError()); return ; } // Create the namespace for local administrator only SECURITY_ATTRIBUTES sa = {0}; sa.nLength = sizeof(sa); sa.bInheritHandle = FALSE; if(!ConvertStringSecurityDescriptorToSecurityDescriptor(_T("D:(A;;GA;;;BA)"), SDDL_REVISION_1, &sa.lpSecurityDescriptor, NULL)) { DUMPINFO(_T("ConvertStringSecurityDescriptorToSecurityDescriptor failed, error code : %d\r\n"), GetLastError()); return ; } if(lpszNamespace && _tcslen(lpszNamespace)) { m_hNamespace = CreatePrivateNamespace(&sa, m_hBoundary, lpszNamespace); DWORD dwRet = GetLastError(); LocalFree(sa.lpSecurityDescriptor); if(NULL == m_hNamespace) { if(ERROR_ALREADY_EXISTS != dwRet) { DUMPINFO(_T("CreatePrivateNamespace failed, error code : %d\r\n"), dwRet); return ; } else { m_hNamespace = OpenPrivateNamespace(m_hBoundary, lpszNamespace); if(NULL == m_hNamespace) { DUMPINFO(_T("OpenPrivateNamespace failed, error code : %d\r\n"), dwRet); return ; } m_bNamespaceOpen = TRUE; } } } if(NULL == lpszNamespace) { DUMPINFO(_T("lpszNamespace is NULL\r\n")); return ; } } CSingleton::~CSingleton(void) { if(NULL != m_hSingleton) { CloseHandle(m_hSingleton); m_hSingleton = NULL; } if(NULL != m_hNamespace) { ClosePrivateNamespace(m_hNamespace, m_bNamespaceOpen ? 0 : PRIVATE_NAMESPACE_FLAG_DESTROY); m_hNamespace = NULL; } if(NULL != m_hBoundary) { DeleteBoundaryDescriptor(m_hBoundary); m_hBoundary = NULL; } } void CSingleton::DUMPINFO(LPCTSTR lpszFormat, ...) { TCHAR szText[MAX_BUFFER_LENGTH] = {0}; va_list argList; va_start(argList, lpszFormat); _vstprintf_s(szText, _countof(szText), lpszFormat, argList); va_end(argList); OutputDebugString(szText); } BOOL CSingleton::IsInstanceExist(LPCTSTR lpszMutex) { if(m_hBoundary && m_hNamespace && lpszMutex && _tcslen(lpszMutex)) { m_hSingleton = CreateMutex(NULL, FALSE, lpszMutex); DWORD dwRet = GetLastError(); if(NULL == m_hSingleton) { DUMPINFO(_T("CreateMutex failed, error code : %d\r\n"), dwRet); return FALSE; } if(ERROR_ALREADY_EXISTS == dwRet) { DUMPINFO(_T("The another instance of App is running ...\r\n")); return TRUE; } else { DUMPINFO(_T("The first instance of App ...\r\n")); } } return FALSE; }
// 调用方法,主要修改App类的InitInstance函数 CSingleton* m_pSingleton = NULL; // 定义为App类的成员变量,并在App类的构造函数中初始化为NULL m_pSingleton = new CSingleton(_T("Chapter3Boundary"), _T("Chapter3Namesapce")); BOOL CXXXXXApp::InitInstance() { // Check Instance of App if((NULL != m_pSingleton) && (m_pSingleton->IsInstanceExist(_T("Chapter3Mutex")))) { return FALSE; } ... }