我要做一个应用程序的升级程序,这样当有新的版本时,用户只要网上升级一下就了可以了,用户使用也方便,我管理也方便。但不知道该怎么做。大家说说,该如何写升级?

解决方案 »

  1.   

    把你的主要功能模块写到DLL中,这样用户只要更新DLL就可以了
      

  2.   

    VC中实现在线版本检测http://www.xiaozhou.net/ReadNews.asp?NewsID=242
      

  3.   

    主要功能模块写到DLL中,这样用户只要下载更新DLL就可以
      

  4.   

    技术:进程通信+网络通信
    1)启动更新程序(就是一个独立的EXE文件吗)
    2)下载最新版本到临时文件
    3)关闭当前版本程序
    4)复盖旧版本,册除临时文件
    ....
      

  5.   

    选用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);
           ...