We wrote an application.ProgramAfter the application is released, how can I deploy the upgraded version to the customer's machine after the application has a new version?
My current practice is:
If the upgraded version is an unimportant version, for example, to add new features only for specific customers, you can notify these customers to perform the upgrade as follows:
As shown in, the current version of the program is 1.225, and the updated version of the program is 1.226. In this case, you can click "Update" in the "about" dialog box of the program to upgrade the application.
After the upgrade, a dialog box is displayed. Click "OK" to exit the program, restart the application, and check that the version has been updated to version 1.226:
The Update button is unavailable because the program is already the latest version and cannot be upgraded.
If you want to release a key upgraded version, you can set the minimum version of the program to the version just released.
In this example, the minimum version of the program is set to 1.225, the latest version of the released program is 1.226, and the current version of the program on the client machine is 1.206. Therefore, when logging on to the system, the customer will receive a prompt "the program is outdated", requesting to upgrade the program version. Click "yes:
The program is also updated, and the version is upgraded to 1.226, as shown in:
The above describes how the customer upgraded the version. How can we release new versions of programs as program developers?
This is very simple. After a new version is developed and compiled, run the application and click the menu item "system> Publish application, in the displayed "application release" dialog box, click "release.
If this version is a key version, you can also set the minimum version required by the client program to this version.
How are these functions implemented?
First, our client application needs to connect to a Microsoft SQL Server database server at runtime. The SQL Server database has the following data tables:
Some records in this adm_configuration table store the values of the minimum and updated versions of the program.
The adm_clientrelease data table stores the specific information of the updated version of the program. The releasedata field has the data type varbinary (max), which stores the binary of the updated version of the program to be released.CodeItself.
The following is a stored procedure for reading the adm_configuration data table:
Create procedure [DBO]. [pradm_getconfiguration] @ thekey nvarchar (50), @ value nvarchar (128) outputasselect @ value = value from adm_configuration where thekey = @ thekey; if @ error = 0 and @ rowcount <> 1 begin declare @ errormessage nvarchar (4000); Set @ errormessage = n' error in reading the database configuration table, without this key: '+ @ thekey; raiserror (@ errormessage, 11, 1); End
The following is a stored procedure for updating the adm_configuration data table:
Create procedure [DBO]. [pradm_updateconfiguration] @ thekey nvarchar (50), @ value nvarchar (128) asupdate adm_configurationset value = @ valuewhere thekey = @ thekey; if @ error = 0 and @ rowcount <> 1 begin declare @ errormessage nvarchar (4000); Set @ errormessage = n' An error occurred while updating the database configuration table. No such key exists: '+ @ thekey; raiserror (@ errormessage, 11, 1); End
The following code reads and updates the C # source program (data layer) of the adm_configuration data table:
Namespace skyiv. ben. ICBC. MIS. ADM. data {sealed class configuration: dbobject {public configuration (string newconnectionstring): Base (newconnectionstring) {} Public String getvalue (string key) {sqlparameter [] parameters = {New sqlparameter ("@ thekey", sqldbtype. nvarchar, 50), new sqlparameter ("@ value", sqldbtype. nvarchar, 128)}; Parameters [0]. value = key; Parameters [1]. direction = parameterdirection. output; runnonquery ("pradm_getconfiguration", parameters); Return (string) parameters [1]. value;} public void Update (string key, string value) {sqlparameter [] parameters = {New sqlparameter ("@ thekey", sqldbtype. nvarchar, 50), new sqlparameter ("@ value", sqldbtype. nvarchar, 128)}; Parameters [0]. value = key; Parameters [1]. value = value; runnonquery ("pradm_updateconfiguration", parameters );}}}
The following is a stored procedure for reading the length of the binary code of the application version to be released in the adm_clientrelease data table:
Create procedure [DBO]. [release] @ releasename nvarchar (128), @ releaseversion varchar (128), @ releaselength int outputasselect @ release = datalength (releasedata) from releasename = @ releasename and releaseversion = @ releaseversion
The following is a stored procedure for reading the binary code of the application version to be released in the adm_clientrelease data table:
Create procedure [DBO]. [pradm_getclientreleasedata] @ releasename nvarchar (128), @ releaseversion varchar (128), @ userid int output, @ releasetime datetime output, @ releasedata varbinary (max) outputasselect @ userid = userid, @ releasetime = releasetime, @ releasedata = releasedatafrom adm_clientreleasewhere releasename = @ releasename and releaseversion = @ releaseversion
The following is the stored procedure for updating the adm_clientrelease data table:
Create procedure [DBO]. [pradm_updateclientrelease] @ releasename nvarchar (128), @ releaseversion varchar (128), @ userid int, @ releasedata varbinary (max) asdelete from adm_clientreleasewhere releasename = @ releasename; insert into adm_clientrelease (releasename, releaseversion, userid, releasedata) values (@ releasename, @ releaseversion, @ userid, @ releasedata );
The following code reads and updates the C # source program (data layer) of the adm_clientrelease data table:
Namespace skyiv. ben. ICBC. MIS. ADM. data {sealed class clientrelease: dbobject {public clientrelease (string newconnectionstring): Base (newconnectionstring) {} public void Update (string name, string version, int userid, byte [] data) {sqlparameter [] parameters = {New sqlparameter ("@ releasename", sqldbtype. nvarchar, 128), new sqlparameter ("@ releaseversion", sqldbtype. varchar, 128), new sqlparameter ("@ userid", sqldbtype. int, 4), new sqlparameter ("@ releasedata", sqldbtype. varbinary, Data. length)}; Parameters [0]. value = Name; Parameters [1]. value = version; Parameters [2]. value = userid; Parameters [3]. value = data; runnonquery ("pradm_updateclientrelease", parameters);} public byte [] getdata (string name, string version) {return getdata (name, version, getlength (name, version);} public int getlength (string name, string version) {sqlparameter [] parameters = {New sqlparameter ("@ releasename", sqldbtype. nvarchar, 128), new sqlparameter ("@ releaseversion", sqldbtype. varchar, 128), new sqlparameter ("@ releaselength", sqldbtype. int, 4)}; Parameters [0]. value = Name; Parameters [1]. value = version; Parameters [2]. direction = parameterdirection. output; runnonquery ("pradm_getclientreleaselength", parameters); Return (INT) parameters [2]. value;} byte [] getdata (string name, string version, int length) {sqlparameter [] parameters = {New sqlparameter ("@ releasename", sqldbtype. nvarchar, 128), new sqlparameter ("@ releaseversion", sqldbtype. varchar, 128), new sqlparameter ("@ userid", sqldbtype. int, 4), new sqlparameter ("releasetime", sqldbtype. datetime, 8), new sqlparameter ("@ releasedata", sqldbtype. varbinary, length)}; Parameters [0]. value = Name; Parameters [1]. value = version; Parameters [2]. direction = parameterdirection. output; Parameters [3]. direction = parameterdirection. output; Parameters [4]. direction = parameterdirection. output; runnonquery ("pradm_getclientreleasedata", parameters); Return (byte []) parameters [4]. value ;}}}
The following is part of the code for updating the key C # source program of the application:
Namespace skyiv. ben. ICBC. MIS. ADM. business {sealed class configuration: bizobject {public static version updateclientversion {get {return new version (dB. getvalue ("sys_updateclientversion");} set {dB. update ("sys_updateclientversion", value. tostring () ;}//< summary> /// check whether logon is allowed /// </Summary> Public static void checklogin () {If (maxminutesfortimediffserverandclient> 0 & math. ABS (DBC Ommon. getdbtime ()-datetime. Now). totalminutes)> maxminutesfortimediffserverandclient) throw new appexception ("the client system clock is inconsistent with the server"); If (! Online) throw new appexception ("database maintenance in progress, suspended. contact the Administrator "); If (dbversion <pub. mindbversion) throw new appexception ("the current database version is too low, please contact the Administrator ");} /// <summary> /// determine whether the application update conditions are met. /// </Summary> /// <returns> whether the application can be updated </returns> Public static bool canupdate () {If (Pub. theprincipal! = NULL) return false; version updateversion = NULL; try {updateversion = configuration. updateclientversion;} catch {} If (updateversion = NULL) return false; return updateversion> pub. version;} public static void updateapplicatoin () {If (! Canupdate () throw new appexception ("error: the condition for updating is not met"); string version = updateclientversion. tostring (); byte [] BS = clientrelease. getdata (Pub. assembly. getname (). name, version); string assemblylocation = pub. assembly. location; string oldfilename = assemblylocation + ". old "; file. delete (oldfilename); file. move (assemblylocation, oldfilename); Using (binarywriter BW = new binarywriter (New filestream (assemblylocation, filemode. createnew) {BW. write (BS);} MessageBox. show ("update complete, please click" OK "to exit this program", "Update", messageboxbuttons. OK, messageboxicon. information); application. exit ();}}}
The following is part of the C # source code of the "Update" button in the "about" dialog box:
Namespace skyiv. ben. ICBC. MIS. window {public partial class aboutform: skyiv. ben. ICBC. MIS. window. base2form {private void btnupdate_click (Object sender, eventargs e) {btnupdate. enabled = false; try {configuration. updateapplicatoin ();} catch (exception ex) {MessageBox. show (Pub. getmessage (Ex), "Update", messageboxbuttons. OK, messageboxicon. error );}}}}
The following is the C # source code of the "user login" dialog box:
Namespace skyiv. ben. ICBC. MIS. window {public partial class loginform: skyiv. ben. ICBC. MIS. window. base2form {private void btnsumbit_click (Object sender, eventargs e) {btnsubmit. enabled = false; try {tbxmessage. TEXT = ""; // (mdiwindow) mdiparent ). settimerinterval (); If (Pub. theprincipal! = NULL) {spcmain. enabled = false; tbxmessage. TEXT = "the user has logged on"; return;} configuration. checklogin (); If (Pub. version <configuration. clientversion) {If (! Configuration. canupdate () throw new exception ("this program is outdated and no new version is available, please contact the Administrator"); waityesno (configuration. updateapplicatoin, "this program is outdated and a new version is available. Are you sure you want to update it? "); Btnsubmit. Enabled = true; return;} pub. theprincipal = user. validateloginandsetlogined (tbxuserid. Text. Trim (), isusekeepedpassword? Logininfo. defaultpassword: tbxpassword. text); keepuserinfo (); If (Pub. theprincipal = NULL) tbxmessage. TEXT = string. format ("{0} user does not exist" + "or {0} password is incorrect or {0} user has logged on or {0} user has been disabled", environment. newline); else {tbxmessage. TEXT = "User Logon successful"; (mdiwindow) mdiparent ). updatestatus (); (mdiwindow) mdiparent ). afterlogin () ;}} catch (exception ex) {tbxmessage. TEXT = pub. getmessage (Ex);} btnsubmit. enabled = true ;}}}
The C # source code of the "Application release" dialog box is as follows:
Namespace skyiv. ben. ICBC. MIS. window {public partial class releaseapplicationform: skyiv. ben. ICBC. MIS. window. base2form {private void releaseapplicationform_load (Object sender, eventargs e) {releasefilename = pub. assembly. location; updatestatus ();} private void btnfilename_click (Object sender, eventargs e) {openfiledialog DLG = new openfiledialog (); DLG. filter = "Program (*. EXE ;*. DLL) | *. EXE ;*. DLL | all files (*. *) | *. * "; If (DLG. showdialog ()! = Dialogresult. OK) return; releasefilename = DLG. filename; updatestatus ();} void updatestatus () {tbxmessage. TEXT = ""; datatable dt = new datatable (); DT. columns. add ("attribute", typeof (string); DT. columns. add ("value", typeof (string); try {btnsubmit. enabled = false; assemblyname myself = pub. assembly. getname (); Pub. addrow (DT, "the Assembly name", myself. name); Pub. addrow (DT, "version of this Assembly", myself. version. tostring ()); Pub. addrow (DT, "Minimum Version Required", configuration. clientversion. tostring (); Pub. addrow (DT, "Last released version", configuration. updateclientversion. tostring (); Pub. addrow (DT, "information about the program to be released", ""); Pub. addrow (DT, "file name", releasefilename); Pub. addrow (DT, "file size", (new fileinfo (releasefilename )). length. tostring ("N0") + "bytes"); torelease = assembly. loadFile (releasefilename ). getname (); Pub. addrow (DT, "assembly name", torelease. na Me); Pub. addrow (DT, "assembly version", torelease. version. tostring (); If (myself. Name! = Torelease. name) throw new appexception ("the Assembly name to be released is incorrect"); tbxmessage. TEXT = "this program meets the conditions for publishing. Please press the" publish "button to publish"; btnsubmit. enabled = true;} catch (exception ex) {tbxmessage. TEXT = pub. getmessage (Ex);} finally {dgvmain. datasource = DT ;}} private void btnsubmit_click (Object sender, eventargs e) {tbxmessage. TEXT = ""; btnsubmit. enabled = false; try {using (binaryreader BR = new binaryreader (New filestream (releasefilename, filemode. open, fileaccess. read) {byte [] BS = BR. readbytes (INT) Br. basestream. length); clientrelease. update (torelease. name, torelease. version. tostring (), BS); configuration. updateclientversion = torelease. version; dgvmain. datasource = NULL; tbxmessage. TEXT = "client program released successfully, version:" + torelease. version. tostring () ;}} catch (exception ex) {tbxmessage. TEXT = pub. getmessage (Ex) ;}} private void btnminclientversion_click (Object sender, eventargs e) {tbxmessage. TEXT = ""; btnminclientversion. enabled = false; try {version = new version (tbxminclientversion. text); configuration. clientversion = version; tbxminclientversion. TEXT = ""; dgvmain. datasource = NULL; btnsubmit. enabled = false; tbxmessage. TEXT = "the minimum version required by the client program has been set to:" + version. tostring ();} catch (exception ex) {tbxmessage. TEXT = pub. getmessage (Ex);} btnminclientversion. enabled = true ;}}}
This is my current method for updating client applications. I hope to inspire everyone and give them some inspiration.