📄 appupdater.cs
字号:
using System;
using System.Net;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Collections;
using System.Diagnostics;
using System.Globalization;
using System.ComponentModel;
namespace Microsoft.Samples.AppUpdater
{
public enum ChangeDetectionModes:int {DirectFileCheck=1, ServerManifestCheck=2};
//**************************************************************
// AppUpdater Class
// - This is the main AppUpdater object
//**************************************************************
public class AppUpdater: Component, ISupportInitialize
{
public const int RestartAppReturnValue = 2;
private System.ComponentModel.Container components = null;
//Used to prevent event recursion in OnAssemblyResolve
private bool LoadingAssembly;
private Control EventControl;
internal AppManifest Manifest;
//Handles downloading & applying the update
private AppDownloader _Downloader;
[TypeConverter(typeof(ExpandableObjectConverter))]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Description("The object that downloads and installs new updates."),
Category("AppUpdate Configuration")]
public AppDownloader Downloader
{
get {return _Downloader;}
set {_Downloader=value;}
}
//Triggers update checks
private ServerPoller _Poller;
[TypeConverter(typeof(ExpandableObjectConverter))]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Description("The object that periodically polls for new updates."),
Category("AppUpdate Configuration")]
public ServerPoller Poller
{
get {return _Poller;}
set {_Poller=value;}
}
//Instructs the updater where to check & subsequently download updates
private string _UpdateUrl = "http://localhost/";
[DefaultValue(@"http://localhost/")]
[Description("The Url to download updates from."),
Category("AppUpdate Configuration")]
public string UpdateUrl
{
get {return _UpdateUrl;}
set {_UpdateUrl = value;}
}
//Indicates the mechanism to check for updates
private ChangeDetectionModes _ChangeDetectionMode = ChangeDetectionModes.DirectFileCheck;
[DefaultValue(ChangeDetectionModes.DirectFileCheck)]
[Description("The way to detect new updates."),
Category("AppUpdate Configuration")]
public ChangeDetectionModes ChangeDetectionMode
{
get {return _ChangeDetectionMode;}
set {_ChangeDetectionMode = value;}
}
//Indicates whether the udpater should put up it's default UI
private bool _ShowDefaultUI = false;
[DefaultValue(false)]
[Description("Determines whether the default UI is shown or supressed."),
Category("AppUpdate Configuration")]
public bool ShowDefaultUI
{
get {return _ShowDefaultUI;}
set {_ShowDefaultUI = value;}
}
//Whether the updater should try to automatically download missing files
private bool _AutoFileLoad = false;
[DefaultValue(false)]
[Description("Enables auto-download of missing assemblies."),
Category("AppUpdate Configuration")]
public bool AutoFileLoad
{
get {return _AutoFileLoad;}
set {_AutoFileLoad = value;}
}
//**************************************************************
// OnCheckForUpdate Event
// This event is called everytime the appupdater attempts to check for
// an update. You can hook this event and perform your own update check.
// Return a boolean value indicating whether an update was found.
// Notes:
// * This event fires on the poller thread, so you can make network requests
// to check for updates & it will be done asyncronously.
// * Because this event has a non void return value, it can only
// be handled by one event handler. It can not be multi-cast.
//**************************************************************
public delegate bool CheckForUpdateEventHandler(object sender, EventArgs e);
public event CheckForUpdateEventHandler OnCheckForUpdate;
//**************************************************************
// UpdateDetected Event
// - Fired when a new udpate is detected.
// - Fired on the UI thread.
//**************************************************************
public delegate void UpdateDetectedEventHandler(object sender, EventArgs e);
public event UpdateDetectedEventHandler OnUpdateDetected;
//**************************************************************
// UpdateComplete Event
// - Fired when an update is complete.
// - Fired on the UI thread.
//**************************************************************
public delegate void UpdateCompleteEventHandler(object sender, UpdateCompleteEventArgs e);
public event UpdateCompleteEventHandler OnUpdateComplete;
//**************************************************************
// Constructor()
// If you use this contrusctor, be sure to call Initialize() after
// you set all of the properties.
//**************************************************************
public AppUpdater()
{
Poller = new ServerPoller(this);
Downloader = new AppDownloader(this);
}
//**************************************************************
// Constructor()
// - Design time constructor
//**************************************************************
public AppUpdater(System.ComponentModel.IContainer container)
{
Poller = new ServerPoller(this);
Downloader = new AppDownloader(this);
container.Add(this);
InitializeComponent();
}
//**************************************************************
// Constructor()
// - If you use this contructor, no need to call initialize
//**************************************************************
public AppUpdater(string updateUrl,
ChangeDetectionModes changeDetectionMode,
bool showDefaultUI,
bool autoFileLoad,
bool validateAssemblies)
{
//Load the Poller & Updater
Poller = new ServerPoller(this);
Downloader = new AppDownloader(this);
UpdateUrl = updateUrl;
ChangeDetectionMode = changeDetectionMode;
ShowDefaultUI = showDefaultUI;
AutoFileLoad = autoFileLoad;
Downloader.ValidateAssemblies = validateAssemblies;
Initialize();
}
//**************************************************************
// BeginInit()
//**************************************************************
public void BeginInit()
{
}
//**************************************************************
// EndInit()
// - Called by designer generated code, after designer generated
// code has set all properites
//**************************************************************
public void EndInit()
{
if (!this.DesignMode)
Initialize();
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
//**************************************************************
// Initialize()
// - Sets up the updater, generates the default manifest,
// starts the threads, etc...
//**************************************************************
public void Initialize()
{
//Load the Manifest Config File
string AppManifestPath =Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @"\";
string AppManifestName = Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().Location);
AppManifestName += ".xml";
AppManifestPath = Path.Combine(AppManifestPath,AppManifestName);
Manifest = AppManifest.Load(AppManifestPath);
if (ChangeDetectionMode == ChangeDetectionModes.DirectFileCheck)
EnableManifestGeneration();
if (AutoFileLoad == true)
EnableFileAutoLoad();
if (Poller.AutoStart == true)
Poller.Start();
Downloader.OnUpdateComplete += new AppDownloader.UpdateCompleteEventHandler(OnDownloaderComplete);
Application.ApplicationExit += new EventHandler(OnApplicationExit);
EventControl = new Control();
//Access the control handle to make sure it's bound to this thread
IntPtr h = EventControl.Handle;
//If an update was in progress when the app was shut down,
//continue the download now that the app has restarted.
if (Manifest.State.Phase != UpdatePhases.Complete)
{
Debug.WriteLine("APPMANAGER: Continuing update already in progress");
Downloader.Start();
}
}
//**************************************************************
// DownloadUpdate()
// - Starts downloading an update from the location specified at
// UpdateUrl. The udpate itself is done async.
//**************************************************************
public void DownloadUpdate()
{
Downloader.Start();
}
//**************************************************************
// CheckForUpdates()
// - Checks for an update
// - This is a sync call... normally called by the poller object
// on the poller thread.
//**************************************************************
public bool CheckForUpdates()
{
Debug.WriteLine("APPMANAGER: Checking for updates.");
bool retValue = false;
//If the OnCheckForUpdate event the caller is doing the check
if (OnCheckForUpdate != null)
retValue = OnCheckForUpdate(this, new EventArgs());
//otherwise do the check ourselves
else
//If versioning is enabled check to see if the version file has changed.
if (ChangeDetectionMode == ChangeDetectionModes.ServerManifestCheck)
{
ServerManifest vm = new ServerManifest();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -