您的位置:首页 > 其它

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

2014-11-06 18:01 405 查看
背景:

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

解决方案:

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

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

[cpp] view
plaincopy





/*

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不同,符合预期。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐