使用 Http 在线自动升级程序

 开发背景
近几日一些程序老要修改点小毛病,为避免每次都通知程序使用者,便有想做一个在线自动升级的程序。在VCKBase看到一个是使用 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);
       ...  

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

时间: 2024-08-02 03:09:40

使用 Http 在线自动升级程序的相关文章

使用Http在线自动升级程序

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

[IT]C/S自动升级程序原理

背景 我们给几个景区做了一个C/S项目,但是由于需求的变化,或者是Bug的出现,我们不得不修改程序程序.众所周知,C/S结构的应用程序可维护性比较差,它不同于B/S结构的程序,可以随着服务器端的更新,立即显现出来.因此我们不得不经常跑去景区手动更换程序.这样非常的麻烦,因此我们就做了一个自动升级的程序,由景区自己下载更新. 运行形式 (1)是作为一种服务,用户开机后自动隐藏运行.这种方式技术成本高,要求高可靠性和可用性.偶尔也会引起用户的反感.因windows操作系统升级就是这样进行的; (2)

C#客户端软件自动升级程序

程序界面: 本程序说明 * 自动更新通用程序.最好放在需要用到自动更新的程序的同级目录下 * 自动更新采用文件接口.在本程序的同级目录下必须要有autoupdate.config文件 * 文件格式为: * url=获取升级到配置文件 * cmd=升级完成后执行的命令 url=url1$url2$url3$url4 cmd=cmd.exe * 自动升级程序会按顺序检查url,如果第一个无效就选第二个,依次类推. * 升级完成以后执行cmd处写的命令. 如果检查到URL有效那么就会获取URL的返回的

一个应用程序通过ShellExecute启动一个自动升级程序,在不关闭自动升级程序的窗体时,始终显示在最前面不隐藏到后面,有办法做到吗

问题描述 应用场景:有一个主程序App1,有时候要自动升级,自动升级是另外一个程序App2,当App1监测到自动升级信息后通过ShellExecute启动自动升级程序App2,有办法让用户不关闭App2的窗体,它能始终显示在最前面不隐藏到后面吗?我通过Process类得到了自动升级程序的Process信息,里面有handle,mainwindowshandle等一些属性和方法,对这个类也不是太熟,还是不通过Process用其他方法做到? 解决方案 解决方案二:[DllImport("User32

WordPress程序手动和自动升级的图文教程

第一.升级准备工作   我们在升级WordPres之前我们一定要备份数据库和网站文件,即便我们很有把握也都要备份,因为很多时候万一出现导致不可预见的错误,那就比较麻烦.备份网站我们可以参考"Linux VPS网站文件.数据库备份"文章,当然我们也可以根据自己的习惯进行不同方式的备份,确保数据的安全.   同时,我们也可以将所有的插件都停止运行,因为有些特殊的插件可能在升级版本后不兼容.如果是常规的也不需要停止,我们需要在升级完毕之后再开启.   第二.自动升级程序     如果有新版本

ESFramework介绍之(22)―― 服务器系统自动升级

    (本文名字取为"服务器系统自动升级",实际上适用于所有应用程序自动升级的情况.)    前文介绍了在服务器或客户端应用程序运行的过程中,插件如何自动升级.更新.基于前文相同的理由,AS.FS.IRAS也需要有自动升级的功能.     与插件在运行时动态更新不同,服务器系统无法在运行时动态更新,只有在服务器系统重新启动的时候,才是自动升级的切入点.(1)对于功能服务器FS,可以采用持续/逐个更新的方式,即依次重启每个功能服务器.这样可以避免功能服务被中断的情况发生.需要注意的是,

ASP在线升级程序

ASP在线升级程序 <% '文件名:updata.asp '远程地址 const url="http://localhost/test/" action=request("action") if action="updata" then  download(url&"config.txt")  download(url&"pack.jpg")  response.Write("

实例-winform程序已经开启。如果通过从另一台电脑获取新版本,让winform程序自动升级安装?

问题描述 winform程序已经开启.如果通过从另一台电脑获取新版本,让winform程序自动升级安装? winform程序如何实现自动安装升级?不需要人工去控制升级.就是一台pc机已经在运行winform程序了,怎么通过从另一台机子获取新版本,然后先关闭原来的winform程序后再实现安装新版本.自动升级不需要人工再去操作.在网上看了好多实例,发现都不怎么好用,关键有些技术也没看懂.哪位大神会的话,请教下新人.谢谢.没有分给大家,真是不好意思啊.都用完了! 解决方案 自动升级和人工升级没有区别

ASP 程序实现自动升级功能_小偷/采集

现在流行虚拟主机建站,我也有个网站,也算是个站长咯.当了近一年的站长,感到网站程序每次升级的时候颇为麻烦:先去官方看公告,然后下载升级包到本地,解压,FTP上传到虚拟主机.这些都是累人的体力活,加之本人又懒得很,所以异想天开的觉得要是程序能够自动升级就好了.所以就想了想,写了本文,希望对WEB程序开发者有帮助.这里只针对ASP,因为我只会ASP :-( 先看看传统的win32程序的升级过程(比如杀毒软件),它是依靠软件的升级程序通过网络连接到服务器分析并下载升级文件到本地. WEB程序有点不一样