功能描述:在无人看守的情况下,防止软件意外退出。
接口调用简单,只需要简单声明就行:
- int main(int argc, char **argv)
- {
- QShareProcess shareProcess("共享内存名称随意");
-
- // 下面实现自己的主体代码即可
- ......
- }
类声明:
- #if !defined(AFX_SHAREMEMORY_H_INCLUDED)
- #define AFX_SHAREMEMORY_H_INCLUDED
-
- class QShareProcess
- {
- public:
- QShareProcess(const char *name, size_t memsize = 32) ;
- virtual ~QShareProcess();
-
- private:
- int startShared();
-
- void *getMemPointer();
-
- void write(unsigned long dwData, long lOffset = 0);
- void write(char *pData, long lSize, long lOffset = 0);
-
- void read(char *pData, long lSize, long lOffset = 0);
-
- void close();
- bool isLive();
- bool isTerminated();
-
- protected:
- bool createFile(const char *name, size_t size);
-
- bool mapViewOfFile();
- bool setAllAccess(void* objHandle);
- void freeRes();
-
- void* m_hToMap;
- void *m_memory;
- };
-
- #endif // !defined(AFX_SHAREMEMORY_H_INCLUDED)
类定义:
- #include "ShareProcess.h"
-
- #include
- #pragma comment(lib,"Advapi32.lib")
- QShareProcess::QShareProcess(const char *name, size_t memsize)
- : m_hToMap(0),
- m_memory(0)
- {
- try {
- bool needToInit = createFile(name, memsize);
- mapViewOfFile();
- if (needToInit) {
- memset(m_memory, 0, memsize);
- }
- }
- catch (...) {
- freeRes();
- throw;
- }
-
- startShared();
- }
-
- QShareProcess::~QShareProcess()
- {
- freeRes();
- }
-
- #include
- #include
- #include
- int QShareProcess::startShared()
- {
- auto getCurrentModulePath = [] ()-> std::string
- {
- std::vector<char> buffer;
- DWORD size = MAX_PATH;
-
- while (true) {
- buffer.resize(size + 1);
- DWORD ret = GetModuleFileName(NULL, &buffer[0], size);
-
- if (ret == 0) {
- return false;
- }
- else if (ret == size || GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
- size += 128;
- }
- else {
- break;
- }
- } // while
-
- std::string out = &buffer[0];
- return out;
- }; // void
-
- bool slient = false;
- for (int i = 0; i < __argc; i++) {
- if (_stricmp(__argv[i], "/Slient") == 0) {
- slient = true;
- break;
- }
- } // for
-
- if (slient) {
- // 互斥 上线地址:端口:服务名
- char strMutex[100];
- wsprintfA(strMutex, "{4EB9E321-8C12-478F-BC53-9920E7BFE114}");
- HANDLE m_hMutex = CreateMutex(NULL, FALSE, strMutex);
- if (m_hMutex && GetLastError() == ERROR_ALREADY_EXISTS) {
- ReleaseMutex(m_hMutex);
- CloseHandle(m_hMutex);
- ExitProcess(0);
- return 0;
- }
-
- this->write((DWORD)GetCurrentProcessId(), 12);
- this->write((DWORD)GetTickCount(), 16);
-
- while (!this->isTerminated()) {
- if (!this->isLive()) {
- TCHAR szCommandline[_MAX_PATH] = { 0 };
- sprintf(szCommandline, "\"%s\"", getCurrentModulePath().c_str());
- for (int i = 1; i < __argc; i++) {
- if (_stricmp(__argv[i], "/Slient") != 0) {
- strcat_s(szCommandline, " ");
- strcat_s(szCommandline, __argv[i]);
- }
- }
- STARTUPINFO si;
- ZeroMemory(&si, sizeof(STARTUPINFO));
- si.cb = sizeof(STARTUPINFO);
- si.dwFlags = STARTF_USESHOWWINDOW;
- si.wShowWindow = TRUE;
-
- PROCESS_INFORMATION pi;
- CreateProcess(NULL, (LPTSTR)szCommandline,
- NULL, NULL, FALSE, 0/*CREATE_NEW_CONSOLE*/, NULL, NULL,
- &si, &pi);
- } // if
-
- this->write((DWORD)GetCurrentProcessId(), 12);
- this->write((DWORD)GetTickCount(), 16);
-
- std::this_thread::sleep_for(std::chrono::milliseconds(5000));
- }
-
- ExitProcess(0);
- return 1;
- } // if
-
- this->write((DWORD)0xABCD);
- this->write((DWORD)GetCurrentProcessId(), 4);
- this->write((DWORD)GetTickCount(), 8);
-
- TCHAR szCommandline[_MAX_PATH] = { 0 };
- sprintf(szCommandline, "\"%s\" ", getCurrentModulePath().c_str());
- for (int i = 1; i < __argc; i++) {
- if (_stricmp(__argv[i], "/Slient") != 0) {
- strcat_s(szCommandline, " ");
- strcat_s(szCommandline, __argv[i]);
- }
- }
- strcat_s(szCommandline, " /Slient");
- STARTUPINFO si;
- ZeroMemory(&si, sizeof(STARTUPINFO));
- si.cb = sizeof(STARTUPINFO);
- si.dwFlags = STARTF_USESHOWWINDOW;
- si.wShowWindow = TRUE;
-
- PROCESS_INFORMATION pi;
- if (CreateProcess(NULL, (LPTSTR)szCommandline,
- NULL, NULL, FALSE, 0/*CREATE_NEW_CONSOLE*/, NULL, NULL,
- &si, &pi) == 0) {
- return -1;
- }
-
- return 1;
- }
-
- void *QShareProcess::getMemPointer()
- {
- return m_memory;
- }
-
- bool QShareProcess::createFile(const char *name, size_t size)
- {
- DWORD lowSize = size & 0xffffffff;
- DWORD highSize = (DWORD64)size >> 32 & 0xffffffff;
-
- //创建共享文件句柄
- m_hToMap = CreateFileMapping(INVALID_HANDLE_VALUE, //物理文件句柄
- NULL,
- PAGE_READWRITE, // 可读可写
- highSize, // 地址偏移:高位
- lowSize, // 地址偏移:地位
- name); // 共享内存名称
- if (m_hToMap == NULL) {
- return false;
- }
-
- bool needToInit = GetLastError() != ERROR_ALREADY_EXISTS;
- if (needToInit) {
- setAllAccess(m_hToMap);
- }
-
- return needToInit;
- }
-
- #include
- bool QShareProcess::mapViewOfFile()
- {
- //映射缓存区视图,得到共享内存的指针
- m_memory = MapViewOfFile(m_hToMap, //已经创建的文件映射对象的句柄
- FILE_MAP_ALL_ACCESS, //可读可写
- 0, // 地址偏移:高位
- 0, // 地址偏移:地位
- 0); // 映射视图的大小
- if (m_memory == NULL) {
- return false;
- }
-
- printf("ShareMemory addr: 0x%08x\n", *(DWORD*)m_memory);
-
- return true;
- }
-
- bool QShareProcess::setAllAccess(void* objHandle)
- {
- DWORD errorCode = SetSecurityInfo(objHandle, SE_FILE_OBJECT,
- DACL_SECURITY_INFORMATION,
- NULL,
- NULL,
- NULL,
- NULL);
- if (errorCode != ERROR_SUCCESS) {
- return false;
- }
-
- return true;
- }
-
- void QShareProcess::freeRes()
- {
- if (m_memory) {
- UnmapViewOfFile(m_memory);
- m_memory = 0;
- }
-
- if (m_hToMap) {
- CloseHandle(m_hToMap);
- m_hToMap = 0;
- }
- }
-
- void QShareProcess::write(unsigned long dwData, long lOffset)
- {
- write((char*)&dwData, sizeof(unsigned long), lOffset);
- }
-
- void QShareProcess::write(char *pData, long lSize, long lOffset)
- {
- if (m_memory == NULL)
- return ;
-
- ::memcpy((char*)m_memory + lOffset, pData, lSize);
- }
-
- void QShareProcess::read(char *pData, long lSize, long lOffset)
- {
- if (m_memory == NULL)
- return ;
-
- ::memcpy(pData, (char*)m_memory + lOffset, lSize);
- }
-
- void QShareProcess::close()
- {
- write(0);
- }
-
- bool QShareProcess::isTerminated()
- {
- DWORD dwValue = 0;
- read((char*)&dwValue, 4);
- if (dwValue = 0xABCD)
- return false;
- else
- return true;
- }
-
- #include
- bool QShareProcess::isLive()
- {
- DWORD dwProcessID;
- read((char*)&dwProcessID, sizeof(DWORD), 4);
-
- bool bFind = false;
- HANDLE hSnapShot = INVALID_HANDLE_VALUE;
- PROCESSENTRY32 pe;
-
- //获取系统快照(hSnapShot)
- pe.dwSize = sizeof(PROCESSENTRY32);
- hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
-
- //查找进程
- Process32First(hSnapShot, &pe);
- do {
- if (pe.th32ProcessID == dwProcessID) {
- bFind = true;
- break;
- }
- } while (Process32Next(hSnapShot, &pe));
-
- CloseHandle(hSnapShot);
- return bFind;
- }