如何实现程序的重新启动(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不同,符合预期。
在游戏程序的开发中,经常会碰到这样的情况,运行游戏更新程序后需要重新启动更新程序,在游戏内修改视频等相关设置后需要重新启动游戏程序,这样的操作该如何实现呢?
解决方案:
一种解决方案是通过等待来启动新的程序,但是这样的实现方式在极端情况下会出现问题,假设某游戏程序每次在一个物理机上只允许启动一个进程,如果关闭旧的进程因为一些原因而造成延迟,那么启动新的进程时会失败,试想游戏更新程序结束后,提示玩家游戏将重启,而游戏并没有重启,这种体验是相当糟糕的。
另一种解决方案,为了保证程序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不同,符合预期。
相关文章推荐
- 如何实现程序的重新启动(windows环境下)
- 发现Windows程序 最主要的还是要理解消息和窗口的相互调用,相互影响是如何实现的,才能更准确的去理解Windows程序,去编好自己想要的程序功能
- 在Windows远程桌面的不同会话之间,如何实现程序的互斥?
- windows程序如何实现精准定时
- Windows 2000下如何在自己的程序中实现关机!
- Windows 平台上的使用 Python 语言实现 appium 自动化程序环境配置
- Windows 2000下如何在自己的程序中实现关机!
- 问题的提出:如何在Windows上通过终端程序实现Unix平台的前台编译?
- 如何实现在Windows上运行Linux程序,附示例代码
- 如何用程序实现“rescan windows device manager"
- python os.startfile python实现双击运行程序 python监控windows程序 监控进程不在时重新启动
- 如何通过CuteFTP实现在windows环境下和Ubuntu进行文件相互传输
- 如何使用java程序实现windows锁屏
- 如何实现.net下开发的程序脱离.net环境运行并且可以跨平台的想法
- Windows 2000下如何在自己的程序中实现关机!
- Windows 2000下如何在自己的程序中实现关机!
- C++控制台程序,windows环境下响应按键消息实现一
- mac下如何改变当前环境目录(程序实现)
- 如何实现在Windows上运行Linux程序,附示例代码
- Python 实现根据不同的程序运行环境存放日志目录,Python实现Linux和windows系统日志的存放