mirror of
https://github.com/LorenzCK/OnTopReplica.git
synced 2024-05-10 07:22:29 +12:00
Issue #54: new updating mechanism, now based on official CodePlex RSS release feed.
Some code clean-up.
This commit is contained in:
parent
b75214d5e4
commit
56e47fb7e5
135
OnTopReplica/AppStrings.resx
Normal file
135
OnTopReplica/AppStrings.resx
Normal file
|
@ -0,0 +1,135 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ApplicationWebsite" xml:space="preserve">
|
||||
<value>http://ontopreplica.codeplex.com</value>
|
||||
</data>
|
||||
<data name="AuthorWebsite" xml:space="preserve">
|
||||
<value>http://lorenz.klopfenstein.net</value>
|
||||
</data>
|
||||
<data name="LatestCommitsLink" xml:space="preserve">
|
||||
<value>http://ontopreplica.codeplex.com/SourceControl/list/changesets</value>
|
||||
</data>
|
||||
<data name="MsRlLicenseLink" xml:space="preserve">
|
||||
<value>http://opensource.org/licenses/ms-rl.html</value>
|
||||
</data>
|
||||
<data name="UpdateFeed" xml:space="preserve">
|
||||
<value>http://ontopreplica.codeplex.com/project/feeds/rss?ProjectRSSFeed=codeplex%3a%2f%2frelease%2fontopreplica</value>
|
||||
</data>
|
||||
</root>
|
|
@ -102,6 +102,11 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AppPaths.cs" />
|
||||
<Compile Include="AppStrings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>AppStrings.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="AspectRatioForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
@ -154,6 +159,7 @@
|
|||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Shell.cs" />
|
||||
<Compile Include="SidePanelContainer.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
@ -201,6 +207,10 @@
|
|||
<Compile Include="WindowSeekers\RestoreWindowSeeker.cs" />
|
||||
<Compile Include="WindowSeekers\TaskWindowSeeker.cs" />
|
||||
<Compile Include="WindowsFormsExtensions.cs" />
|
||||
<EmbeddedResource Include="AppStrings.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>AppStrings.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="SidePanelContainer.resx">
|
||||
<DependentUpon>SidePanelContainer.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
|
|
@ -116,7 +116,7 @@ namespace OnTopReplica {
|
|||
if (e.Success && e.Information != null) {
|
||||
Log.Write("Updated check successful (latest version is {0})", e.Information.LatestVersion);
|
||||
|
||||
if (e.Information.IsNewVersion) {
|
||||
if (e.Information.IsNewVersionAvailable) {
|
||||
Update.ConfirmAndInstall();
|
||||
}
|
||||
}
|
||||
|
|
27
OnTopReplica/Shell.cs
Normal file
27
OnTopReplica/Shell.cs
Normal file
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace OnTopReplica {
|
||||
|
||||
static class Shell {
|
||||
|
||||
/// <summary>
|
||||
/// Executes a filename via Windows shell.
|
||||
/// </summary>
|
||||
/// <param name="filename">Filename to execute.</param>
|
||||
public static void Execute(string filename){
|
||||
if (filename == null)
|
||||
throw new ArgumentNullException();
|
||||
|
||||
Process.Start(new ProcessStartInfo {
|
||||
FileName = filename,
|
||||
UseShellExecute = true
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -23,7 +23,7 @@ namespace OnTopReplica {
|
|||
/// <summary>
|
||||
/// Gets the panel's parent form.
|
||||
/// </summary>
|
||||
protected MainForm ParentForm { get; private set; }
|
||||
protected MainForm ParentMainForm { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Raised when the side panel requests to be closed.
|
||||
|
@ -41,7 +41,7 @@ namespace OnTopReplica {
|
|||
/// </summary>
|
||||
/// <param name="form">Parent form that is embedding the side panel.</param>
|
||||
public virtual void OnFirstShown(MainForm form) {
|
||||
ParentForm = form;
|
||||
ParentMainForm = form;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -54,18 +54,18 @@ namespace OnTopReplica.SidePanels {
|
|||
}
|
||||
|
||||
private void LinkHomepage_clicked(object sender, LinkLabelLinkClickedEventArgs e) {
|
||||
Process.Start("http://ontopreplica.codeplex.com");
|
||||
Shell.Execute(AppStrings.ApplicationWebsite);
|
||||
}
|
||||
|
||||
private void LinkAuthor_clicked(object sender, LinkLabelLinkClickedEventArgs e) {
|
||||
Process.Start("http://lorenz.klopfenstein.net");
|
||||
Shell.Execute(AppStrings.AuthorWebsite);
|
||||
}
|
||||
|
||||
private void LinkCredits_click(object sender, LinkLabelLinkClickedEventArgs e) {
|
||||
var exeDir = Path.GetDirectoryName(Application.ExecutablePath);
|
||||
var filePath = Path.Combine(exeDir, "CREDITS.txt");
|
||||
|
||||
Process.Start(filePath);
|
||||
Shell.Execute(filePath);
|
||||
}
|
||||
|
||||
void UpdateButton_click(object sender, System.EventArgs e) {
|
||||
|
@ -80,7 +80,7 @@ namespace OnTopReplica.SidePanels {
|
|||
//TODO
|
||||
MessageBox.Show("Failed to download update info.");
|
||||
}
|
||||
else if (!e.Information.IsNewVersion) {
|
||||
else if (!e.Information.IsNewVersionAvailable) {
|
||||
Program.Update.DisplayInfo();
|
||||
}
|
||||
|
||||
|
@ -89,11 +89,11 @@ namespace OnTopReplica.SidePanels {
|
|||
}
|
||||
|
||||
private void LinkLicense_click(object sender, LinkLabelLinkClickedEventArgs e) {
|
||||
Process.Start("http://opensource.org/licenses/ms-rl.html");
|
||||
Shell.Execute(AppStrings.MsRlLicenseLink);
|
||||
}
|
||||
|
||||
private void LinkContribute_clicked(object sender, LinkLabelLinkClickedEventArgs e) {
|
||||
Process.Start("http://ontopreplica.codeplex.com/SourceControl/list/changesets");
|
||||
Shell.Execute(AppStrings.LatestCommitsLink);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace OnTopReplica.SidePanels {
|
|||
|
||||
LoadWindowList();
|
||||
|
||||
labelStatus.Text = (ParentForm.MessagePumpManager.Get<GroupSwitchManager>().IsActive) ?
|
||||
labelStatus.Text = (ParentMainForm.MessagePumpManager.Get<GroupSwitchManager>().IsActive) ?
|
||||
Strings.GroupSwitchModeStatusEnabled :
|
||||
Strings.GroupSwitchModeStatusDisabled;
|
||||
}
|
||||
|
|
|
@ -217,7 +217,7 @@ namespace OnTopReplica.SidePanels {
|
|||
/// <param name="regionBounds">Region bounds.</param>
|
||||
protected virtual void OnRegionSet(ThumbnailRegion region) {
|
||||
//Forward region to thumbnail
|
||||
ParentForm.SelectedThumbnailRegion = region;
|
||||
ParentMainForm.SelectedThumbnailRegion = region;
|
||||
|
||||
//Have region, allowed to save
|
||||
buttonSave.Enabled = true;
|
||||
|
@ -231,7 +231,7 @@ namespace OnTopReplica.SidePanels {
|
|||
|
||||
private void Reset_click(object sender, EventArgs e) {
|
||||
Reset();
|
||||
ParentForm.SelectedThumbnailRegion = null;
|
||||
ParentMainForm.SelectedThumbnailRegion = null;
|
||||
}
|
||||
|
||||
private void Delete_click(object sender, EventArgs e) {
|
||||
|
@ -305,9 +305,9 @@ namespace OnTopReplica.SidePanels {
|
|||
var region = ConstructCurrentRegion();
|
||||
region.Relative = !region.Relative; //this must be reversed because the GUI has already switched state when calling ConstructCurrentRegion()
|
||||
if (checkRelative.Checked)
|
||||
region.SwitchToRelative(ParentForm.ThumbnailPanel.ThumbnailOriginalSize);
|
||||
region.SwitchToRelative(ParentMainForm.ThumbnailPanel.ThumbnailOriginalSize);
|
||||
else
|
||||
region.SwitchToAbsolute(ParentForm.ThumbnailPanel.ThumbnailOriginalSize);
|
||||
region.SwitchToAbsolute(ParentMainForm.ThumbnailPanel.ThumbnailOriginalSize);
|
||||
|
||||
//Update GUI
|
||||
SetRegion(region);
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Xml.Serialization;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
|
||||
namespace OnTopReplica.Update {
|
||||
|
@ -13,79 +9,62 @@ namespace OnTopReplica.Update {
|
|||
/// </summary>
|
||||
public class UpdateInformation {
|
||||
|
||||
Version _latestVersion;
|
||||
/// <summary>
|
||||
/// Construct update information from raw data.
|
||||
/// </summary>
|
||||
/// <param name="latestVersion">Latest available version.</param>
|
||||
/// <param name="downloadLink">Direct link to the download page (has URL form).</param>
|
||||
/// <param name="publicationDate">Publication date of latest version, in standard RTF/RSS format.</param>
|
||||
public UpdateInformation(Version latestVersion, string downloadLink, string publicationDate) {
|
||||
LatestVersion = latestVersion;
|
||||
DownloadPage = downloadLink;
|
||||
|
||||
//RSS date formatted as in: <pubDate>Thu, 29 Nov 2012 12:55:04 GMT</pubDate>
|
||||
DateTime parsedPublicationDate;
|
||||
if (DateTime.TryParseExact(publicationDate, "R", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out parsedPublicationDate)) {
|
||||
LatestVersionRelease = parsedPublicationDate;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the latest available version of the software.
|
||||
/// Gets or sets the latest available version of the software.
|
||||
/// </summary>
|
||||
[XmlIgnore]
|
||||
public Version LatestVersion {
|
||||
get {
|
||||
return _latestVersion;
|
||||
}
|
||||
set {
|
||||
_latestVersion = value;
|
||||
}
|
||||
}
|
||||
|
||||
[XmlElement("latestVersion")]
|
||||
public string LatestVersionInternal {
|
||||
get {
|
||||
return _latestVersion.ToString();
|
||||
}
|
||||
set {
|
||||
_latestVersion = new Version(value);
|
||||
}
|
||||
}
|
||||
public Version LatestVersion { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns whether this update information instance represents data about
|
||||
/// a new available version.
|
||||
/// </summary>
|
||||
public bool IsNewVersion {
|
||||
public bool IsNewVersionAvailable {
|
||||
get {
|
||||
var currentVersion = CurrentVersion;
|
||||
|
||||
return (LatestVersion > currentVersion);
|
||||
return (LatestVersion > CurrentVersion);
|
||||
}
|
||||
}
|
||||
|
||||
private Version _currentVersion = null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the currently installed version.
|
||||
/// </summary>
|
||||
public Version CurrentVersion {
|
||||
get {
|
||||
return Assembly.GetExecutingAssembly().GetName().Version;
|
||||
if (_currentVersion == null) {
|
||||
_currentVersion = Assembly.GetExecutingAssembly().GetName().Version;
|
||||
}
|
||||
|
||||
return _currentVersion;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates when the latest version was released.
|
||||
/// </summary>
|
||||
[XmlElement("latestVersionRelease")]
|
||||
public DateTime LatestVersionRelease { get; set; }
|
||||
public DateTime LatestVersionRelease { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the URL of the page that allows the user to download the updated installer.
|
||||
/// </summary>
|
||||
[XmlElement("downloadPage")]
|
||||
public string DownloadPage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the URL of the installer executable.
|
||||
/// </summary>
|
||||
/// <remarks>New after version 3.3.1.</remarks>
|
||||
[XmlElement("downloadInstaller")]
|
||||
public string DownloadInstaller { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes an UpdateInformation object from a stream.
|
||||
/// </summary>
|
||||
public static UpdateInformation Deserialize(Stream source) {
|
||||
var serializer = new XmlSerializer(typeof(UpdateInformation));
|
||||
var info = serializer.Deserialize(source) as UpdateInformation;
|
||||
return info;
|
||||
}
|
||||
public string DownloadPage { get; private set; }
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -34,8 +34,6 @@ namespace OnTopReplica.Update {
|
|||
|
||||
#region Checking
|
||||
|
||||
const string UpdateFeedUrl = "https://ontopreplica.codeplex.com/project/feeds/rss?ProjectRSSFeed=codeplex%3a%2f%2frelease%2fontopreplica";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the latest update information available.
|
||||
/// </summary>
|
||||
|
@ -53,7 +51,7 @@ namespace OnTopReplica.Update {
|
|||
}
|
||||
|
||||
//Build web request
|
||||
_checkRequest = (HttpWebRequest)HttpWebRequest.Create(UpdateFeedUrl);
|
||||
_checkRequest = (HttpWebRequest)HttpWebRequest.Create(AppStrings.UpdateFeed);
|
||||
_checkRequest.AllowAutoRedirect = true;
|
||||
_checkRequest.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
|
||||
_checkRequest.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache);
|
||||
|
@ -90,11 +88,13 @@ namespace OnTopReplica.Update {
|
|||
let title = item.Element("title").Value
|
||||
let match = _versionExtractor.Match(title)
|
||||
where match.Success
|
||||
let versionNumber = match.Groups["version"].Value
|
||||
let versionNumber = new Version(match.Groups["version"].Value)
|
||||
orderby versionNumber descending
|
||||
select new { versionNumber, item.Element("link").Value };
|
||||
select new { Version = versionNumber, Link = item.Element("link").Value, Date = item.Element("pubDate").Value };
|
||||
|
||||
return new UpdateInformation();
|
||||
var lastRelease = releases.FirstOrDefault();
|
||||
|
||||
return new UpdateInformation(lastRelease.Version, lastRelease.Link, lastRelease.Date);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -127,15 +127,11 @@ namespace OnTopReplica.Update {
|
|||
|
||||
#region Updating
|
||||
|
||||
HttpWebRequest _downloadRequest;
|
||||
TaskDialog _updateDialog;
|
||||
bool _updateDownloaded = false;
|
||||
|
||||
/// <summary>
|
||||
/// Asks confirmation for an update and installs the update.
|
||||
/// Asks confirmation for an update and installs the update (if available).
|
||||
/// </summary>
|
||||
public void ConfirmAndInstall() {
|
||||
if (LastInformation == null || !LastInformation.IsNewVersion)
|
||||
if (LastInformation == null || !LastInformation.IsNewVersionAvailable)
|
||||
return;
|
||||
|
||||
AttachedForm.SafeInvoke(new Action(ConfirmAndInstallCore));
|
||||
|
@ -145,7 +141,7 @@ namespace OnTopReplica.Update {
|
|||
/// Core delegate that asks for update confirmation and installs. Must be called from GUI thread.
|
||||
/// </summary>
|
||||
private void ConfirmAndInstallCore() {
|
||||
_updateDialog = new TaskDialog {
|
||||
var updateDialog = new TaskDialog {
|
||||
Title = Strings.UpdateTitle,
|
||||
Instruction = string.Format(Strings.UpdateAvailableInstruction, LastInformation.LatestVersion),
|
||||
Content = Strings.UpdateAvailableContent,
|
||||
|
@ -157,111 +153,11 @@ namespace OnTopReplica.Update {
|
|||
CommonIcon = TaskDialogIcon.Information,
|
||||
ExpandedInformation = string.Format(Strings.UpdateAvailableExpanded, LastInformation.CurrentVersion, LastInformation.LatestVersion),
|
||||
};
|
||||
_updateDialog.ButtonClick += delegate(object sender, ClickEventArgs args) {
|
||||
if (args.ButtonID == (int)Result.OK) {
|
||||
args.PreventClosing = true;
|
||||
|
||||
if (_updateDownloaded) {
|
||||
//Terminate application
|
||||
AttachedForm.Close();
|
||||
|
||||
//Launch updater
|
||||
Process.Start(UpdateInstallerPath);
|
||||
}
|
||||
else {
|
||||
var downDlg = new TaskDialog {
|
||||
Title = Strings.UpdateTitle,
|
||||
Instruction = Strings.UpdateDownloadingInstruction,
|
||||
ShowProgressBar = true,
|
||||
ProgressBarMinRange = 0,
|
||||
ProgressBarMaxRange = 100,
|
||||
ProgressBarPosition = 0,
|
||||
CommonButtons = TaskDialogButton.Cancel
|
||||
};
|
||||
_updateDialog.Navigate(downDlg);
|
||||
|
||||
_downloadRequest = (HttpWebRequest)HttpWebRequest.Create(LastInformation.DownloadInstaller);
|
||||
_downloadRequest.BeginGetResponse(DownloadAsyncCallback, null);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
_updateDialog.Show(AttachedForm);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the target filename used when downloading the update from the Internet.
|
||||
/// </summary>
|
||||
private string UpdateInstallerPath {
|
||||
get {
|
||||
var downloadPath = Native.FilesystemMethods.DownloadsPath;
|
||||
|
||||
string versionName = (LastInformation != null) ?
|
||||
LastInformation.LatestVersion.ToString() : string.Empty;
|
||||
string filename = string.Format("OnTopReplica-Update-{0}.exe", versionName);
|
||||
|
||||
return Path.Combine(downloadPath, filename);
|
||||
if (updateDialog.Show(AttachedForm).CommonButton == Result.OK) {
|
||||
Shell.Execute(LastInformation.DownloadPage);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles background downloading.
|
||||
/// </summary>
|
||||
private void DownloadAsyncCallback(IAsyncResult result) {
|
||||
if (_downloadRequest == null || _updateDialog == null)
|
||||
return;
|
||||
|
||||
try {
|
||||
var response = _downloadRequest.EndGetResponse(result);
|
||||
var responseStream = response.GetResponseStream();
|
||||
long total = response.ContentLength;
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
|
||||
using (var stream = new FileStream(UpdateInstallerPath, FileMode.Create)) {
|
||||
int readTotal = 0;
|
||||
while (true) {
|
||||
int read = responseStream.Read(buffer, 0, buffer.Length);
|
||||
readTotal += read;
|
||||
|
||||
if (read <= 0) //EOF
|
||||
break;
|
||||
|
||||
stream.Write(buffer, 0, read);
|
||||
|
||||
_updateDialog.Content = string.Format(Strings.UpdateDownloadingContent, readTotal, total);
|
||||
_updateDialog.ProgressBarPosition = (int)((readTotal * 100.0) / total);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
DownloadShowError(ex.Message);
|
||||
return;
|
||||
}
|
||||
|
||||
_updateDownloaded = true;
|
||||
|
||||
var okDlg = new TaskDialog {
|
||||
Title = Strings.UpdateTitle,
|
||||
Instruction = Strings.UpdateReadyInstruction,
|
||||
Content = string.Format(Strings.UpdateReadyContent, LastInformation.LatestVersion),
|
||||
UseCommandLinks = true,
|
||||
CommonButtons = TaskDialogButton.Cancel,
|
||||
CustomButtons = new CustomButton[] {
|
||||
new CustomButton(Result.OK, Strings.UpdateReadyCommandOk)
|
||||
}
|
||||
};
|
||||
_updateDialog.Navigate(okDlg);
|
||||
}
|
||||
|
||||
private void DownloadShowError(string msg) {
|
||||
if (_updateDialog == null)
|
||||
return;
|
||||
|
||||
_updateDialog.ProgressBarState = WindowsFormsAero.ProgressBar.States.Error;
|
||||
_updateDialog.Content = msg;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Displays some information about the current installation and available updates.
|
||||
/// </summary>
|
||||
|
@ -285,8 +181,9 @@ namespace OnTopReplica.Update {
|
|||
Footer = string.Format(Strings.UpdateInfoFooter, LastInformation.LatestVersionRelease.ToLongDateString())
|
||||
};
|
||||
dlg.HyperlinkClick += delegate(object sender, HyperlinkEventArgs args) {
|
||||
Process.Start("http://ontopreplica.codeplex.com");
|
||||
Shell.Execute(AppStrings.ApplicationWebsite);
|
||||
};
|
||||
|
||||
dlg.Show(AttachedForm);
|
||||
}
|
||||
|
||||
|
|
|
@ -113,16 +113,6 @@ namespace OnTopReplica {
|
|||
}
|
||||
|
||||
return sb.ToString();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(_title)) {
|
||||
return string.Format("#{0}", _handle.ToInt64());
|
||||
}
|
||||
else if (string.IsNullOrWhiteSpace(_class)) {
|
||||
return string.Format("#{0} ({1})", _handle.ToInt64(), _title);
|
||||
}
|
||||
else {
|
||||
return string.Format("#{0} ({1}, class {2})", _handle.ToInt64(), _title, _class);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Equals(object obj) {
|
||||
|
|
Loading…
Reference in a new issue