[Reproduced] UAB

xiaoxiao2021-03-06  42

Generate a self-updated WinForms app with Application Updater Block

BigTall

Original address

In the past two weeks, I have been doing my first real .NET Winform application development. This is a very interesting process, I have been crazy learning. One is what I want. Allow applications to be able to use Microsoft Application Updater Block for self-updating. When it's normal to work, let me have a great sense of accomplishment, and I also realize that Microsoft does not provide that sequential example. Duncan Mackenzie has a good blog article to be a beginning, but this example is VB did and does not provide the details of the RSA public key and private key, so I decided to say my work process. I hope to be useful to you!

Step # 1 Install the Application Blocks

Download The Updater Application Block from Microsoft.

Run the msi installer.

Step # 2 Add code and reference in the project:

Add the following projects to your WINFORM project:

Microsoft.ApplicationBlocks.ApplicationUpdater Microsoft.ApplicationBlocks.ApplicationUpdater.Interfaces Microsoft.ApplicationBlocks.ExceptionManagement Microsoft.ApplicationBlocks.ExceptionManagement.Interfaces

If you choose the default installation, their location may be:

C: / Program Files / Microsoft Application Blocks for .NET / UPDATER / CODE / CS / Microsoft.ApplicationBlocks.Updater

Quote the following projects in your WinForm project

Microsoft.ApplicationBlocks.ApplicationUpdater Microsoft.ApplicationBlocks.ApplicationUpDater.Interfaces Microsoft.ApplicationBlocks.ExceptionManagement

Add the following namespace to your form .cs file

Using system.Runtime.interopservices; using system.runtime.serialization; using system.diagnostics; using system.io; using system.xml;

Then add this location to update the code to your code. You need to call InitializeAutOupDate () from your MainForm initialization method.

Step # 3 Generate your application's publishing directory structure and configure AppStart.exe

Generate a directory for the client program installation. In this example, we use the following directory:

C: / program files / yourapp / 1.0.0.0 /

Copy AppStart.exe and AppStart.exe.config to the following root directory

C: / program files / yourapp / appstart.exe c: / program files / yourapp / appstart.exe.config

Description: These two files You can find "C: / Program Files / Microsoft Application Blocks for .NET / Updater / Code / CS / Microsoft.ApplicationBlocks.Updater / AppStart / Bin / Debug" in the following directory

Step # 4 Modify AppStart.exe.config file AppStart.exe will start your application, if you can restart after the update file download is complete. It needs to know the directory location of your latest program. Modify the configuration file to cooperate with the current version: C: / Program Files / YourApp / 1.0.0.0 YourAppName.exe 1.0.0.0 2004-06-10T15: 33: 17.3745836-04: 00

STEP # 5: Generate your public key and private key

Run "C: / Program Files / Microsoft Application Blocks for .NET / UPDATER / CODE / CS / Microsoft.ApplicationBlocks.Updater / Manifestutility / Bin / Debug / Manifestutility.exe"

Select "file..generate Keys" will prompt you if you need to save: publickey.xml and privateKey.xml The two key will be used next.

I have to remind everyone that these keys can be generated once, because the following places need to be referenced to the RSA public key and private key. You need to put these keys in a safe place, because it is released a new one It will be used when updating

Step # 6 Create an IIS virtual directory

Generate a directory on your web server to store your update file. In these two directories, you have to put two things 1) ServerManifest.xml files, contain some information about the last version; 2) The directory of your new program. In this directory, generate a directory to store your new version of the program. In our example, we use these two directories, c: / inetpub / appupdates and c: /inetpub/appupdates/1.0.0.1

Generate a virtual directory by IIS Manager to point to the actual directory you just, write down your URL, we need to use it in the upload step. You must open the Directory Browse option of the virtual directory.

Step # 7. Configure your version 1.0.0.0 app.config file here, we need to add some new things in the middle. First, we need to join a configsections element to define our AppUpdater section:

Next, we need to add a Version key to our appsettings, we first set our local version of 1.0.0.0, so we can test the automatic update to version 1.0.0.1

Finally, join the AppUpdater section to your configuration file. I use a pair of brackets to include the value you want to modify. You can copy the element directly from the publickey.xml file generated by you.

element must point to the URL of the virtual directory created in Step # 6.

[YOUR MODULUS KEY] [YOUR EXPONENET] C: / program files / yourapp C: / Program Files / Yourapp / AppStart.exe.config C: / Program Files / Yourapp / Temp HTTP : // [Your URL] /Servermanifest.xml C: / Program Files / Yourapp / ServerManifest.xml 60000 < / UpdaterConfiguration>

STEP # 8 Release 1.0.0.0 Settings the application version number. You can set the version number by setting the version attribute in the assemblyinfo.cs file.

[Assembly: askMBLYVERSION ("1.0.0.0")]]]]

Compile the application and copy the 1.0.0.0.0.0 directory of the 1.0.0.0.0.0 version of your program. "C: / program files / yourapp / 1.0.0.0"

Here, you need to run AppStart.exe. The update process will fail because we don't have the release serverManifest XML file to indicate if the application new version is available. You can check the log file, location in C: / Program files / yourapp / directory China. Step # 9 Build Version 1.0.0.1 This is the most interesting part. First, by updating the application's assemblyinfo.cs and app.config file content to generate a revised version 1.0.0.1. Compiler, then copy files to step # 6 Generate the web server directory. STEP # 10 Generate the list of servers This is the last step. If you make any modification in this step, you must raise this step again. The practice is as follows:

Run the ManifestUtility program again. Select the 1.0.0.1 directory in the "Update Files Folder" selector. Enter the URL of the update location. Enter the new version number 1.0.0.1 Open the previously generated privatekey.xml file. Select the verification class "Microsoft.ApplicationBlocks. ApplicationUpdater.validators.rsavalidator "Mouse click CreateManifest and saves serverManifest.xml files into your virtual server directory. That's these! Pheew! From your C: / program files / yourapp / directory, run your appstart.exe. You The program will be loaded. When your program is running, you will get a prompt "new version available". The new version will download to the directory C: / program files / yourapp / 1.0.0.1, then the program will Automatic restart. If there is any problem, remember to check the log file. These logs will be useful when diagnostic problems. -Brendan

Posted on Thursday, June 10, 2004 11:25 am

Appendix: The code contained in the text step # 2 is as follows:

Auto-Update Stuff

#region Auto-Update Stuff private ApplicationUpdateManager _updater = null; private Thread _updaterThread = null; private const int UPDATERTHREAD_JOIN_TIMEOUT = 3 * 1000; private delegate void MarshalEventDelegate (object sender, UpdaterActionEventArgs e); private void InitializeAutoUpdate () {// hook ProcessExit for a chance to clean up when closed peremptorily AppDomain.CurrentDomain.ProcessExit = new EventHandler (CurrentDomain_ProcessExit); // make an Updater for use in-process with us _updater = new ApplicationUpdateManager (); // hook Updater events _updater.DownloadStarted = new UpdaterActionEventHandler (OnUpdaterDownloadStarted); _updater.FilesValidated = new UpdaterActionEventHandler (OnUpdaterFilesValidated); _updater.UpdateAvailable = new UpdaterActionEventHandler (OnUpdaterUpdateAvailable); _updater.DownloadCompleted = new UpdaterActionEventHandler (OnUpdaterDownloadCompleted); // start the updater on a separate thread so that our UI remains responsive _updaterThread = new Thread (new ThreadStart (_updater.StartUpdater)); _updaterThread.Start (); // get version from config, set caption correctly string version = System.Configuration.ConfigurationSettings.AppSettings [ "version" ]; This.text = this.text string.format ("v. {0}", version;} private void currentdomain_processExit (Object sender, Eventargs e) {stopupdater ();} private void stopupdater () {// Tell Updater to stop_Updater.stopupdater (); if (null! =

_updaterThread) {// join the updater thread with a suitable timeout bool isThreadJoined = _updaterThread.Join (UPDATERTHREAD_JOIN_TIMEOUT); // check if we joined, if we did not interrupt the thread if (isThreadJoined) {_updaterThread.Interrupt ()!; } _Updaterthread = null;}} /// This handler gets fas is the main st haked for this form. It takes the time /// arguments as the event Handler Below It - Sender, E - And Acts on the Eventing Thread /// /// Marshalled Reference to the Original Event's sender argument /// marshalled reference to the original event's args private void OnUpdaterDownloadStartedHandler (object sender, UpdaterActionEventArgs e) {Debug.WriteLine ( "Thread:" Thread.CurrentThread.GetHashCode ( ) .Tostring ()); debug.writeLine (STR ING.FORMAT ("DownloadStarted for Application '{0}'", E.ApplicationName);} / ** ////

/// Event Handler for Updater Event. This Event is Fired by The Originating Thread from Fred by THIS "inside" the Updater While it is /// possible for this same thread to act on our UI, it is nOT a good thing to do -.. UI is not threadsafe /// Therefore here we marshal from the Eventing thread ( Belongs to updater) To outline invoke /// mechanism. /// /// Event sender in this case applicationUpdaterManager /// the UpdaterActionEventArgs packaged by Updater, which gives us access to update information private void OnUpdaterDownloadStarted (object sender, UpdaterActionEventArgs e) {// using the synchronous" Invoke "This marshals from the eventing thread -. which comes from the Updater and should not // be allowed to enter and "touch" the UI's window thread // so we use Invoke which allows us to block the Updater thread at will while only allowing window thread to update UI Debug.WriteLine (String. Format ( "[OnUpdaterDownloadStarted] Thread: {0}"., Thread.CurrentThread.GetHashCode () ToString ())); this.Invoke (new MarshalEventDelegate (this.OnUpdaterDownloadStartedHandler), new object [] {sender, e}); } / ** //// /// this handler gets fas at the wall sta thread for this form. It takes the same /// arguments as the Event Handler Below It - sender , E - and ACTS ON Them Using The Main Thread No T the evening thread /// /// Marshalled Reference to the Original Event's sender argument /// Marshalled Reference to the Original event's args private void OnUpdaterFilesValidatedHandler (object sender, UpdaterActionEventArgs e) {Debug.WriteLine (String.Format ( "FilesValidated successfully for application '{0}'", e.ApplicationName)); // ask user to use new App DialogResult Dialog = MessageBox.show ("Would You Like to Stop this Application And Open THE New Version?", "Open New Version?"

MessageBoxButtons.yesno; if (DialogResult.yes == Dialog) {StartNewVersion (E.ServerInformation);}} / ** ////

/// Event Handler for updater event. This Event is Fired by THIS feve ORIGINATING Thread from "Inside" The Updater. While It Is // Possible for this Same Thread To Act On Our UI, IT IS Not a Goodsafe Do - UI Is Not Threadsafe. // Therefore Here WE Marshal from THE eventing thread (belongs to Updater) to our window thread using the synchronous Invoke /// mechanism. /// /// event sender in this case ApplicationUpdaterManager // / the UpdaterActionEventArgs packaged by Updater, which gives us access to update information private void OnUpdaterFilesValidated (object sender, UpdaterActionEventArgs e) {// using the asynchronous "BeginInvoke". // we don 'T NEED / WANT to block (New MarshaleventDelegate (this.onUpdaterfilesvalidatedha) NDLER, new object [] {seronder, e});} / ** //// /// this handler gets Fired by The Windows Ui Thread That Is The Main Sta Thread for this Form. It takes the Same /// arguments as The Event Handler Below It - Sender, E - And Acts on The Eventing Thread /// /// Marshalled Reference To the Original Event's sender argument /// Marshalled Reference to the Original Event's Args

private void OnUpdaterUpdateAvailableHandler (object sender, UpdaterActionEventArgs e) {Debug.WriteLine ( "Thread:". Thread.CurrentThread.GetHashCode () ToString ()); string message = String.Format ( "Update available: The new version on the server is {0} and current version is {1} would you like to upgrade ", e.ServerInformation.AvailableVersion, System.Configuration.ConfigurationSettings.AppSettings [" version "]);? // for update available we actually WANT to block the downloading thread so we can refuse an update // and reset until next polling cycle; // NOTE that we do not block the thread _in the UI_, we have it blocked at the marshalling dispatcher "OnUpdaterUpdateAvailable" DialogResult dialog = MessageBox.Show ( Message, "Update Available", MessageBoxButtons.yesno; if (DialogResult.no == Dialog) {// if no, stop the updater for this app _Updater.stopupdater (E.ApplicationName); Debug. WriteLine ("Update Cancelle);} else {debug.writeline (" Update in Progress. ");}} / ** ////

/// Event Handler for update event. This event is fas The Originating Thread from "Inside" The Updater. While It Is // Possible for this Same Thread To Act On Our UI, IT IS Not a Goodsa - UI Is Not Threadsafe. // Therefore Here We Marshal from the Eventing thread (belongs to Updater) to our window thread using the synchronous Invoke /// mechanism. /// /// event sender in this case ApplicationUpdaterManager / //

"E"> the UpdaterActionEventArgs packaged by Updater, which gives us access to update private void OnUpdaterUpdateAvailable (object sender, UpdaterActionEventArgs e) {// using the synchronous "Invoke" information This marshals from the eventing thread -. Which comes from the Updater and should not // be allowed to enter and "touch" the UI's window thread // so we use Invoke which allows us to block the Updater thread at will while only allowing window thread to update UI this.Invoke (new MarshalEventDelegate (this.OnUpdaterUpdateAvailableHandler), new object [] {sender, e});} / ** ////

/// This handler gets fired by the Windows UI thread that is the main STA thread for THIS FORM . It takes the same /// arguments as the Event Handler Below It - sender, E - and ACTS ON THEM USING THETREAD NOT I Eventing thread /// /// Marshalled Reference to the Original Event's sender argument /// marshalled reference to the original event's args private void OnUpdaterDownloadCompletedHandler (object sender, UpdaterActionEventArgs e) {Debug.WriteLine ( "Download Completed.");} / ** // // /// Event Handler for update Event. This Event is fasad from "Inside" The updater. While it is /// Possible for this Same Thread To Act On Our UI, IS Not a Goodthing to do - ui is not threadsafe. //////////////////////////////////////////////////> <

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

New Post(0)