UI: Help menu (about, report bug, check for updates)

This commit is contained in:
Sour 2019-03-14 12:34:29 -04:00
parent bceb0394ef
commit 58af2b136f
24 changed files with 1808 additions and 22 deletions

1
.gitignore vendored
View file

@ -188,4 +188,3 @@ Libretro/*
Docs/*
Lua/*
TestHelper/*
UpdateHelper/*

View file

@ -557,7 +557,7 @@
<Control ID="labelProductName">Mesen-S</Control>
<Control ID="labelCopyright">© 2019 M. Bibaud (aka Sour)</Control>
<Control ID="lblWebsite">Website:</Control>
<Control ID="lblLink">www.mesen.ca</Control>
<Control ID="lblLink">www.mesen.ca/snes/</Control>
<Control ID="labelVersion">Version:</Control>
<Control ID="lblBuildDateLabel">Build Date:</Control>
<Control ID="lblDonate">If you want to support Mesen-S, please consider donating.&#13;Thank you for your support!</Control>

43
UI/Forms/frmAbout.cs Normal file
View file

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Mesen.GUI.Forms
{
partial class frmAbout : BaseForm
{
public frmAbout()
{
InitializeComponent();
lblMesenVersion.Text = EmuApi.GetMesenVersion().ToString(3);
Version ver = Assembly.GetEntryAssembly().GetName().Version;
DateTime buildTime = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddDays(ver.Build).AddSeconds(ver.Revision * 2);
lblBuildDate.Text = buildTime.ToShortDateString() + " " + buildTime.ToShortTimeString();
#if AUTOBUILD
string devVersion = ResourceManager.ReadZippedResource("DevBuild.txt");
if(devVersion != null) {
lblMesenVersion.Text = devVersion;
}
#endif
}
private void lblLink_Click(object sender, EventArgs e)
{
Process.Start("https://www.mesen.ca/snes/");
}
private void picDonate_Click(object sender, EventArgs e)
{
Process.Start("https://www.mesen.ca/Donate.php?l=" + ResourceHelper.GetLanguageCode());
}
}
}

309
UI/Forms/frmAbout.designer.cs generated Normal file
View file

@ -0,0 +1,309 @@
namespace Mesen.GUI.Forms
{
partial class frmAbout
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose(bool disposing)
{
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form 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()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmAbout));
this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
this.flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel();
this.lblBuildDateLabel = new System.Windows.Forms.Label();
this.lblBuildDate = new System.Windows.Forms.Label();
this.logoPictureBox = new System.Windows.Forms.PictureBox();
this.labelProductName = new System.Windows.Forms.Label();
this.labelCopyright = new System.Windows.Forms.Label();
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
this.lblWebsite = new System.Windows.Forms.Label();
this.lblLink = new System.Windows.Forms.Label();
this.okButton = new System.Windows.Forms.Button();
this.picDonate = new System.Windows.Forms.PictureBox();
this.lblDonate = new System.Windows.Forms.Label();
this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel();
this.labelVersion = new System.Windows.Forms.Label();
this.lblMesenVersion = new System.Windows.Forms.Label();
this.tableLayoutPanel.SuspendLayout();
this.flowLayoutPanel3.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).BeginInit();
this.flowLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picDonate)).BeginInit();
this.flowLayoutPanel2.SuspendLayout();
this.SuspendLayout();
//
// tableLayoutPanel
//
this.tableLayoutPanel.AutoSize = true;
this.tableLayoutPanel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.tableLayoutPanel.ColumnCount = 2;
this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 84F));
this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel.Controls.Add(this.flowLayoutPanel3, 1, 2);
this.tableLayoutPanel.Controls.Add(this.logoPictureBox, 0, 0);
this.tableLayoutPanel.Controls.Add(this.labelProductName, 1, 0);
this.tableLayoutPanel.Controls.Add(this.labelCopyright, 1, 3);
this.tableLayoutPanel.Controls.Add(this.flowLayoutPanel1, 1, 4);
this.tableLayoutPanel.Controls.Add(this.okButton, 1, 6);
this.tableLayoutPanel.Controls.Add(this.picDonate, 0, 6);
this.tableLayoutPanel.Controls.Add(this.lblDonate, 0, 5);
this.tableLayoutPanel.Controls.Add(this.flowLayoutPanel2, 1, 1);
this.tableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel.Location = new System.Drawing.Point(5, 5);
this.tableLayoutPanel.Name = "tableLayoutPanel";
this.tableLayoutPanel.RowCount = 8;
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel.Size = new System.Drawing.Size(337, 151);
this.tableLayoutPanel.TabIndex = 0;
//
// flowLayoutPanel3
//
this.flowLayoutPanel3.Controls.Add(this.lblBuildDateLabel);
this.flowLayoutPanel3.Controls.Add(this.lblBuildDate);
this.flowLayoutPanel3.Location = new System.Drawing.Point(84, 38);
this.flowLayoutPanel3.Margin = new System.Windows.Forms.Padding(0, 3, 0, 0);
this.flowLayoutPanel3.Name = "flowLayoutPanel3";
this.flowLayoutPanel3.Size = new System.Drawing.Size(250, 15);
this.flowLayoutPanel3.TabIndex = 32;
//
// lblBuildDateLabel
//
this.lblBuildDateLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblBuildDateLabel.AutoSize = true;
this.lblBuildDateLabel.Location = new System.Drawing.Point(6, 0);
this.lblBuildDateLabel.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
this.lblBuildDateLabel.Name = "lblBuildDateLabel";
this.lblBuildDateLabel.Size = new System.Drawing.Size(59, 13);
this.lblBuildDateLabel.TabIndex = 0;
this.lblBuildDateLabel.Text = "Build Date:";
this.lblBuildDateLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// lblBuildDate
//
this.lblBuildDate.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblBuildDate.AutoSize = true;
this.lblBuildDate.Location = new System.Drawing.Point(71, 0);
this.lblBuildDate.Name = "lblBuildDate";
this.lblBuildDate.Size = new System.Drawing.Size(65, 13);
this.lblBuildDate.TabIndex = 1;
this.lblBuildDate.Text = "<build date>";
//
// logoPictureBox
//
this.logoPictureBox.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.logoPictureBox.Image = global::Mesen.GUI.Properties.Resources.MesenSIcon;
this.logoPictureBox.Location = new System.Drawing.Point(12, 12);
this.logoPictureBox.Margin = new System.Windows.Forms.Padding(4, 12, 0, 5);
this.logoPictureBox.Name = "logoPictureBox";
this.tableLayoutPanel.SetRowSpan(this.logoPictureBox, 5);
this.logoPictureBox.Size = new System.Drawing.Size(64, 65);
this.logoPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.logoPictureBox.TabIndex = 12;
this.logoPictureBox.TabStop = false;
//
// labelProductName
//
this.labelProductName.Dock = System.Windows.Forms.DockStyle.Fill;
this.labelProductName.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelProductName.Location = new System.Drawing.Point(90, 0);
this.labelProductName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
this.labelProductName.Name = "labelProductName";
this.labelProductName.Size = new System.Drawing.Size(244, 17);
this.labelProductName.TabIndex = 19;
this.labelProductName.Text = "Mesen-S";
this.labelProductName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// labelCopyright
//
this.labelCopyright.Dock = System.Windows.Forms.DockStyle.Fill;
this.labelCopyright.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelCopyright.Location = new System.Drawing.Point(90, 53);
this.labelCopyright.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
this.labelCopyright.Name = "labelCopyright";
this.labelCopyright.Size = new System.Drawing.Size(244, 17);
this.labelCopyright.TabIndex = 21;
this.labelCopyright.Text = "© 2019 M. Bibaud (aka Sour)";
this.labelCopyright.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// flowLayoutPanel1
//
this.flowLayoutPanel1.Controls.Add(this.lblWebsite);
this.flowLayoutPanel1.Controls.Add(this.lblLink);
this.flowLayoutPanel1.Location = new System.Drawing.Point(84, 70);
this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel1.Name = "flowLayoutPanel1";
this.flowLayoutPanel1.Size = new System.Drawing.Size(236, 18);
this.flowLayoutPanel1.TabIndex = 26;
//
// lblWebsite
//
this.lblWebsite.AutoSize = true;
this.lblWebsite.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblWebsite.Location = new System.Drawing.Point(6, 0);
this.lblWebsite.Margin = new System.Windows.Forms.Padding(6, 0, 0, 0);
this.lblWebsite.Name = "lblWebsite";
this.lblWebsite.Size = new System.Drawing.Size(61, 16);
this.lblWebsite.TabIndex = 25;
this.lblWebsite.Text = "Website:";
this.lblWebsite.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// lblLink
//
this.lblLink.AutoSize = true;
this.lblLink.Cursor = System.Windows.Forms.Cursors.Hand;
this.lblLink.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblLink.ForeColor = System.Drawing.Color.Blue;
this.lblLink.Location = new System.Drawing.Point(67, 2);
this.lblLink.Margin = new System.Windows.Forms.Padding(0, 2, 3, 0);
this.lblLink.Name = "lblLink";
this.lblLink.Size = new System.Drawing.Size(112, 13);
this.lblLink.TabIndex = 26;
this.lblLink.Text = "www.mesen.ca/snes/";
this.lblLink.Click += new System.EventHandler(this.lblLink_Click);
//
// okButton
//
this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.okButton.Location = new System.Drawing.Point(259, 122);
this.okButton.Name = "okButton";
this.okButton.Size = new System.Drawing.Size(75, 23);
this.okButton.TabIndex = 24;
this.okButton.Text = "&OK";
//
// picDonate
//
this.picDonate.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.picDonate.Cursor = System.Windows.Forms.Cursors.Hand;
this.picDonate.Image = ((System.Drawing.Image)(resources.GetObject("picDonate.Image")));
this.picDonate.Location = new System.Drawing.Point(3, 122);
this.picDonate.Name = "picDonate";
this.picDonate.Size = new System.Drawing.Size(78, 22);
this.picDonate.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.picDonate.TabIndex = 29;
this.picDonate.TabStop = false;
this.picDonate.Click += new System.EventHandler(this.picDonate_Click);
//
// lblDonate
//
this.lblDonate.AutoSize = true;
this.tableLayoutPanel.SetColumnSpan(this.lblDonate, 2);
this.lblDonate.Location = new System.Drawing.Point(0, 93);
this.lblDonate.Margin = new System.Windows.Forms.Padding(0, 5, 0, 0);
this.lblDonate.Name = "lblDonate";
this.lblDonate.Size = new System.Drawing.Size(281, 26);
this.lblDonate.TabIndex = 30;
this.lblDonate.Text = "If you want to support Mesen-S, please consider donating.\r\nThank you for your sup" +
"port!";
//
// flowLayoutPanel2
//
this.flowLayoutPanel2.Controls.Add(this.labelVersion);
this.flowLayoutPanel2.Controls.Add(this.lblMesenVersion);
this.flowLayoutPanel2.Location = new System.Drawing.Point(84, 20);
this.flowLayoutPanel2.Margin = new System.Windows.Forms.Padding(0, 3, 0, 0);
this.flowLayoutPanel2.Name = "flowLayoutPanel2";
this.flowLayoutPanel2.Size = new System.Drawing.Size(250, 15);
this.flowLayoutPanel2.TabIndex = 31;
//
// labelVersion
//
this.labelVersion.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.labelVersion.AutoSize = true;
this.labelVersion.Location = new System.Drawing.Point(6, 0);
this.labelVersion.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
this.labelVersion.Name = "labelVersion";
this.labelVersion.Size = new System.Drawing.Size(45, 13);
this.labelVersion.TabIndex = 0;
this.labelVersion.Text = "Version:";
this.labelVersion.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// lblMesenVersion
//
this.lblMesenVersion.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblMesenVersion.AutoSize = true;
this.lblMesenVersion.Location = new System.Drawing.Point(57, 0);
this.lblMesenVersion.Name = "lblMesenVersion";
this.lblMesenVersion.Size = new System.Drawing.Size(53, 13);
this.lblMesenVersion.TabIndex = 1;
this.lblMesenVersion.Text = "<version>";
//
// frmAbout
//
this.AcceptButton = this.okButton;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.AutoSize = true;
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.CancelButton = this.okButton;
this.ClientSize = new System.Drawing.Size(347, 161);
this.Controls.Add(this.tableLayoutPanel);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "frmAbout";
this.Padding = new System.Windows.Forms.Padding(5);
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "About - Mesen";
this.tableLayoutPanel.ResumeLayout(false);
this.tableLayoutPanel.PerformLayout();
this.flowLayoutPanel3.ResumeLayout(false);
this.flowLayoutPanel3.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).EndInit();
this.flowLayoutPanel1.ResumeLayout(false);
this.flowLayoutPanel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.picDonate)).EndInit();
this.flowLayoutPanel2.ResumeLayout(false);
this.flowLayoutPanel2.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel;
private System.Windows.Forms.PictureBox logoPictureBox;
private System.Windows.Forms.Label labelProductName;
private System.Windows.Forms.Label labelVersion;
private System.Windows.Forms.Label labelCopyright;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
private System.Windows.Forms.Label lblWebsite;
private System.Windows.Forms.Label lblLink;
private System.Windows.Forms.Button okButton;
private System.Windows.Forms.PictureBox picDonate;
private System.Windows.Forms.Label lblDonate;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2;
private System.Windows.Forms.Label lblMesenVersion;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel3;
private System.Windows.Forms.Label lblBuildDateLabel;
private System.Windows.Forms.Label lblBuildDate;
}
}

164
UI/Forms/frmAbout.resx Normal file
View file

@ -0,0 +1,164 @@
<?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>
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="picDonate.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAE4AAAAWCAYAAABud6qHAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
vAAADrwBlbxySQAAABl0RVh0U29mdHdhcmUAcGFpbnQubmV0IDQuMC4xMkMEa+wAAAfNSURBVFhH7Zd5
UNXXFcdJOpmkTiZjmrbWmrSTGStVNKg8UFlEERQQRWRcUJRNeIAIuLK4VxvFpETABR7wFB4IAiou4BpH
MWJdSmw0uIC4b4ktChIV8X56f7+HJG+E1JD2Lzwzn3nv3nvOufd+5945v2vWmlEw7hfCMNRc5Lnq2DQS
8r06EGMg1w2x08ddZGjMmyX57ybSrLQciYilfDlc2wV11dBYB08fdgye1EJtJVwugrIliGNxUSK1/8hm
eVo36ZAgji55wq3PoeEaPLrTsWm4DrcOIg7Pvy7SNG7NMpmaKtqpTx/xry+h/tIrnqPcuG+OI/bOuCVS
+2ma5TKacj3F/uAn3Dksj+lXkjOvMEFqcvMAotCrXmT0+70qmloIijRxfJ0E3x6De+3j6d1yaq+U8W3N
YZV7kvtXy2i8U96q//8DIdevzPfsZ+zjRzkWhdjm1gczs9fMREYfc7YOR1TpEXfkfW4nxw4XYuE1l7cG
hfHekAh+PXQG/cbHsFav437N3lZj/pc03T7IuX9sZ0OunrsXdrfq87M5+xnk2CKSur9pJvRWekpdEOeS
EbdKJHLSdlBQmEFXl0hC5n9MXr6O3Lw0JkQvpatzJHtLsmi6Wdri+++qHVRVFPHg0k6THD+k4eouLp0u
4uGVXSb9Sh4l9u75YpOctdU7mDjzLwTHf8w3cuyH/Yr/w8ttz/XSVCxG7LBH6KxWm5Fpjdg9Qpbd6Ygr
eYibctJ2sCI5kTdstJTt0/PsRrHKwT2ZdPeIZn7CKhpqttJ0vZisnHU4+sXRd9xcbH1j+Wz9atVXyZGi
S2aIfzxr05Nx1y6UJ3Yus5ev5G5lgTq+vzSTkaEL1VgbH3mapZ+SVxlzCZrP2/bhdBseydy/Jsj+LWRm
rcUpMF7195BxX5XntMz1k6mWN7IsAFEyDHRWmKG3kcK5IvaMRJycJ8XLR1wt/Ek8vJhP+IJl8npGUH0i
q6X/dJkeq/FzmBa7lLoLeeRtSuFdx+m4B8ezTpeIw5R5vOMQzrbCtdw/n4fvrMWYWYWoMbqM1bhKvw/d
ozi0Wyfj89X/XZ1nkJKaiJ3vPLoMi+BahYHrkolRi9TY4UFxbN+yDv3GJONcIfEsXrWS96Wg3hELeFS9
2WTtL8XlXMSJWbKySo2kVug0UjjlxJU4GSkdZlT10gYpoHR+SW5UbMB1WixO/jHcPv197KmDaXw0diaR
i5ZSfyEb89HR8gRGcb48g6aaXPYUp9BpUCgBcxZx5ZRebjpGFeNMmY6nNTksT1xBT89oju1br+Z7VGXg
cbWB2q+z8JcxilA1JzJ5JjdmMCTyOxm7a0sKTbLdY1Q0nWxDuSrzKnO7BMbwukZL/fnslvW9FDXSvzzc
qE2zTsYTl6mBnfamlDrDcVlBKv8mi4ZcdHW6FDOzTc4dWUNvr2jC4hbI6p2m9jVVZ5C9cRXv2IeRZ0jg
1IFk9Sp7hspT3RxXVrJa3dy46bGc2JeE+agotLELeHBWp46PDIlhyNTZXPxiDVXl65kUPV/6zKCbcxi/
HKRFM24mtytSVd/w+EVYjo3m5P4kKsvW0HlwOG8N1OI+ba5Kd3dZsBxDqa805m4TZa8X5Z6VvctTxu7h
L+qjCpdhBcXWEpsXUZz2jYLDvogj8iS2wfHcIClQKLqVfjw55M/jQ4EcypmOxjsC+7FTqd7qxz/z/aRw
IfiEaHl6OJBG6TMzJkLtS1nmS2n6NN621ZKb6CfH/NW8XYaGMVUbSN1+Pzz8w3jdOoQNK8azN90fS08t
AaEB1O4zrsFuQhjDJwVxbYc/lYV+dLYPpodbMKXrJlKUNJnUFX7sWOMj5zbmbgsOTZJ7lu/z7YNa12Sb
PGhG4fpDUW/YYtkunhVZkr10mHptBntNYsKUcYydPJ7erlP4k8tUShIG01jYl4b8fvRx9eWPTv58GuPK
wigPfuMQiP0YH25laUiKG8Gv7AP5e4qdmrdSN5A3rINZHO2uth29JvKaJoRP5rkxXTuGTgOnsWyWG99t
7qeOK+1BoydRsmoI93KscPaewLt2QSTMdScuchRO3j5qbiHX+3zt7aLQAtKkcPIZMYrsj6CgZ7to2tyL
NXFOWHv4mDAr1J2TydY8zuvV4vvlGg2eE7z5rUMAHwz1Y6qfJ9W6fqrPqjnOavtyRl/Vd9dKO4Z4jad0
pa2xvcKO7s5T+NBpKnPC3Bkt8xiWOPKkOb8S29k2kIgQD+5l9+Fcan88J3rTZXAAPVymkDDbhXtZfVrW
0m70fZHP0/5mYp3GnI1KQnPJn9uFsvH6HAsTlD6x2dRPaTfk9qLW0Jv7ku82KZv+PofSftYc05jfk4e5
FjyVv0q7Sf7WybxK3CPpp+RpzDOOKSixypjSr8wjZJ/yX+l7YLCQAn/v2242S43S+xs/gBWTCkZS6GAs
Cq9oHeX7beMAhF7zgSqaYsp1FZtsb3DAB74Ih6OvMOGIVgrngdhgc1RkWb/XLJvRRLqVu8hzusXRSDi7
WiIf/a+AM4lwMAhhGFwsdDbvN8tlaiJNYy0MjnUckmX5UgFcK+nYVG+Czycjsh3K2hTtuYn1lt1E4QgL
CuRnwKklMsFu5Kc68k3UMbhXAVW58orOgGz5Stjh/IcXruePmSh1fVOkD/iE9AGykgzsQCj7le/3TDvL
lur5gpmZ/QdCEW0eU8qyCQAAAABJRU5ErkJggg==
</value>
</data>
</root>

View file

@ -100,8 +100,8 @@
this.mnuBilinearInterpolation = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripSeparator();
this.mnuAudioConfig = new System.Windows.Forms.ToolStripMenuItem();
this.mnuVideoConfig = new System.Windows.Forms.ToolStripMenuItem();
this.mnuInputConfig = new System.Windows.Forms.ToolStripMenuItem();
this.mnuVideoConfig = new System.Windows.Forms.ToolStripMenuItem();
this.mnuEmulationConfig = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator();
this.mnuPreferences = new System.Windows.Forms.ToolStripMenuItem();
@ -299,7 +299,7 @@
this.mnuShowFPS});
this.mnuEmulationSpeed.Image = global::Mesen.GUI.Properties.Resources.Speed;
this.mnuEmulationSpeed.Name = "mnuEmulationSpeed";
this.mnuEmulationSpeed.Size = new System.Drawing.Size(152, 22);
this.mnuEmulationSpeed.Size = new System.Drawing.Size(135, 22);
this.mnuEmulationSpeed.Text = "Speed";
this.mnuEmulationSpeed.DropDownOpening += new System.EventHandler(this.mnuEmulationSpeed_DropDownOpening);
//
@ -387,7 +387,7 @@
this.mnuFullscreen});
this.mnuVideoScale.Image = global::Mesen.GUI.Properties.Resources.Fullscreen;
this.mnuVideoScale.Name = "mnuVideoScale";
this.mnuVideoScale.Size = new System.Drawing.Size(152, 22);
this.mnuVideoScale.Size = new System.Drawing.Size(135, 22);
this.mnuVideoScale.Text = "Video Size";
this.mnuVideoScale.DropDownOpening += new System.EventHandler(this.mnuVideoScale_DropDownOpening);
//
@ -473,7 +473,7 @@
this.mnuBilinearInterpolation});
this.mnuVideoFilter.Image = global::Mesen.GUI.Properties.Resources.VideoFilter;
this.mnuVideoFilter.Name = "mnuVideoFilter";
this.mnuVideoFilter.Size = new System.Drawing.Size(152, 22);
this.mnuVideoFilter.Size = new System.Drawing.Size(135, 22);
this.mnuVideoFilter.Text = "Video Filter";
this.mnuVideoFilter.DropDownOpening += new System.EventHandler(this.mnuVideoFilter_DropDownOpening);
//
@ -654,50 +654,50 @@
// toolStripMenuItem4
//
this.toolStripMenuItem4.Name = "toolStripMenuItem4";
this.toolStripMenuItem4.Size = new System.Drawing.Size(149, 6);
this.toolStripMenuItem4.Size = new System.Drawing.Size(132, 6);
//
// mnuAudioConfig
//
this.mnuAudioConfig.Image = global::Mesen.GUI.Properties.Resources.Audio;
this.mnuAudioConfig.Name = "mnuAudioConfig";
this.mnuAudioConfig.Size = new System.Drawing.Size(152, 22);
this.mnuAudioConfig.Size = new System.Drawing.Size(135, 22);
this.mnuAudioConfig.Text = "Audio";
this.mnuAudioConfig.Click += new System.EventHandler(this.mnuAudioConfig_Click);
//
// mnuVideoConfig
//
this.mnuVideoConfig.Image = global::Mesen.GUI.Properties.Resources.VideoOptions;
this.mnuVideoConfig.Name = "mnuVideoConfig";
this.mnuVideoConfig.Size = new System.Drawing.Size(152, 22);
this.mnuVideoConfig.Text = "Video";
this.mnuVideoConfig.Click += new System.EventHandler(this.mnuVideoConfig_Click);
//
// mnuInputConfig
//
this.mnuInputConfig.Image = global::Mesen.GUI.Properties.Resources.Controller;
this.mnuInputConfig.Name = "mnuInputConfig";
this.mnuInputConfig.Size = new System.Drawing.Size(152, 22);
this.mnuInputConfig.Size = new System.Drawing.Size(135, 22);
this.mnuInputConfig.Text = "Input";
this.mnuInputConfig.Click += new System.EventHandler(this.mnuInputConfig_Click);
//
// mnuVideoConfig
//
this.mnuVideoConfig.Image = global::Mesen.GUI.Properties.Resources.VideoOptions;
this.mnuVideoConfig.Name = "mnuVideoConfig";
this.mnuVideoConfig.Size = new System.Drawing.Size(135, 22);
this.mnuVideoConfig.Text = "Video";
this.mnuVideoConfig.Click += new System.EventHandler(this.mnuVideoConfig_Click);
//
// mnuEmulationConfig
//
this.mnuEmulationConfig.Image = global::Mesen.GUI.Properties.Resources.DipSwitches;
this.mnuEmulationConfig.Name = "mnuEmulationConfig";
this.mnuEmulationConfig.Size = new System.Drawing.Size(152, 22);
this.mnuEmulationConfig.Size = new System.Drawing.Size(135, 22);
this.mnuEmulationConfig.Text = "Emulation";
this.mnuEmulationConfig.Click += new System.EventHandler(this.mnuEmulationConfig_Click);
//
// toolStripMenuItem3
//
this.toolStripMenuItem3.Name = "toolStripMenuItem3";
this.toolStripMenuItem3.Size = new System.Drawing.Size(149, 6);
this.toolStripMenuItem3.Size = new System.Drawing.Size(132, 6);
//
// mnuPreferences
//
this.mnuPreferences.Image = global::Mesen.GUI.Properties.Resources.Settings;
this.mnuPreferences.Name = "mnuPreferences";
this.mnuPreferences.Size = new System.Drawing.Size(152, 22);
this.mnuPreferences.Size = new System.Drawing.Size(135, 22);
this.mnuPreferences.Text = "Preferences";
this.mnuPreferences.Click += new System.EventHandler(this.mnuPreferences_Click);
//
@ -794,13 +794,13 @@
this.mnuHelp.Name = "mnuHelp";
this.mnuHelp.Size = new System.Drawing.Size(44, 20);
this.mnuHelp.Text = "Help";
this.mnuHelp.Visible = false;
//
// mnuCheckForUpdates
//
this.mnuCheckForUpdates.Name = "mnuCheckForUpdates";
this.mnuCheckForUpdates.Size = new System.Drawing.Size(170, 22);
this.mnuCheckForUpdates.Text = "Check for updates";
this.mnuCheckForUpdates.Click += new System.EventHandler(this.mnuCheckForUpdates_Click);
//
// toolStripMenuItem20
//
@ -813,6 +813,7 @@
this.mnuReportBug.Name = "mnuReportBug";
this.mnuReportBug.Size = new System.Drawing.Size(170, 22);
this.mnuReportBug.Text = "Report a bug";
this.mnuReportBug.Click += new System.EventHandler(this.mnuReportBug_Click);
//
// toolStripMenuItem5
//
@ -825,6 +826,7 @@
this.mnuAbout.Name = "mnuAbout";
this.mnuAbout.Size = new System.Drawing.Size(170, 22);
this.mnuAbout.Text = "About";
this.mnuAbout.Click += new System.EventHandler(this.mnuAbout_Click);
//
// pnlRenderer
//

View file

@ -3,10 +3,12 @@ using Mesen.GUI.Config.Shortcuts;
using Mesen.GUI.Debugger;
using Mesen.GUI.Emulation;
using Mesen.GUI.Forms.Config;
using Mesen.GUI.Updates;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
@ -282,6 +284,23 @@ namespace Mesen.GUI.Forms
new frmLogWindow().Show();
}
private void mnuCheckForUpdates_Click(object sender, EventArgs e)
{
UpdateHelper.CheckForUpdates(false);
}
private void mnuReportBug_Click(object sender, EventArgs e)
{
Process.Start("https://www.mesen.ca/snes/ReportBug.php");
}
private void mnuAbout_Click(object sender, EventArgs e)
{
using(frmAbout frm = new frmAbout()) {
frm.ShowDialog(this);
}
}
private void mnuFile_DropDownOpening(object sender, EventArgs e)
{
mnuRecentFiles.DropDownItems.Clear();

View file

@ -19,6 +19,14 @@ namespace Mesen.GUI
[DllImport(DllPath)] public static extern void InitDll();
[DllImport(DllPath, EntryPoint = "GetMesenVersion")] private static extern UInt32 GetMesenVersionWrapper();
public static Version GetMesenVersion()
{
UInt32 version = GetMesenVersionWrapper();
UInt32 revision = version & 0xFF;
UInt32 minor = (version >> 8) & 0xFF;
UInt32 major = (version >> 16) & 0xFFFF;
return new Version((int)major, (int)minor, (int)revision, 0);
}
[DllImport(DllPath)] public static extern IntPtr RegisterNotificationCallback(NotificationListener.NotificationCallback callback);
[DllImport(DllPath)] public static extern void UnregisterNotificationCallback(IntPtr notificationListener);

View file

@ -580,6 +580,16 @@ namespace Mesen.GUI.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap MesenSIcon {
get {
object obj = ResourceManager.GetObject("MesenSIcon", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>

View file

@ -448,4 +448,7 @@
<data name="Zoom2x" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Zoom2x.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="MesenSIcon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\MesenSIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

View file

@ -98,7 +98,7 @@ namespace Mesen.GUI
string outputFilename = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), entry.Name.Replace(suffix, ""));
ExtractFile(entry, outputFilename);
} else if(entry.Name == "MesenUpdater.exe") {
string outputFilename = Path.Combine(ConfigManager.HomeFolder, entry.Name);
string outputFilename = Path.Combine(ConfigManager.HomeFolder, "Resources", entry.Name);
ExtractFile(entry, outputFilename);
} else if(entry.Name == "Font.24.spritefont" || entry.Name == "Font.64.spritefont" || entry.Name == "LICENSE.txt" || entry.Name == "PixelFont.ttf") {
string outputFilename = Path.Combine(ConfigManager.HomeFolder, "Resources", entry.Name);

BIN
UI/Resources/MesenSIcon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -542,6 +542,12 @@
</Compile>
<Compile Include="Forms\Config\KeyPresets.cs" />
<Compile Include="Forms\EntityBinder.cs" />
<Compile Include="Forms\frmAbout.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\frmAbout.designer.cs">
<DependentUpon>frmAbout.cs</DependentUpon>
</Compile>
<Compile Include="Forms\frmLogWindow.cs">
<SubType>Form</SubType>
</Compile>
@ -560,6 +566,18 @@
<Compile Include="Forms\frmSelectRom.designer.cs">
<DependentUpon>frmSelectRom.cs</DependentUpon>
</Compile>
<Compile Include="Updates\frmDownloadProgress.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Updates\frmDownloadProgress.designer.cs">
<DependentUpon>frmDownloadProgress.cs</DependentUpon>
</Compile>
<Compile Include="Updates\frmUpdatePrompt.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Updates\frmUpdatePrompt.designer.cs">
<DependentUpon>frmUpdatePrompt.cs</DependentUpon>
</Compile>
<Compile Include="Forms\MesenMsgBox.cs" />
<Compile Include="Forms\OpenSaveFileDialogExtensions.cs" />
<Compile Include="Forms\ResourceHelper.cs" />
@ -580,7 +598,9 @@
<Compile Include="Utilities\ArchiveHelper.cs" />
<Compile Include="Utilities\HexConverter.cs" />
<Compile Include="Utilities\Md5Helper.cs" />
<Compile Include="Updates\UpdateHelper.cs" />
<Compile Include="Utilities\XmlColor.cs" />
<None Include="Resources\MesenSIcon.png" />
<None Include="app.manifest" />
<EmbeddedResource Include="Controls\ctrlPathSelection.resx">
<DependentUpon>ctrlPathSelection.cs</DependentUpon>
@ -708,6 +728,9 @@
<EmbeddedResource Include="Forms\Config\frmVideoConfig.resx">
<DependentUpon>frmVideoConfig.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\frmAbout.resx">
<DependentUpon>frmAbout.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\frmLogWindow.resx">
<DependentUpon>frmLogWindow.cs</DependentUpon>
</EmbeddedResource>
@ -717,6 +740,12 @@
<EmbeddedResource Include="Forms\frmSelectRom.resx">
<DependentUpon>frmSelectRom.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Updates\frmDownloadProgress.resx">
<DependentUpon>frmDownloadProgress.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Updates\frmUpdatePrompt.resx">
<DependentUpon>frmUpdatePrompt.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>

View file

@ -0,0 +1,50 @@
using Mesen.GUI.Forms;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
namespace Mesen.GUI.Updates
{
public static class UpdateHelper
{
public static void CheckForUpdates(bool silent)
{
Task.Run(() => {
try {
using(var client = new WebClient()) {
XmlDocument xmlDoc = new XmlDocument();
string platform = Program.IsMono ? "linux" : "win";
xmlDoc.LoadXml(client.DownloadString("https://www.mesen.ca/snes/Services/GetLatestVersion.php?v=" + EmuApi.GetMesenVersion().ToString(3) + "&p=" + platform + "&l=" + ResourceHelper.GetLanguageCode()));
Version currentVersion = EmuApi.GetMesenVersion();
Version latestVersion = new Version(xmlDoc.SelectSingleNode("VersionInfo/LatestVersion").InnerText);
string changeLog = xmlDoc.SelectSingleNode("VersionInfo/ChangeLog").InnerText;
string fileHash = xmlDoc.SelectSingleNode("VersionInfo/Sha1Hash").InnerText;
string donateText = xmlDoc.SelectSingleNode("VersionInfo/DonateText")?.InnerText;
if(latestVersion > currentVersion) {
Application.OpenForms[0].BeginInvoke((MethodInvoker)(() => {
using(frmUpdatePrompt frmUpdate = new frmUpdatePrompt(currentVersion, latestVersion, changeLog, fileHash, donateText)) {
if(frmUpdate.ShowDialog(null, Application.OpenForms[0]) == DialogResult.OK) {
Application.Exit();
}
}
}));
} else if(!silent) {
MesenMsgBox.Show("MesenUpToDate", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
} catch(Exception ex) {
if(!silent) {
MesenMsgBox.Show("ErrorWhileCheckingUpdates", MessageBoxButtons.OK, MessageBoxIcon.Error, ex.ToString());
}
}
});
}
}
}

View file

@ -0,0 +1,99 @@
using Mesen.GUI.Forms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Mesen.GUI.Updates
{
public partial class frmDownloadProgress : BaseForm
{
private string _link;
private string _filename;
private bool _cancel = false;
public frmDownloadProgress(string link, string filename)
{
InitializeComponent();
_link = link;
_filename = filename;
try {
File.Delete(_filename);
} catch {}
lblFilename.Text = link;
tmrStart.Start();
}
protected override void OnClosing(CancelEventArgs e)
{
_cancel = true;
base.OnClosing(e);
}
private void tmrStart_Tick(object sender, EventArgs e)
{
tmrStart.Stop();
DialogResult result = DialogResult.None;
Task.Run(() => {
using(var client = new WebClient()) {
client.DownloadProgressChanged += (object s, DownloadProgressChangedEventArgs args) => {
this.BeginInvoke((Action)(() => {
lblFilename.Text = string.Format("{0} ({1:0.00}Mb)", _link, (double)args.TotalBytesToReceive/1024/1024);
progressDownload.Value = args.ProgressPercentage;
}));
};
client.DownloadFileCompleted += (object s, AsyncCompletedEventArgs args) => {
if(!args.Cancelled && args.Error == null && File.Exists(_filename)) {
result = DialogResult.OK;
} else if(args.Error != null) {
MesenMsgBox.Show("UnableToDownload", MessageBoxButtons.OK, MessageBoxIcon.Error, args.Error.ToString());
result = DialogResult.Cancel;
}
};
Task downloadTask = null;
try {
downloadTask = client.DownloadFileTaskAsync(_link, _filename);
} catch(Exception ex) {
MesenMsgBox.Show("UnableToDownload", MessageBoxButtons.OK, MessageBoxIcon.Error, ex.ToString());
result = DialogResult.Cancel;
}
if(downloadTask == null) {
result = DialogResult.Cancel;
} else {
while(!downloadTask.IsCompleted && !_cancel) {
System.Threading.Thread.Sleep(200);
}
if(_cancel) {
client.CancelAsync();
} else if(result == DialogResult.None) {
result = DialogResult.OK;
}
}
}
//Wait a bit for the progress bar to update to 100% (display updates are slower than the .Value updates)
System.Threading.Thread.Sleep(500);
this.BeginInvoke((Action)(() => {
DialogResult = result;
this.Close();
}));
});
}
}
}

100
UI/Updates/frmDownloadProgress.designer.cs generated Normal file
View file

@ -0,0 +1,100 @@
namespace Mesen.GUI.Updates
{
partial class frmDownloadProgress
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form 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()
{
this.components = new System.ComponentModel.Container();
this.progressDownload = new System.Windows.Forms.ProgressBar();
this.lblFilename = new System.Windows.Forms.Label();
this.tmrStart = new System.Windows.Forms.Timer(this.components);
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.tableLayoutPanel1.SuspendLayout();
this.SuspendLayout();
//
// progressDownload
//
this.progressDownload.Dock = System.Windows.Forms.DockStyle.Top;
this.progressDownload.Location = new System.Drawing.Point(3, 38);
this.progressDownload.Name = "progressDownload";
this.progressDownload.Size = new System.Drawing.Size(328, 23);
this.progressDownload.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
this.progressDownload.TabIndex = 0;
//
// lblFilename
//
this.lblFilename.AutoSize = true;
this.lblFilename.Location = new System.Drawing.Point(3, 5);
this.lblFilename.Margin = new System.Windows.Forms.Padding(3, 5, 3, 0);
this.lblFilename.Name = "lblFilename";
this.lblFilename.Size = new System.Drawing.Size(100, 13);
this.lblFilename.TabIndex = 1;
this.lblFilename.Text = "Downloading file: ...";
//
// tmrStart
//
this.tmrStart.Tick += new System.EventHandler(this.tmrStart_Tick);
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 1;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Controls.Add(this.lblFilename, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.progressDownload, 0, 1);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 35F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.Size = new System.Drawing.Size(334, 67);
this.tableLayoutPanel1.TabIndex = 2;
//
// frmDownloadProgress
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(334, 67);
this.Controls.Add(this.tableLayoutPanel1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.MaximumSize = new System.Drawing.Size(350, 500);
this.Name = "frmDownloadProgress";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Downloading...";
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ProgressBar progressDownload;
private System.Windows.Forms.Label lblFilename;
private System.Windows.Forms.Timer tmrStart;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
}
}

View file

@ -0,0 +1,126 @@
<?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>
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="tmrStart.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>107, 17</value>
</metadata>
</root>

View file

@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Mesen.GUI.Config;
using Mesen.GUI.Controls;
using Mesen.GUI.Forms;
namespace Mesen.GUI.Updates
{
public partial class frmUpdatePrompt : BaseForm
{
private string _fileHash;
private string _donateText;
public frmUpdatePrompt(Version currentVersion, Version latestVersion, string changeLog, string fileHash, string donateText)
{
InitializeComponent();
_donateText = donateText;
this.txtChangelog.Font = new Font(BaseControl.MonospaceFontFamily, 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
_fileHash = fileHash;
lblCurrentVersionString.Text = currentVersion.ToString();
lblLatestVersionString.Text = latestVersion.ToString();
txtChangelog.Text = changeLog.Replace("\n", Environment.NewLine);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if(_donateText != null) {
if(!string.IsNullOrEmpty(_donateText)) {
this.lblDonate.Text = _donateText;
}
this.lblDonate.Visible = true;
this.picDonate.Visible = true;
} else {
this.lblDonate.Visible = false;
this.picDonate.Visible = false;
}
btnUpdate.Focus();
}
private void btnUpdate_Click(object sender, EventArgs e)
{
#if DISABLEAUTOUPDATE
MesenMsgBox.Show("AutoUpdateDisabledMessage", MessageBoxButtons.OK, MessageBoxIcon.Information);
this.DialogResult = DialogResult.Cancel;
this.Close();
#else
string destFilePath = System.Reflection.Assembly.GetEntryAssembly().Location;
string srcFilePath = Path.Combine(ConfigManager.DownloadFolder, "Mesen." + lblLatestVersionString.Text + ".exe");
string backupFilePath = Path.Combine(ConfigManager.BackupFolder, "Mesen." + lblCurrentVersionString.Text + ".exe");
string updateHelper = Path.Combine(ConfigManager.HomeFolder, "Resources", "MesenUpdater.exe");
if(!File.Exists(updateHelper)) {
MesenMsgBox.Show("UpdaterNotFound", MessageBoxButtons.OK, MessageBoxIcon.Error);
DialogResult = DialogResult.Cancel;
} else if(!string.IsNullOrWhiteSpace(srcFilePath)) {
frmDownloadProgress frmDownload = new frmDownloadProgress("https://www.mesen.ca/snes/Services/GetLatestVersion.php?a=download&p=win&v=" + EmuApi.GetMesenVersion().ToString(3), srcFilePath);
if(frmDownload.ShowDialog() == DialogResult.OK) {
FileInfo fileInfo = new FileInfo(srcFilePath);
if(fileInfo.Length > 0 && ResourceExtractor.GetSha1Hash(File.ReadAllBytes(srcFilePath)) == _fileHash) {
if(Program.IsMono) {
Process.Start("mono", string.Format("\"{0}\" \"{1}\" \"{2}\" \"{3}\"", updateHelper, srcFilePath, destFilePath, backupFilePath));
} else {
Process.Start(updateHelper, string.Format("\"{0}\" \"{1}\" \"{2}\"", srcFilePath, destFilePath, backupFilePath));
}
} else {
//Download failed, mismatching hashes
MesenMsgBox.Show("UpdateDownloadFailed", MessageBoxButtons.OK, MessageBoxIcon.Error);
DialogResult = DialogResult.Cancel;
}
}
}
#endif
}
private void picDonate_Click(object sender, EventArgs e)
{
Process.Start("https://www.mesen.ca/Donate.php?l=" + ResourceHelper.GetLanguageCode());
}
}
}

268
UI/Updates/frmUpdatePrompt.designer.cs generated Normal file
View file

@ -0,0 +1,268 @@
namespace Mesen.GUI.Updates
{
partial class frmUpdatePrompt
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form 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()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmUpdatePrompt));
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.lblLatestVersionString = new System.Windows.Forms.Label();
this.lblLatestVersion = new System.Windows.Forms.Label();
this.lblCurrentVersion = new System.Windows.Forms.Label();
this.txtChangelog = new System.Windows.Forms.TextBox();
this.lblChangeLog = new System.Windows.Forms.Label();
this.lblCurrentVersionString = new System.Windows.Forms.Label();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
this.btnCancel = new System.Windows.Forms.Button();
this.btnUpdate = new System.Windows.Forms.Button();
this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel();
this.picDonate = new System.Windows.Forms.PictureBox();
this.lblDonate = new System.Windows.Forms.Label();
this.tableLayoutPanel1.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
this.flowLayoutPanel1.SuspendLayout();
this.flowLayoutPanel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picDonate)).BeginInit();
this.SuspendLayout();
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 4;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 100F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.Controls.Add(this.lblLatestVersionString, 1, 0);
this.tableLayoutPanel1.Controls.Add(this.lblLatestVersion, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.lblCurrentVersion, 2, 0);
this.tableLayoutPanel1.Controls.Add(this.txtChangelog, 0, 2);
this.tableLayoutPanel1.Controls.Add(this.lblChangeLog, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.lblCurrentVersionString, 3, 0);
this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 0, 3);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(5, 10, 5, 0);
this.tableLayoutPanel1.RowCount = 4;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(689, 354);
this.tableLayoutPanel1.TabIndex = 0;
//
// lblLatestVersionString
//
this.lblLatestVersionString.AutoSize = true;
this.lblLatestVersionString.Location = new System.Drawing.Point(91, 10);
this.lblLatestVersionString.Name = "lblLatestVersionString";
this.lblLatestVersionString.Size = new System.Drawing.Size(28, 13);
this.lblLatestVersionString.TabIndex = 7;
this.lblLatestVersionString.Text = "x.x.x";
//
// lblLatestVersion
//
this.lblLatestVersion.AutoSize = true;
this.lblLatestVersion.Location = new System.Drawing.Point(8, 10);
this.lblLatestVersion.Name = "lblLatestVersion";
this.lblLatestVersion.Size = new System.Drawing.Size(77, 13);
this.lblLatestVersion.TabIndex = 2;
this.lblLatestVersion.Text = "Latest Version:";
//
// lblCurrentVersion
//
this.lblCurrentVersion.AutoSize = true;
this.lblCurrentVersion.Location = new System.Drawing.Point(191, 10);
this.lblCurrentVersion.Name = "lblCurrentVersion";
this.lblCurrentVersion.Size = new System.Drawing.Size(82, 13);
this.lblCurrentVersion.TabIndex = 3;
this.lblCurrentVersion.Text = "Current Version:";
//
// txtChangelog
//
this.txtChangelog.BackColor = System.Drawing.Color.White;
this.tableLayoutPanel1.SetColumnSpan(this.txtChangelog, 4);
this.txtChangelog.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtChangelog.Location = new System.Drawing.Point(8, 49);
this.txtChangelog.Multiline = true;
this.txtChangelog.Name = "txtChangelog";
this.txtChangelog.ReadOnly = true;
this.txtChangelog.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.txtChangelog.Size = new System.Drawing.Size(673, 271);
this.txtChangelog.TabIndex = 4;
this.txtChangelog.TabStop = false;
//
// lblChangeLog
//
this.lblChangeLog.AutoSize = true;
this.lblChangeLog.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblChangeLog.Location = new System.Drawing.Point(8, 33);
this.lblChangeLog.Margin = new System.Windows.Forms.Padding(3, 10, 3, 0);
this.lblChangeLog.Name = "lblChangeLog";
this.lblChangeLog.Size = new System.Drawing.Size(61, 13);
this.lblChangeLog.TabIndex = 5;
this.lblChangeLog.Text = "Changelog:";
//
// lblCurrentVersionString
//
this.lblCurrentVersionString.AutoSize = true;
this.lblCurrentVersionString.Location = new System.Drawing.Point(279, 10);
this.lblCurrentVersionString.Name = "lblCurrentVersionString";
this.lblCurrentVersionString.Size = new System.Drawing.Size(28, 13);
this.lblCurrentVersionString.TabIndex = 6;
this.lblCurrentVersionString.Text = "x.x.x";
//
// tableLayoutPanel2
//
this.tableLayoutPanel2.ColumnCount = 2;
this.tableLayoutPanel1.SetColumnSpan(this.tableLayoutPanel2, 4);
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel1, 1, 0);
this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel2, 0, 0);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel2.Location = new System.Drawing.Point(5, 323);
this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 1;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(679, 31);
this.tableLayoutPanel2.TabIndex = 9;
//
// flowLayoutPanel1
//
this.flowLayoutPanel1.Controls.Add(this.btnCancel);
this.flowLayoutPanel1.Controls.Add(this.btnUpdate);
this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft;
this.flowLayoutPanel1.Location = new System.Drawing.Point(520, 0);
this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel1.Name = "flowLayoutPanel1";
this.flowLayoutPanel1.Size = new System.Drawing.Size(159, 28);
this.flowLayoutPanel1.TabIndex = 8;
//
// btnCancel
//
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(85, 3);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(71, 23);
this.btnCancel.TabIndex = 1;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
//
// btnUpdate
//
this.btnUpdate.DialogResult = System.Windows.Forms.DialogResult.OK;
this.btnUpdate.Location = new System.Drawing.Point(4, 3);
this.btnUpdate.Name = "btnUpdate";
this.btnUpdate.Size = new System.Drawing.Size(75, 23);
this.btnUpdate.TabIndex = 0;
this.btnUpdate.Text = "Update";
this.btnUpdate.UseVisualStyleBackColor = true;
this.btnUpdate.Click += new System.EventHandler(this.btnUpdate_Click);
//
// flowLayoutPanel2
//
this.flowLayoutPanel2.Controls.Add(this.picDonate);
this.flowLayoutPanel2.Controls.Add(this.lblDonate);
this.flowLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.flowLayoutPanel2.Location = new System.Drawing.Point(0, 0);
this.flowLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel2.Name = "flowLayoutPanel2";
this.flowLayoutPanel2.Size = new System.Drawing.Size(520, 31);
this.flowLayoutPanel2.TabIndex = 9;
this.flowLayoutPanel2.WrapContents = false;
//
// picDonate
//
this.picDonate.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.picDonate.Cursor = System.Windows.Forms.Cursors.Hand;
this.picDonate.Image = ((System.Drawing.Image)(resources.GetObject("picDonate.Image")));
this.picDonate.Location = new System.Drawing.Point(3, 3);
this.picDonate.Name = "picDonate";
this.picDonate.Size = new System.Drawing.Size(78, 22);
this.picDonate.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.picDonate.TabIndex = 0;
this.picDonate.TabStop = false;
this.picDonate.Click += new System.EventHandler(this.picDonate_Click);
//
// lblDonate
//
this.lblDonate.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblDonate.AutoSize = true;
this.lblDonate.Location = new System.Drawing.Point(84, 7);
this.lblDonate.Margin = new System.Windows.Forms.Padding(0);
this.lblDonate.Name = "lblDonate";
this.lblDonate.Size = new System.Drawing.Size(331, 13);
this.lblDonate.TabIndex = 1;
this.lblDonate.Text = "If you want to support Mesen, please consider donating. Thank you!";
//
// frmUpdatePrompt
//
this.AcceptButton = this.btnUpdate;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(689, 354);
this.Controls.Add(this.tableLayoutPanel1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "frmUpdatePrompt";
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Mesen - Update Available";
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
this.tableLayoutPanel2.ResumeLayout(false);
this.flowLayoutPanel1.ResumeLayout(false);
this.flowLayoutPanel2.ResumeLayout(false);
this.flowLayoutPanel2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.picDonate)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.Label lblLatestVersionString;
private System.Windows.Forms.Label lblLatestVersion;
private System.Windows.Forms.Label lblCurrentVersion;
private System.Windows.Forms.TextBox txtChangelog;
private System.Windows.Forms.Label lblChangeLog;
private System.Windows.Forms.Label lblCurrentVersionString;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.Button btnUpdate;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2;
private System.Windows.Forms.PictureBox picDonate;
private System.Windows.Forms.Label lblDonate;
}
}

View file

@ -0,0 +1,164 @@
<?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>
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="picDonate.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
</value>
</data>
</root>

BIN
UpdateHelper/Icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

62
UpdateHelper/Program.cs Normal file
View file

@ -0,0 +1,62 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Diagnostics;
using System.Windows.Forms;
namespace MesenUpdater
{
class Program
{
static void Main(string[] args)
{
if(args.Length > 2) {
string srcFile = args[0];
string destFile = args[1];
string backupDestFile = args[2];
bool isAdmin = args.Length > 3 && args[3] == "admin";
int retryCount = 0;
while(retryCount < 10) {
try {
using(FileStream file = File.Open(destFile, FileMode.Open, FileAccess.ReadWrite, FileShare.Delete | FileShare.ReadWrite)) { }
break;
} catch {
retryCount++;
System.Threading.Thread.Sleep(1000);
}
}
try {
File.Copy(destFile, backupDestFile, true);
File.Copy(srcFile, destFile, true);
} catch {
try {
if(!isAdmin) {
ProcessStartInfo proc = new ProcessStartInfo();
proc.WindowStyle = ProcessWindowStyle.Normal;
proc.FileName = System.Reflection.Assembly.GetEntryAssembly().Location;
proc.Arguments = string.Format("\"{0}\" \"{1}\" \"{2}\" admin", srcFile, destFile, backupDestFile);
proc.UseShellExecute = true;
proc.Verb = "runas";
Process.Start(proc);
return;
} else {
MessageBox.Show("Update failed. Please try downloading and installing the new version manually.", "Mesen-S", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
} catch {
MessageBox.Show("Update failed. Please try downloading and installing the new version manually.", "Mesen-S", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
Process.Start(destFile);
} else {
MessageBox.Show("Please run Mesen-S directly to update.", "Mesen-S");
}
}
}
}

View file

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("MesenUpdater")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MesenUpdater")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("36abbf1c-66e1-4577-828a-619a2ef0dae9")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,198 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{36ABBF1C-66E1-4577-828A-619A2EF0DAE9}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MesenUpdater</RootNamespace>
<AssemblyName>MesenUpdater</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\bin\Any CPU\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\bin\Any CPU\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>..\bin\x64\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>..\bin\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'PGO Profile|AnyCPU'">
<OutputPath>..\bin\Any CPU\PGO Profile\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'PGO Profile|x64'">
<OutputPath>..\bin\x64\PGO Profile\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'PGO Profile|x86'">
<OutputPath>..\bin\x86\PGO Profile\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'PGO Optimize|AnyCPU'">
<OutputPath>..\bin\Any CPU\PGO Profile\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'PGO Optimize|x64'">
<OutputPath>..\bin\x64\PGO Profile\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'PGO Optimize|x86'">
<OutputPath>..\bin\x86\PGO Profile\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Icon.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Libretro|AnyCPU'">
<OutputPath>bin\Libretro\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Libretro|x64'">
<OutputPath>bin\x64\Libretro\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Libretro|x86'">
<OutputPath>bin\x86\Libretro\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Icon.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>