今天又碰到需要做一个简单的自动升级的客户端程序,
客户端程序在拿到升级包并且解压之后,怎样自更新并再启动呢?
这里我封装了一个类,利用批处理,将升级文件覆盖掉本地文件,然后重启动应用程序。
#ifndef KILL_MYSELF_H_
#define KILL_MYSELF_H_
#include <iostream>
#include <vector>
class UpdateMyself
{
public:
UpdateMyself()
{
m_Files.clear();
}
//设置更新目录
void SetDir( std::string dir )
{
m_UpdateDir = dir;
}
//增加更新文件
void AddFile( std::string filename )
{
m_Files.push_back( filename );
}
//设置启动应用名
void SetStartApp( std::string appname )
{
m_StartApp = appname;
}
//执行
void Execute()
{
//建立更新批处理文件
FILE *fp;
fp = fopen( "update.bat" , "w+" );
fprintf( fp , "@echo off\n" );
//覆盖本地文件
for( std::vector<std::string>::iterator iter = m_Files.begin(); iter != m_Files.end(); ++iter )
{
std::string filename = *iter;
fprintf( fp , "del %s\n", filename.c_str() );
fprintf( fp , "copy .\\%s\\%s %s\n", m_UpdateDir.c_str(), filename.c_str(), filename.c_str() );
fprintf( fp , "del .\\%s\\%s\n", m_UpdateDir.c_str(), filename.c_str() );
}
//自杀
fprintf( fp , ":begin\n" );
fprintf( fp , "del %s\n", m_StartApp.c_str() );
fprintf( fp , "if exist %s goto begin\n", m_StartApp.c_str() );
fprintf( fp , "copy .\\%s\\%s %s\n", m_UpdateDir.c_str(), m_StartApp.c_str(), m_StartApp.c_str() );
//fprintf( fp , "rd/q %s\n", m_UpdateDir.c_str() );
fprintf( fp , "del .\\%s\\%s\n", m_UpdateDir.c_str(), m_StartApp.c_str() );
fprintf( fp , "start %s\n", m_StartApp.c_str() );
fprintf( fp , "del %%0%%\n");
fclose(fp);
WinExec("update.bat",SW_SHOW);
exit(0);
}
private:
std::vector<std::string> m_Files;
std::string m_UpdateDir;
std::string m_StartApp;
};
#endif
假设我们下载之后的更新文件都位于update目录中,我只需要
UpdateMyself test;
test.SetDir("update");
test.AddFile(...); 把要更新的文件名加进去
test.SetStartApp(...); 设置更新之后启动的应用程序名称
test.Execute();
就可以完成更新了。