今天又碰到需要做一个简单的自动升级的客户端程序,
客户端程序在拿到升级包并且解压之后,怎样自更新并再启动呢?
这里我封装了一个类,利用批处理,将升级文件覆盖掉本地文件,然后重启动应用程序。
#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();
就可以完成更新了。