背景:
在游戏程序的开发中,经常会碰到这样的情况,运行游戏更新程序后需要重新启动更新程序,在游戏内修改视频等相关设置后需要重新启动游戏程序,这样的操作该如何实现呢?
解决方案:
一种解决方案是通过等待来启动新的程序,但是这样的实现方式在极端情况下会出现问题,假设某游戏程序每次在一个物理机上只允许启动一个进程,如果关闭旧的进程因为一些原因而造成延迟,那么启动新的进程时会失败,试想游戏更新程序结束后,提示玩家游戏将重启,而游戏并没有重启,这种体验是相当糟糕的。
另一种解决方案,为了保证程序A关闭后与程序B再打开,在windows环境下有一种很常用的方法——批处理,由于批处理中的方法都是顺序执行的,关闭程序A打开程序B的操作可以保证同步执行,将杀死进程与启动进程的功能写入批处理,在需要重启的地方,调用API执行该批处理即可。
/* author: coffeecat brief : All the code below has been tested. date : 2014/10/21 */ #include "stdafx.h" #include <iostream> using namespace std; void Restart() { FILE* pf; ::DeleteFile(L"restart.cmd"); //确保删除上次遗留下的批处理文件 errno_t err = ::_wfopen_s(&pf, L"restart.cmd", L"w"); //“w”表示打开一个空文件以进行写入。如果该文件存在,其内容将被销毁。 if( err == 0 ) //restart.cmd不存在时,err == 0 { char szExeName[1024]; GetModuleFileNameA( NULL, szExeName, 1024); //获取进程的名称 fprintf( pf, "@echo off\n:a\n taskkill /f /im restart.exe \n start \"\" \"%s\" \ndel %%0", szExeName); //restart.exe为需要重启的进程名称 //taskkill /f(指定要强行终止的进程) /im( image name 可以理解为指定要终止的进程名名称) //%%0在批处理中表示%0,del %%0(删除批处理自身) fclose( pf ); } else { cout << "can not open restart.cmd" << endl; } STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof si ); ZeroMemory( &pi, sizeof pi ); si.cb = sizeof si; si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; TCHAR winSysDir[1024]; ZeroMemory( winSysDir, sizeof winSysDir ); ::GetSystemDirectory( winSysDir, 1024 ); std::wstring appName = winSysDir; appName += L"\\cmd.exe"; BOOL bRet = CreateProcess( appName.c_str(), L"/c restart.cmd", //执行字符串指定的命令然后终断 NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi); if ( bRet == FALSE ) { int err = GetLastError(); cout << "can not restart test, error code:" << err << endl; } } int main() { int input, curPid; curPid = GetCurrentProcessId(); cout << "Current process Id:" << curPid << endl; cout << "Do you need to restart the program ? (input 1 for restart, else do not restart)" << endl; cin >> input; if (input == 1) { Restart(); } system("pause"); return 0; }
执行上述代码,输入1会关闭当前进程,重新打开一个新的进程。
运行结果:
以下为进程A,待输入1后会被关闭。
以下为进程B,进程A被关闭后,进程B将会被创建。
可以看到两个进程的PID不同,符合预期。