| ÍøÕ¾Ê×Ò³ | ÎÄÕÂÖÐÐÄ | µç×ÓÊéÏÂÔØ | Ê¸Á¿Í¼¿â | ÊÓÆµ½Ì³Ì | ËزÄÏÂÔØ | ³ÌÐò´úÂëÏÂÔØ | JS´úÂë | ÂÛ̳ | 
ÁúÌڽ̳ÌÍø  
³£ÓÃÈí¼þÀࣺ
|ɱ¶¾°²È« |ÁªÂçÁÄÌì |ÍøÂçÈí¼þ |¶àýÌåÀà |ϵͳ¹¤¾ß |ͼÐÎͼÏñ |ϵͳ¹¤¾ß |Ó¦ÓÃÈí¼þ |ÐÐÒµÈí¼þ
¿ª·¢Éè¼ÆÀࣺ
|¶¯»­ÖÆ×÷ |ͼÏñ´¦Àí |3DÉè¼Æ |²Ù×÷ϵͳ |Õ¾³¤Ñ§Ôº |ÍøÂçÏà¹Ø |WEBÉè¼Æ |Êý¾Ý¿âÀà |³ÌÐò¿ª·¢
 
  Äúµ±Ç°Î»ÖãºÄúÏÖÔÚµÄλÖ㺠ÁúÌÚÈí¼þ½Ì³ÌÍø >> ÎÄÕÂÖÐÐÄ >> Ó¦ÓóÌÐò >> C#×¨Çø >> C#±à³ÌʵÁР>> ÎÄÕÂÕýÎÄ>>>>>> 
ÓÃApplication Updater BlockÉú³ÉÒ»¸ö×ÔÎÒ¸üеÄWinForms Ó¦ÓÃ(amart client)

ÔÚ¹ýÈ¥µÄÁ½¸öÐÇÆÚÀï, ÎÒÒ»Ö±ÔÚ×öÎҵĵÚÒ»¸öÕæÕýµÄ.net WinFormÓ¦ÓõĿª·¢.  ÕâÊÇÒ»¸öºÜÓÐȤµÄ¹ý³Ì,ÎÒÒ»Ö±ÔÚ·èÁËËÆµÄѧϰ¶«Î÷.  ÆäÖÐÖ®Ò»¾ÍÊÇÎÒÒªÔÊÐíÓ¦ÓóÌÐòÄܹ»ÓÃ΢ÈíµÄApplication Updater Block½øÐÐ×ÔÎÒ¸üС£  µ±ËüÕý³£¹¤×÷µÄÄÇÒ»¿Ì£¬ÈÃÎÒÓÐÒ»ÖֺܴóµÄ³É¾Í¸Ð£¬Í¬Ê±ÎÒÒ²Òâʶµ½Î¢ÈíûÓÐÌṩÄÇÖÖ°´²½Öè˳ÐòµÄÀý×Ó¡£  Duncan Mackenzie ÓÐÒ»¸ö ºÜºÃµÄblogÎÄÕ ¿ÉÒÔ×öÒ»¸ö¿ªÊ¼£¬µ«ÊÇÕâ¸öÀý×ÓÊÇVB×öµÄ²¢ÇÒûÓÐÌṩRSA¹«Ô¿ºÍ˽ԿµÄϸ½ÚÇé¿ö£¬ËùÒÔÎÒ¾ö¶¨ËµÒ»ÏÂÎҵŤ×÷¹ý³Ì¡£  Ï£ÍûÄܶÔÄãÓÐÓã¡

Step #1 Install the Application Blocks

Download the Updater Application Block from Microsoft .

Run the MSI Installer.

Step #2 ÔÚÏîÄ¿ÖмÓÈë´úÂëºÍÒýÓÃ:

°ÑÏÂÁй¤³Ì¼ÓÈëµ½ÄãµÄWinForm¹¤³ÌËùÔڵĽâ¾ö·½°¸:

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

Èç¹ûÄãÑ¡ÔñĬÈϰ²×°µÄ»°£¬ËüÃǵÄλÖÿÉÄÜÊÇ£º

C:\Program Files\Microsoft Application Blocks for .NET\Updater\Code\CS\Microsoft.ApplicationBlocks.Updater

ÔÚÄãµÄWinForm¹¤³ÌÖÐÒýÓÃÏÂÁй¤³Ì

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

°ÑÏÂÁÐÃüÃû¿Õ¼ä¼ÓÈëµ½ÄãFormµÄ.csÎļþÖР

 

using System.Runtime.InteropServices; 
using System.Runtime.Serialization; 
using System.Threading; 
using System.Diagnostics; 
using System.IO; 
using System.Xml; 

È»ºó Ìí¼ÓÕâ¸öλÖõÄÓ¦ÓóÌÐò¸üдúÂëµ½ÄãµÄ´úÂëÖÐ.  ÄãÐèÒª´ÓÄãµÄMainForm³õʼ»¯·½·¨Öе÷Óà InitializeAutoUpdate()¡£

Step #3 Éú³ÉÄãÓ¦ÓóÌÐòµÄ·¢²¼Ä¿Â¼½á¹¹²¢ÅäÖà AppStart.exe

Éú³ÉÒ»¸öÓÃÓÚ¿Í»§¶Ë³ÌÐò°²×°µÄĿ¼.  ±¾Àý×ÓÖУ¬ÎÒÃÇÓÃÈçϵÄĿ¼£º

C:\Program Files\YourApp\1.0.0.0\

ÏÖÔÚ¸´ÖÆ AppStart.exe ºÍ AppStart.exe.config µ½ÀàËÆÈçϵĸùĿ¼ÖÐ

 C:\Program Files\YourApp\AppStart.exe
 C:\Program Files\YourApp\AppStart.exe.config

˵Ã÷: ÕâÁ½¸öÎļþÄã¿ÉÒÔÔÚÈçÏÂĿ¼ÖÐÕÒµ½ ¡°C:\Program Files\Microsoft Application Blocks for .NET\Updater\Code\CS\Microsoft.ApplicationBlocks.Updater\AppStart\bin\Debug¡°  

Step #4 ÐÞ¸Ä AppStart.exe.config Îļþ

AppStart.exe »áÆô¶¯ÄãµÄÓ¦ÓóÌÐò£¬Èç¹û¸üÐÂÎļþÏÂÔØÍê³ÉÖ®ºó»¹ÓпÉÄÜÒªÖØÆô.  ËüÐèÒªÖªµÀÆô¶¯Äã×îеijÌÐòµÄĿ¼λÖÃ. 
ÐÞ¸ÄÅäÖÃÎļþÒÔÅäºÏµ±Ç°µÄ°æ±¾:

 

<appStart> 
  
<ClientApplicationInfo> 
    
<appFolderName>C:Program FilesYourApp1.0.0.0</appFolderName> 
    
<appExeName>YourAppName.exe</appExeName> 
    
<installedVersion>1.0.0.0</installedVersion> 
    
<lastUpdated>2004-06-10T15:33:17.3745836-04:00</lastUpdated> 
  
</ClientApplicationInfo> 
</appStart> 

Step #5: Éú³ÉÄãµÄ¹«Ô¿ºÍ˽Կ

ÔËÐÐ "C:\Program Files\Microsoft Application Blocks for .NET\Updater\Code\CS\Microsoft.ApplicationBlocks.Updater\ManifestUtility\bin\Debug\ManifestUtility.exe"

Ñ¡Ôñ ¡°File..Generate Keys¡±  »áÌáʾÄãÊÇ·ñÐèÒª±£´æ: PublicKey.xml ºÍ PrivateKey.xml  ÕâÁ½¸öÃÜÔ¿½ÓÏÂÀ´¾Í»áÓõ½. 

ÎÒÕâÀïÒªÌáÐÑ´ó¼Ò£¬ÕâЩÃÜÔ¿Ö»ÒªÉú³ÉÒ»´Î¾Í¿ÉÒÔÁË, ÒòΪÏÂÃæ¼¸¸öµØ·½ÐèÒªÒýÓõ½RSA¹«Ô¿ºÍ˽Կ.  ÄãÐèÒª°ÑÕâЩÃÜÔ¿´æ·ÅÔÚÒ»¸ö°²È«µÄµØ·½£¬ÒòΪÔÚ·¢²¼Ò»¸öеĸüеÄʱºò»áÓõ½Ëü

Step #6 ´´½¨IIS ÐéÄâĿ¼

ÔÚÄãµÄWeb·þÎñÆ÷ÉÏÉú³ÉÒ»¸öĿ¼À´´æ·ÅÄãµÄ¸üÐÂÎļþ.  ÔÚÕâÁ½¸öĿ¼ÖÐÒª·ÅÁ½Ñù¶«Î÷ 1)  ServerManifest.xml Îļþ£¬°üº¬×îºó°æ±¾µÄһЩÐÅÏ¢£»2) ÄãµÄгÌÐòµÄĿ¼. ÔÚÕâ¸öĿ¼ÀÉú³ÉÒ»¸öĿ¼À´´æ·ÅÄãµÄа汾³ÌÐò.  ÔÚÎÒÃǵÄÀý×ÓÖУ¬ÎÒÃÇÓÃÕâÁ½¸öĿ¼, C:\Inetpub\AppUpdates  ºÍC:\Inetpub\AppUpdates\1.0.0.1

Óà IIS ¹ÜÀíÆ÷Éú³ÉÒ»¸öÐéÄâĿ¼ָÏò¸Õ²ÅµÄʵ¼ÊĿ¼.  ¼ÇÏÂÄãµÄ URL, ÔÚÉÏ´«²½ÖèÖÐÎÒÃÇÐèÒªÓõ½Ëü.  Äã±ØÐëÒª´ò¿ªÐéÄâĿ¼µÄ¡°Ä¿Â¼ä¯ÀÀ¡±Ñ¡Ïî.

Step #7. ÅäÖÃÄãµÄ°æ±¾ 1.0.0.0 µÄApp.config Îļþ

ÕâÀÎÒÃÇ»áÐèÒªÍùÀïÌí¼ÓһЩж«Î÷.  Ê×ÏÈ, ÎÒÃÇÐèÒª¼ÓÈëÒ»¸öconfigSections ÔªËØÀ´¶¨ÒåÎÒÃÇµÄ appUpdater ½Ú:

<configSections>
  <section name="appUpdater" type="Microsoft.ApplicationBlocks.ApplicationUpdater.UpdaterSectionHandler,Microsoft.ApplicationBlocks.ApplicationUpdater" />
</configSections>

½ÓÏÂÀ´£¬ÎÒÃÇÐèÒªÌí¼ÓÒ»¸ö Version ¼üµ½ÎÒÃÇµÄ appsettings ÖÐ, ÎÒÃÇÊ×ÏÈÉèÖÃÎÒÃǵı¾µØ°æ±¾Îª 1.0.0.0, ÕâÑùÎÒÃǾͿÉÒÔ²âÊÔ×Ô¶¯¸üе½°æ±¾ 1.0.0.1

<appSettings>
  <add key="VERSION" value="1.0.0.0" />
</appSettings>

×îºó£¬, ¼ÓÈë appUpdater ½Úµ½ÄãµÄÅäÖÃÎļþÖÐ.  ÎÒÕâÀïÓÃÒ»¶Ô·½À¨ºÅ°ÑÄãÒªÐ޸ĵÄÖµ°üº¬ÆðÀ´.  Äã¿ÉÒÔÖ±½Ó´ÓÄãÉÏÒ»²½Éú³ÉµÄ PublicKey.xmlÎļþÖи´ÖÆ <RSAKeyValue> ÔªËØ.

<xmlFile> ÔªËØ±ØÐëÒªÖ¸ÏòÄãÔÚStep #6´´½¨µÄÐéÄâĿ¼µÄ URL .

 

<appUpdater> 
  
<UpdaterConfiguration> 
   
<polling type="Seconds" value="120" /> 
   
<logListener logPath="C:Program FilesYourAppUpdaterLog.txt" /> 
   
<downloader type="Microsoft.ApplicationBlocks.ApplicationUpdater.Downloaders.BITSDownloader" 
assembly
="Microsoft.ApplicationBlocks.ApplicationUpdater,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"/> 
   
<validator type="Microsoft.ApplicationBlocks.ApplicationUpdater.Validators.RSAValidator" assembly="Microsoft.ApplicationBlocks.ApplicationUpdater,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null"> 
  
<key> 
   
<RSAKeyValue> 
  
<Modulus>[YOUR MODULUS KEY]</Modulus> 
  
<Exponent>[YOUR EXPONENET]</Exponent> 
  
</RSAKeyValue> 
  
</key> 
  
</validator>  
  
<application name="[YOUR APP NAME]" useValidation="true"> 
    
<client> 
      
<baseDir>C:Program FilesYourApp</baseDir> 
      
<xmlFile>C:Program FilesYourAppAppStart.exe.config</xmlFile> 
      
<tempDir>C:Program FilesYourApp emp</tempDir> 
    
</client> 
    
<server> 
     
<xmlFile>http://[YOUR URL]/ServerManifest.xml</xmlFile> 
     <xmlFileDest>C:Program FilesYourAppServerManifest.xml</xmlFileDest> 
     
<maxWaitXmlFile>60000</maxWaitXmlFile> 
    
</server> 
  
</application> 
 
</UpdaterConfiguration> 
 
</appUpdater> 

Step #8 ·¢²¼°æ±¾ 1.0.0.0

ÉèÖÃÓ¦ÓóÌÐò°æ±¾ºÅ.  ¿ÉÒÔͨ¹ýÉèÖÃÔÚ AssemblyInfo.cs ÎļþÖеİ汾ÊôÐÔÀ´ÉèÖð汾ºÅ.

[assembly: AssemblyVersion("1.0.0.0")]

±àÒëÓ¦ÓóÌÐò²¢¸´ÖÆ 1.0.0.0 °æ³ÌÐòµ½Äã³ÌÐòµÄ 1.0.0.0 Ŀ¼ÖÐ. ¡°C:\Program Files\YourApp\1.0.0.0¡°

ÕâÀÄãÐèÒªÔËÐÐһϠAppStart.exe.  ¸üйý³Ì»áʧ°Ü£¬ÒòΪÎÒÃDz¢Ã»Óаѷ¢²¼ ServerManifest XML ÎļþÀ´Ö¸Ê¾Ó¦ÓóÌÐòа汾ÊÇ·ñ¿ÉÓÃ.  Äã¿ÉÒÔ¼ì²éÈÕÖ¾Îļþ£¬Î»ÖÃÔÚ C:\Program Files\YourApp\ Ŀ¼ÖÐ.

Step #9 ¹¹½¨°æ±¾ 1.0.0.1 

ÕâÊÇ×îÓÐȤµÄ²¿·Ö.  Ê×ÏÈ, ͨ¹ý¸üÐÂÓ¦ÓóÌÐòµÄ AssemblyInfo.cs ºÍ App.config ÎļþÄÚÈÝÀ´Éú³ÉÐÞ¶©°æ±¾ 1.0.0.1 .  ±àÒë³ÌÐò, È»ºó¸´ÖÆÎļþµ½step #6Éú³ÉµÄWeb·þÎñÆ÷Ŀ¼ÖÐ. 

Step #10 Éú³É·þÎñÆ÷µÄÇåµ¥Îļþ

Õâ¸öÊÇ×îºóÒ»²½.  Èç¹ûÄã¶Ô±¾²½ÖèÖеÄ.configÎļþ×÷ÁËÈκÎÐ޸ĵϰ£¬¶¼±ØÐë°Ñ±¾²½ÖèÖØÀ´Ò»±é.  ×ö·¨ÈçÏÂ:

ÔÙ´ÎÔËÐÐ ManifestUtility ³ÌÐò. 
ÔÚ ¡°Update files folder¡° Ñ¡ÔñÆ÷ÖÐÑ¡Ôñ 1.0.0.1 Ŀ¼ . 
ÊäÈë¸üÐÂλÖÃµÄ URL . 
ÊäÈëа汾ºÅ 1.0.0.1
´ò¿ªÖ®Ç°Éú³ÉµÄ PrivateKey.xml Îļþ.
Ñ¡ÔñÑéÖ¤Àà ¡°Microsoft.ApplicationBlocks.ApplicationUpdater.Validators.RSAValidator¡±
Êó±êµã»÷ CreateManifest, ²¢±£´æ ServerManifest.xml Îļþµ½ÄãµÄÐéÄâ·þÎñÆ÷Ŀ¼ÖÐ.
¾ÍÕâЩ!  Pheeew!  ´ÓÄãµÄ C:\Program Files\YourApp\ Ŀ¼ÖÐÔËÐÐÄãµÄ AppStart.exe .  ÄãµÄ³ÌÐò¾Í»á±»×°Èë, µ±ÄãµÄ³ÌÐòÔËÐеÄʱºò£¬Äã¾Í»áµÃµ½Ò»¸öÌáʾ ¡°Ð°汾¿ÉÓá± .  а汾»áÏÂÔØµ½Ä¿Â¼ C:\Program Files\YourApp\1.0.0.1 ÖÐ, È»ºó³ÌÐò»á×Ô¶¯ÖØÆô.  Èç¹ûÓÐÈκÎÎÊÌâ, ¼ÇµÃ¼ì²éÒ»ÏÂÈÕÖ¾Îļþ.  ÕâЩÈÕÖ¾ÔÚÕï¶ÏÎÊÌâµÄʱºò»áºÜÓÐÓõÄ.

-Brendan

posted on Thursday, June 10, 2004 11:25 AM

¸½Â¼£ºÎÄÖв½Öè #2 °üº¬µÄ´úÂëÈçÏ£º

 

Auto-Update StuffAuto-Update Stuff
/**//// <summary> 
/// 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 the main thread NOT the eventing thread 
/// </summary> 
/// <param name="sender">marshalled reference to the original event's sender argument</param> 
/// <param name="e">marshalled reference to the original event's args</param> 

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 don't 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 Cancelled."); 
    }
 
    
else 
    

        Debug.WriteLine(
"Update in progress."); 
    }
 
}
 
 
/**//// <summary> 
/// Event handler for Updater event.  This event is fired by the originating thread from "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 our window thread using the synchronous Invoke 
/// mechanism. 
/// </summary> 
/// <param name="sender">event sender in this case ApplicationUpdaterManager</param> 
/// <param name="e">the UpdaterActionEventArgs packaged by Updater, which gives us access to update information</param> 

private void OnUpdaterUpdateAvailable( 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 
    this.Invoke(  
        
new MarshalEventDelegate( this.OnUpdaterUpdateAvailableHandler ),  
        
new object[] { sender, e } ); 
}
 
 
     
/**//// <summary> 
/// 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 the main thread NOT the eventing thread 
/// </summary> 
/// <param name="sender">marshalled reference to the original event's sender argument</param> 
/// <param name="e">marshalled reference to the original event's args</param> 

private void OnUpdaterDownloadCompletedHandler( object sender, UpdaterActionEventArgs e ) 

    Debug.WriteLine(
"Download Completed."); 
 
}
 
 
/**//// <summary> 
/// Event handler for Updater event.  This event is fired by the originating thread from "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 our window thread using the synchronous Invoke 
/// mechanism. 
/// </summary> 
/// <param name="sender">event sender in this case ApplicationUpdaterManager</param> 
/// <param name="e">the UpdaterActionEventArgs packaged by Updater, which gives us access to update information</param> 

private void OnUpdaterDownloadCompleted( 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 
    this.Invoke(  
        
new MarshalEventDelegate( this.OnUpdaterDownloadCompletedHandler ),  
        
new object[] { sender, e } ); 
}
 
 
 
private void StartNewVersion( ServerApplicationInfo server ) 

    XmlDocument doc 
= new XmlDocument(); 
 
    
//  load config file to get base dir 
    doc.Load( AppDomain.CurrentDomain.SetupInformation.ConfigurationFile ); 
 
    
//  get the base dir 
    string baseDir = doc.SelectSingleNode("configuration/appUpdater/UpdaterConfiguration/application/client/baseDir").InnerText; 
    
string newDir = Path.Combine( baseDir, "AppStart.exe" ); 
 
    ProcessStartInfo process 
= new ProcessStartInfo( newDir ); 
    process.WorkingDirectory 
= Path.Combine( newDir , server.AvailableVersion ); 
 
    
//  launch new version (actually, launch AppStart.exe which HAS pointer to new version ) 
    Process.Start( process ); 
 
    
//  tell updater to stop 
    CurrentDomain_ProcessExit( nullnull ); 
    
//  leave this app 
    Environment.Exit( 0 ); 
}
 

ÉÏһƪ:
  • ÉÏһƪÎÄÕ£º
  • ÏÂһƪ
  • ÏÂһƪÎÄÕ£º ûÓÐÁË
  • ÊղشËÎĵ½°Ù¶ÈËѲؠ°Ù¶ÈËѲØ| ÐÂÀËVIvi| 365key| Younote| ²©²ÉÖÐÐÄ| ÄãºÃBLOG| ÒÚÓÑÍøÕª| ºÍÑ¶ÍøÕª|
    Ïà¹ØÎÄÕ    
    asp.net£¨C#£©ÏÂÓ¦ÓÃMSMQÊÕ·¢ÏûÏ¢
    C# »ñÈ¡¼ÆËã»úµÄÓ²¼þÐÅÏ¢µÄ·½·¨
    C#ÓïÑÔÖÆ×÷Ö©Öë³ÌÐòÏê½â
    C#Ó