软件的版本更新检查实现[1]

[入库:2005年8月19日] [更新:2007年3月24日]

本文简介:选择自 raptor 的 blog

    还是在“pia-myphotogallery”中,为了能让使用者及时知道软件的更新版本发布,我增加了自动更新检查功能。鉴于这种功能具有很好的实用价值,所以写本文说明此功能的实现。

要实现更新检查,需要解决两个方面的问题:

1、通过internet获取最新发布的版本号;
2、取得当前程序的版本,并与取得的最新版本相比较。

如果检查到有新版本发布,则打开下载页面(至于直接下载更新本文暂不讨论)。

对于第一个问题,最简单的解决办法就是在网站上发布新版本软件的同时,发布一个记录着版本号的文件。在软件进行版本检查时(比如程序启动时),通过internet下载此文件,并读出最新的版本号。

注意:此方法仅适用于简单更新的情况,对于像杀毒软件的病毒库这样增量更新的情况,这种简单方法是不合适的,通常还需要有相应的服务端程序配合才行。

要通过internet下载文件有很多方法,比如用wininet api或现成的控件都可以。本文以indy的tidhttp控件为例。

tidhttp控件的用法非常简单,但是直接使用它下载会有一个问题:程序会被阻塞着,直到文件被下载或连接超时(比如网络未连接)。所以必须将它放到线程中处理。

在pia-myphotogallery中,我用的代码如下:

//---------------------------------------------------------------------------
//  get new version thread
class tgetnewversionthread : public tthread
{
private:
    ansistring      furl;
    tmfileversion * fver;
protected:
    void __fastcall execute( );
public:
    __fastcall tgetnewversionthread( ansistring aurl )
        : tthread( true ), furl( aurl ), fver( new tmfileversion( ) )
    {
        freeonterminate = true;
    }
    __fastcall ~tgetnewversionthread( ) { delete fver; }
    __property tmfileversion * version  = { read=fver };
};
//---------------------------------------------------------------------------
//  tgetnewversionthread
//---------------------------------------------------------------------------
void __fastcall tgetnewversionthread::execute( )
{
    boost::scoped_ptr webconn( new tidhttp( null ) );
    boost::scoped_ptr ss( new tstringlist( ) );
    try {
        ss->text = webconn->get( furl );
    }
    catch ( ... )
    {
        ss->text = "";
    }
    ansistring s = ss->values["piapg"];
    if ( s != "" )
        fver->verstr = s;
}
//---------------------------------------------------------------------------

这段代码很简单:创建一个线程,在线程里创建一个tidhttp实例,然后下载url对应的文件,最后从中读出“piapg”的版本号。为了偷懒,我用了boost库里的smart pointer--scoped_ptr。

这个线程类的使用方法如下:

//---------------------------------------------------------------------------
//  在程序启动时执行:
    if ( piapgcfg->autoupd )  //  如果选择了“检查更新”选项则执行检查
    {
        if ( splashdlg )  //  如果有splash,则在其中显示提示文本
        {
            splashdlg->labprogress->caption = "正在检查新版本...";
            splashdlg->labprogress->refresh( );
        }
        //  创建检查新版本的线程
        tgetnewversionthread * pthread = new tgetnewversionthread( "http://mental.mentsu.com/update.txt" );
        pthread->onterminate = getnewversiondone;
        pthread->resume( );
    }
//---------------------------------------------------------------------------
//  版本文件下载完成或超时
void __fastcall tmainform::getnewversiondone(tobject * sender)
{
    tgetnewversionthread * pthread = dynamic_cast( sender );
    boost::scoped_ptr fv( new tmfileversion( ) );
    fv->getversionfromfile( application->exename );  //  读取当前程序的版本
    if ( ( pthread->version->compare( fv.get( ) ) > 0 )  //  如果有新版本,则提示
        && ( application->messagebox( "发现更新版本的程序,是否现在更新?",
        "新版本检查", mb_yesno | mb_iconinformation ) == idyes ) )
    {
        shellexecute( null, "open", "http://mental.mentsu.com", null, null, sw_show );
        postquitmessage( 0 );
    }
}
//---------------------------------------------------------------------------

此代码的功能详见其中的注释。

再来看第二个问题:程序版本的问题。

在上面的代码中,用到了一个类:tmfileversion。这是我以前用delphi写的一个用于处理可执行文件版本号的类。实现代码如下:

本文关键:软件的版本更新检查实现
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top