如何实现程序的重新启动(windows环境下)

背景:

在游戏程序的开发中,经常会碰到这样的情况,运行游戏更新程序后需要重新启动更新程序,在游戏内修改视频等相关设置后需要重新启动游戏程序,这样的操作该如何实现呢?

解决方案:

一种解决方案是通过等待来启动新的程序,但是这样的实现方式在极端情况下会出现问题,假设某游戏程序每次在一个物理机上只允许启动一个进程,如果关闭旧的进程因为一些原因而造成延迟,那么启动新的进程时会失败,试想游戏更新程序结束后,提示玩家游戏将重启,而游戏并没有重启,这种体验是相当糟糕的。

另一种解决方案,为了保证程序A关闭后与程序B再打开,在windows环境下有一种很常用的方法——批处理,由于批处理中的方法都是顺序执行的,关闭程序A打开程序B的操作可以保证同步执行,将杀死进程与启动进程的功能写入批处理,在需要重启的地方,调用API执行该批处理即可。

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /* 
  2. author: coffeecat 
  3. brief : All the code below has been tested. 
  4. date  : 2014/10/21 
  5. */  
  6. #include "stdafx.h"  
  7. #include <iostream>  
  8.   
  9. using namespace std;  
  10.   
  11. void Restart()    
  12. {    
  13.     FILE* pf;  
  14.     ::DeleteFile(L"restart.cmd");                           //确保删除上次遗留下的批处理文件  
  15.     errno_t err = ::_wfopen_s(&pf, L"restart.cmd", L"w");   //“w”表示打开一个空文件以进行写入。如果该文件存在,其内容将被销毁。  
  16.     if( err == 0 )                                          //restart.cmd不存在时,err == 0  
  17.     {    
  18.         char szExeName[1024];    
  19.         GetModuleFileNameA( NULL, szExeName, 1024);         //获取进程的名称  
  20.         fprintf( pf, "@echo off\n:a\n taskkill /f /im restart.exe \n start \"\" \"%s\" \ndel %%0", szExeName);    
  21.                 //restart.exe为需要重启的进程名称  
  22.         //taskkill /f(指定要强行终止的进程) /im( image name 可以理解为指定要终止的进程名名称)  
  23.         //%%0在批处理中表示%0,del %%0(删除批处理自身)  
  24.         fclose( pf );    
  25.     }    
  26.     else    
  27.     {    
  28.         cout << "can not open restart.cmd" << endl;    
  29.     }    
  30.   
  31.     STARTUPINFO si;    
  32.     PROCESS_INFORMATION pi;    
  33.     ZeroMemory( &si, sizeof si );    
  34.     ZeroMemory( &pi, sizeof pi );    
  35.     si.cb = sizeof si;    
  36.     si.dwFlags = STARTF_USESHOWWINDOW;    
  37.     si.wShowWindow = SW_HIDE;    
  38.     TCHAR winSysDir[1024];    
  39.     ZeroMemory( winSysDir, sizeof winSysDir );    
  40.     ::GetSystemDirectory( winSysDir, 1024 );    
  41.     std::wstring appName = winSysDir;    
  42.     appName += L"\\cmd.exe";    
  43.     BOOL bRet = CreateProcess(    
  44.         appName.c_str(),    
  45.         L"/c restart.cmd",                  //执行字符串指定的命令然后终断  
  46.         NULL,    
  47.         NULL,    
  48.         FALSE,    
  49.         0,    
  50.         NULL,    
  51.         NULL,    
  52.         &si,    
  53.         &pi);    
  54.   
  55.     if ( bRet == FALSE )    
  56.     {    
  57.         int err = GetLastError();    
  58.         cout << "can not restart test, error code:" << err << endl;    
  59.     }    
  60. }   
  61.   
  62. int main()  
  63. {  
  64.     int input, curPid;  
  65.     curPid = GetCurrentProcessId();  
  66.     cout << "Current process Id:" << curPid << endl;  
  67.     cout << "Do you need to restart the program ? (input 1 for restart, else do not restart)" << endl;  
  68.     cin >> input;  
  69.     if (input == 1)  
  70.     {  
  71.         Restart();  
  72.     }  
  73.     system("pause");  
  74.     return 0;  
  75. }  

执行上述代码,输入1会关闭当前进程,重新打开一个新的进程。

运行结果:

以下为进程A,待输入1后会被关闭。

以下为进程B,进程A被关闭后,进程B将会被创建。

可以看到两个进程的PID不同,符合预期。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值