Software version update check implementation

xiaoxiao2021-03-06  115

Software automatic update check

[Mental Studio] Raptor [blog]

Still in "PIA-MyPhotogallery", in order to make the user know the update version of the software in time, I increased the automatic update check. In view of this function, it has a good practical value, so the implementation of this feature is written.

To implement an update check, you need to solve two aspects of questions:

1. Get the latest version number by Internet;

2. Take the version of the current program and compare it with the latest version.

If checking to a new version is released, open the download page (as for direct download updates, this article is not discussed).

For the first question, the easiest solution is to post a new version software on the website, publish a file that records the version number. When the software is checked (for example, when the program is started), this file is downloaded via the Internet and read the latest version number.

Note: This method is only available for simple update, and this simple method is inappropriate for the incremental update of the virus library like anti-virus software, which is usually necessary to have the corresponding server-side program cooperation.

There are many ways to download files over the Internet, such as using Wininet API or ready-made controls. This article uses indeed TIDHTTP control as an example.

The usage of the TIDHTTP control is very simple, but there is a problem with it directly using it: the program will be blocked until the file is downloaded or connected times (such as the network is not connected). So you must put it in the thread.

In PIA-MyPhotogallery, the code I use is as follows:

/ / -------------------------------------------------------------------------------------------- ---------------------------

// Get New Version Thread

Class TgetnewVersionthread: Public TTHREAD

{

Private:

Ansistring furl;

TMFileVersion * Fver;

protected:

Void __fastcall execute ();

PUBLIC:

__fastcall tgetnewversethread (ANSISTRING AURL)

: Tthread (TRUE), FURL (AURL), FVER (New TMFileVersion ())

{

FreeOnterminate = true;

}

__fastcall ~ tgetnewversionthread () {delete fver;}

__property tmfileversion * version = {read = fver};

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

// TgetNewVersionThread

/ / -------------------------------------------------------------------------------------------- ---------------------------

Void __fastcall tgetnewversethread :: 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;

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

This code is simple: create a thread, create a TIDHTTP instance in the thread, then download the file corresponding to the URL, and read the "PIAPG" version number. In order to lazy, I used the Smart Pointer - Scoped_ptr in the Boost Caller.

The method of using this thread class is as follows:

/ / -------------------------------------------------------------------------------------------- ---------------------------

// Perform: when the program starts:

If (PIAPGCFG-> AutouPD) // If you select the Check Update option, check

{

If (splashdlg) // If there is SPLASH, it is displayed in it.

{

Splashdlg-> labprogress-> caption = "Checking new version ...";

Splashdlg-> labprogress-> refresh ();

}

// Create a new version of the thread

TgetNewVersionThread * pthread = New TgetneWVersionThread ("http://ental.mentsu.com/Update.txt");

Pthread-> onterminate = getnewversiondone;

Pthread-> resume ();

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

// version file download complete or timeout

Void __fastcall tMainform :: getNewVersionDone (TOBJECT * SENDER)

{

TgetNewVersionthRead * pthread = Dynamic_cast

Sender;

Boost :: scoped_ptr

FV (New TMFileVersion ());

fv-> getversionFromFile (Application-> Exename); // read the version of the current program

IF ((pthread-> version-> compare (fv.get ())> 0) // If there is a new version, then prompt

&& (Application-> Messagebox ("Discover the updated version of the program, is it updated now?",

"New version check", MB_YESNO | MB_ICONINFORMATION) == iDyes))

{

Shellexecute (NULL, "Open", "http://ental.mentsu.com", null, null, sw_show;

PostquitMessage (0);

}

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

The function of this code is detailed in the comments.

Take later the second question: Problem of the program version.

In the code above, use a class: TMFileVersion. This is a class I used to write to the executable file version number before I used Delphi. The implementation code is as follows: TMFileVersion = Class

Private

Fmajor: integer;

FMINOR: Integer;

Frelease: Integer;

FBUILD: Integer;

Function Getverstr: String;

Procedure setVerstr (averstr: string);

public

Constructor crete;

DESTRUCTOR DESTROY; OVERRIDE;

Procedure getversionFromFile (AfileName: String);

Function Compare (AVER: TMFileVersion): Integer;

Property Verstr: String Read Getverstr Write setVerstr;

END;

{TMFileVersion}

// init

Constructor TMFileVersion.create;

Begin

Inherited;

FMAJOR: = 0;

FMINOR: = 0;

FRELEASE: = 0;

FBUILD: = 0;

END;

Destructor TMFileVersion.destroy;

Begin

Inherited;

END;

// Get Version Info from a file

Procedure TMFileVersion.getVersionFromFile (AfileName: String);

Type

PVS_FIXEDFILEINFO = ^ vs_fixedfileinfo;

VAR

H: cardinal; // a Handle, Ignore

nsize: cardinal; // version info size

PDATA: POINTER; // Version Info Data

PFFIDATA: PVS_FIXEDFILEINFO; / / FIXED File Info Data

NFFISIZE: cardinal; // fixed file info size

Begin

FMAJOR: = 0;

FMINOR: = 0;

FRELEASE: = 0;

FBUILD: = 0;

IF (FileExists (AfileName).

FBUILD: = 1;

nsize: = getfileversionInfosize (Pchar (AfileName), H);

IF (nsize = 0) THEN

EXIT;

GetMem (PDATA, NSIZE);

Try

GetFileVersionInfo (Pchar (AfileName), H, NSIZE, PDATA);

IF (PDATA, '/', Pointer (PfFFIDATA), NFFISIZE)) THEN

Begin

Fmajor: = (pfFFIDATA ^ .dwfileversionms) SHR 16;

Fminor: = (pfFFIDATA ^ .dwfileversionms) and $ fff;

Frelease: = (pffidata ^ .dwfileversionls) SHR 16;

FBUILD: = (pffidata ^ .dwfileversionls) and $ fff;

Finally

FreeMem (PDATA);

END;

END;

// Compare Two Version Info

Function TMFileVersion.comPare (AVER: TMFileVersion): Integer;

VAR

N1, N2: cardinal

Begin

N1: = (Fmajor SHL 16) OR FMINOR;

With aver do

N2: = (Fmajor SHL 16) OR FMINOR;

IF (n1> n2) THEN

Result: = 1

ELSE IF (N1

Result: = -1

Else

Begin

N1: = (FRELEASE SHL 16) or FBuild;

With aver do

N2: = (Frelease SHL 16) or FBuild;

IF (n1> n2) THEN

Result: = 1

ELSE IF (N1

Result: = -1

Else

Result: = 0;

END;

END;

// Get / set Property - Verstr

Function TMFileVersion.getVerstr: String;

Begin

Result: = format ('% D,%. 02d,% D,%. 02d', [FMAJOR, FMINOR, FRELEASE, FBUILD]);

END;

Procedure TMFileVersion.setverstr (Averstr: String);

VAR

Stemp: tstrings;

Begin

FMAJOR: = 0;

FMINOR: = 0;

FRELEASE: = 0;

FBUILD: = 0;

STEMP: = TSTRINGLIST.CREATE;

Try

STEMP.COMMATEXT: = averstr;

Try

Fmajor: = start (STEMP.STRINGS [0]);

Fminor: = start (STEMP.STRINGS [1]);

FRELEASE: = STRTOINT (STEMP.STRINGS [2]);

FBUILD: = STRTOINT (STEMP.STRINGS [3]);

Except

// do nothing

END;

Finally

STEMP.FREE;

END;

END;

Solved these two questions, the function of automatic update check is solved.

BTW: For convenience, you have changed with Delphi to rewrite and package it into a VCL control.

[Mental Studio] Raptor OCT.30-04

转载请注明原文地址:https://www.9cbs.com/read-98237.html

New Post(0)