如何實現程式的重新啟動(windows環境下)
阿新 • • 發佈:2019-02-09
背景:
在遊戲程式的開發中,經常會碰到這樣的情況,運行遊戲更新程式後需要重新啟動更新程式,在遊戲內修改視訊等相關設定後需要重新啟動遊戲程式,這樣的操作該如何實現呢?
解決方案:
一種解決方案是通過等待來啟動新的程式,但是這樣的實現方式在極端情況下會出現問題,假設某遊戲程式每次在一個物理機上只允許啟動一個程序,如果關閉舊的程序因為一些原因而造成延遲,那麼啟動新的程序時會失敗,試想遊戲更新程式結束後,提示玩家遊戲將重啟,而遊戲並沒有重啟,這種體驗是相當糟糕的。
另一種解決方案,為了保證程式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不同,符合預期。