Introduction
2015 first, WinForm online update, is back to the bar, 09 just to Beijing when the hardware linkage programming, so most of the time is engaged in WinForm, but has never done online update this feature, a few days ago to participate in the Department of another project, come up on the need to add an online update. This automatic Update component core is the Templars developed, in addition to reference upstream cold dragon use situation, when I get this component source code do not know how to use, spent a large half a day and did not debug through, so I encountered the problem and the resolution of the record down, easy to follow the other coder use to view the use of the method.
Online Update Ideas
1, request the remote site Version.xml or request the Web server can be, the most important is to compare the server-side configuration file version number and the local configuration file version number.
2. Download the file from the remote site.
3, overwriting the local executable file and the DLL used, of course, before overwriting the need to shut down the local EXE process or Windows service process.
4. Modify the local configuration file autoupdater.config after overwriting the file.
5. Restart executable programs or Windows services after overwriting.
The Autoupdater disadvantage (has been perfected during use)
1, did not see the Templars how to use the component, refer to upstream cold Dragon demo, found the main program closed place.
2, when downloading the file does not take into account when the remote server new file processing local autoupdater.config, that is, the update process is based on the local configuration file config.updatefilelist.
3. There is no process for Windows service processing (the Windows Service processing class has been perfected).
Problems encountered when using
1, do not know how to use the component?
The project should have 4 parts when using the component: The Web site is used to accept requests and download the required update files, autoupdater update components, mainapplication (i.e. your main program), Updateapplication (the Updater portal, starting with the main program , the Autoupdater component is called inside the program).
2, do not know the appropriate to close the main program and Windows services
After looking at upstream Cold Dragon's demo to see that he is in the file before downloading, when you click confirm download to close the process.
if (bdownload) { //Closes Windows service serviceprocess serviceprocess = new ServiceProcess (); Serviceprocess.stopservice (); Switch off the main program operprocess oper=new operprocess (); Oper. Initupdateenvironment (); Downloadconfirm dc = new Downloadconfirm (downloadlist); if (this. OnShow! = null) this . OnShow (); if (DialogResult.OK = = DC. ShowDialog ()) { startdownload (downloadlist); }}
3, File download after the temporary directory and source program main directory aperture inconsistent
This adjusts the file copy, move code according to your needs. Our program executables and primary DLLs are placed in a separate file instead of the default bin\debug. So my approach is to move the download file from TempFolder to the executable source file root. The specific code is handled in the Procdownload method of the DownloadProgress form.
if (!string. IsNullOrEmpty (Tempfolderpath)) { OldPath = Path.Combine (commonunitity.systembinurl, file. FileName); NewPath = Path.Combine (commonunitity.systembinurl + constfile.tempfoldername + tempurlpath, file. FileName); }
4, File download mobile copy after the appropriate launch application
Add the finally code to the update, start the Windows service, start the main program, and close the update (updateapplication).
void Initandcheck () {bool Bhaserror = false; Iautoupdater autoupdater = new Autoupdater (); try {autoupdater.update (); } catch (WebException exp) {MessageBox.Show ("Can not find the specified resource"); Bhaserror = true; } catch (XmlException exp) {Bhaserror = true; MessageBox.Show ("Download The upgrade file error"); } catch (NotSupportedException exp) {Bhaserror = true; MessageBox.Show ("Upgrade address configuration Error"); } catch (ArgumentException exp) {Bhaserror = true; MessageBox.Show ("Download The upgrade file error"); } catch (Exception exp) {Bhaserror = true; MessageBox.Show ("An error occurred duRing the upgrade process "); } finally {if (Bhaserror = = true) {Try {Autoupdater.rollback (); } catch (Exception) {}} ServiceProcess serviceprocess = new ServiceProcess (); Serviceprocess.startservice (); Operprocess oper = new operprocess (); Oper. StartProcess (); } }
5. When a new file appears on the Web site, it is not synced to the local profile.
Look at the source code is found to modify the local autoupdater.config is based on the local updatefilelist, only need to add new Web-side file information to the list, the serialization of local config will be synchronized.
LocalFile tempfile = null; foreach (remotefile file in listremotfile.values) { downloadlist.add (new Downloadfileinfo (file). URL, file. Path, file. Lastver, file. Size)); Add the remote server file to CONFIG. Updatefilelist, use when modifying local autoupdater.config. tempfile = new LocalFile (file. Path, file. Lastver, file. Size); Config. Updatefilelist.add (tempfile); if (file. Needrestart) Bneedrestart = true; }
6. Adding Windows Service processing classes
public class ServiceProcess {#region Determine if the window service starts//<summary>//Determines if a Windows service is started </summary>//<returns></returns> private bool Isservicestart (string serv Icename) {ServiceController PSC = new ServiceController (serviceName); BOOL Bstartstatus = false; try {if (!PSC. Status.equals (servicecontrollerstatus.stopped)) {bstartstatus = true; } return bstartstatus; } catch (Exception ex) {throw new Exception (ex). Message); }} #endregion #region start service private bool StartService (string serviceName) { BOOL flag = TRUE; if (serviceisexisted (ServiceName)) {System.ServiceProcess.ServiceController service = new Syste M.serviceprocess.servicecontrOller (ServiceName); if (service. Status! = System.ServiceProcess.ServiceControllerStatus.Running && service. Status! = System.ServiceProcess.ServiceControllerStatus.StartPending) {service. Start (); for (int i = 0; i <; i++) {service. Refresh (); System.Threading.Thread.Sleep (1000); if (service. Status = = System.ServiceProcess.ServiceControllerStatus.Running) {break ; } if (i = =) {flag = false; }}}} return flag; } #endregion #region stop service private bool StopService (string serviceName) {BOOL Flag = true; if (serviceisexisted (serviceName)) {System.ServiceProcess.ServiceController service = new System.ServiceProcess.ServiceController (serv Icename); if (service. Status = = System.ServiceProcess.ServiceControllerStatus.Running) {service. Stop (); for (int i = 0; i <; i++) {service. Refresh (); System.Threading.Thread.Sleep (1000); if (service. Status = = System.ServiceProcess.ServiceControllerStatus.Stopped) {break ; } if (i = =) {flag = false; }}}} return flag; #endregion #region Determine if the window service exists private bool Serviceisexisted (string serviceName) { Servicecontroller[] Services = Servicecontroller.getservices (); foreach (ServiceController s in services) {if (S.servicename = = ServiceName) { return true; }} return false; } #endregion #region Installation Services private void Installservice (IDictionary statesaver, string filepath) {try {ServiceController service = new ServiceController ("ServiceName"); if (! Serviceisexisted ("ServiceName")) {//install Service assemblyinstal Ler Myassemblyinstaller = new Assemblyinstaller (); Myassemblyinstaller.usenewcontext = true; Myassemblyinstaller.path = filepath; Myassemblyinstaller.install (statesaver); Myassemblyinstaller.commit (statesaver); Myassemblyinstaller.dispose (); --starT Service service. Start (); } else {if (service. Status! = System.ServiceProcess.ServiceControllerStatus.Running && service. Status! = System.ServiceProcess.ServiceControllerStatus.StartPending) {service. Start (); }}} catch (Exception ex) {}} #endregion #region Uninstalling the Windows service private void Uninstallservice (string filepath) {try {if (serviceisexisted ("ServiceName")) {//uninstall Service Assemblyinstaller Myassemblyinstaller = new Assemblyinstaller (); Myassemblyinstaller.usenewcontext = true; Myassemblyinstaller.path = filepath; Myassemblyinstaller.uninstall (NULL); Myassemblyinstaller.dispose (); }} catch (Exception ex) {}} #endregion public void StopService () {if (serviceisexisted ("MyService")) {if (Isservic Estart ("MyService")) {this. StopService ("MyService"); }}} public void StartService () {if (serviceisexisted ("MyService" ) {if (! Isservicestart ("MyService")) {this. StartService ("MyService"); } } } }
Summarize
When there is any one function need to understand the principle of development, and can repeatedly debug the source code found on the Internet, after repeated debugging can understand the principles in order to better application. When I first got this function, I didn't understand that I wanted to integrate, and it took time to figure out how to use it. Thanks again for the revelation of the Templars and upstream's article.
Demo Download Extract Code 99A9
WinForm Online Update