科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件VC实现应用程序在线升级

VC实现应用程序在线升级

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

介绍如何用VC设计在线升级程序,并提供了源代码。

作者:佚名 来源:论坛 2007年10月21日

关键字: VC 应用程序 在线升级

  • 评论
  • 分享微博
  • 分享邮件
开发背景

  近几日一些程序老要修改点小毛病,为避免每次都通知程序使用者,便有想做一个在线自动升级的程序。在网上曾看到一个是使用 FTP 的,想到 FTP 需要用户名密码,许多程序如KFW 防火墙都能监看到程序发送的数据包,为防止密码泄露,故自己选用Http来做更新。我的思路是用命令行传递程序名称、版本号和 Update.ini 配置文件的 URL。命令行用法如下:

  update.exe 程序名 版本 版本文件URL



  例如:

update.exe VolleyMail 3.0 http://www.extice.com/update/update.ini

   解析命令行参数的函数原型如下: CUpdateApp::GetCmdLinePara(CStringArray Arr);

  该函数是将命令行参数分解并保存到 paraArr 数据中。然后将命令行信息传递给主对话框类,代码如下:

dlg.m_strSoft = arr.GetAt(0);
dlg.m_strVersion = arr.GetAt(1);
AfxParseURL( arr.GetAt(2),
dwType,
dlg.m_strServer,
dlg.m_strIniPath,
dlg.m_dwPort);

  这是对话框的初始化,将软件版本号显示在 List 框中,如图一:

m_cis.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT,5);
m_pHttp=m_cis.GetHttpConnection( m_strServer,m_dwPort );
m_lbProduct.AddString(m_strSoft+" "+m_strVersion);


图一

  然后是查找可用的更新,先通过 ChttpFile 将 Update.INI 文件下载到系统临时目录下,然后调用 GetPrivateProfileString 读取网上最新的版本号以及要更新的文件,判断是否需要更新,部分代码:

csf.Open( m_strTempDir+"\\update.ini",
CFile::modeCreate|CFile::modeWrite|CFile::typeBinary );

char buf[2048];
int n;
while( ( n=pFile->Read( buf,2048 ) ) > 0 )
csf.Write(buf,n);


char buf[128];
::GetPrivateProfileString( m_strSoft,
"VERSION",
"1.0",
buf,
sizeof(buf),
m_strTempDir+"\\update.ini");
m_strNewVer=buf;
if(atof( m_strVersion ) >= atof( buf ) ) //现有版本大于
{
m_strStatus = "您现在用的版本已是最新的!";
UpdateData(FALSE);
m_buOK.EnableWindow(FALSE);
return;
}

  更新部分代码

  先通过 CUpdateDlg::FindAppProcessID() 看要更新的程序是否在运行:

DWORD CUpdateDlg::FindAppProcessID()
{
HANDLE handle=::CreateToolhelp32Snapshot(TH32CS_SNAPALL,0);
PROCESSENTRY32 Info;
Info.dwSize = sizeof(PROCESSENTRY32);
if(::Process32First(handle,&Info))
{
do{
CString ss=Info.szExeFile;
if(!ss.CompareNoCase(m_strSoft+".exe"))
{
::CloseHandle(handle);
return Info.th32ProcessID;
}
}
while(::Process32Next(handle,&Info));
::CloseHandle(handle);
}
return -1;
}

  该函数返回程序进程号,如果要更新的程序正在运行的话,提示人工退出否则用TerminateProcess 杀掉进程!

  下载的文件大小用: pFile->QueryInfo(HTTP_QUERY_CONTENT_LENGTH,str);取得。

  为防止下载一半网络出现故障,先将下载的文件加后缀名.upg,下载全部成功后替换掉原来在用的程序,完成更新。

  关键代码部分如下: ...

CStdioFile csf;
if( !csf.Open( str+".upg",
CFile::modeCreate
| CFile::modeWrite
| CFile::typeBinary
| CFile::shareDenyWrite ) )
{//先为*.upg文件
AfxMessageBox("写文件"+str +"错误!\n文件正在使用中,请先关闭程序!",
MB_ICONSTOP);
pFile->Close();
return FALSE;
}

char buf[2048];
DWORD dwRead=0;
while((n=pFile->Read(buf,sizeof(buf)))>0)
{
dwRead+=n;
m_prog.SetPos(100*dwRead/dwLen);
MSG msg;
for(int i=0;i<10;i++)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
csf.Write(buf,n);
}
pFile->Close();
...

if(::DeleteFile(str)){
::rename(str+".upg",str);
m_strStatus=strFile+"完成更新!";
UpdateData(FALSE);
...

  有关其它细节请参考源代码。

  下载本文源代码

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章