WindowsInstaller skeleton

This commit is contained in:
Jiiks 2015-12-04 03:17:37 +02:00
parent 19637bb5c6
commit 6f66ad26d5
21 changed files with 1333 additions and 71 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/>
</startup>
</configuration>
</configuration>

View File

@ -9,8 +9,9 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>BetterDiscordWI</RootNamespace>
<AssemblyName>BetterDiscordWI</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -34,6 +35,8 @@
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.IO.Compression.FileSystem" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@ -44,17 +47,55 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="components\CTextBox.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="FormMain.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="FormMain.Designer.cs">
<DependentUpon>FormMain.cs</DependentUpon>
</Compile>
<Compile Include="panels\IPanel.cs" />
<Compile Include="panels\Panel0.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="panels\Panel0.Designer.cs">
<DependentUpon>Panel0.cs</DependentUpon>
</Compile>
<Compile Include="panels\Panel1.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="panels\Panel1.Designer.cs">
<DependentUpon>Panel1.cs</DependentUpon>
</Compile>
<Compile Include="panels\Panel2.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="panels\Panel2.Designer.cs">
<DependentUpon>Panel2.cs</DependentUpon>
</Compile>
<Compile Include="panels\Panel3.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="panels\Panel3.Designer.cs">
<DependentUpon>Panel3.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Utils.cs" />
<EmbeddedResource Include="FormMain.resx">
<DependentUpon>FormMain.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="panels\Panel0.resx">
<DependentUpon>Panel0.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="panels\Panel1.resx">
<DependentUpon>Panel1.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="panels\Panel2.resx">
<DependentUpon>Panel2.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
@ -63,6 +104,7 @@
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
<DesignTime>True</DesignTime>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>

View File

@ -28,20 +28,93 @@
/// </summary>
private void InitializeComponent()
{
this.btnCancel = new System.Windows.Forms.Button();
this.panelContainer = new System.Windows.Forms.Panel();
this.btnNext = new System.Windows.Forms.Button();
this.btnBack = new System.Windows.Forms.Button();
this.lblPanelTitle = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// btnCancel
//
this.btnCancel.Location = new System.Drawing.Point(438, 328);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 0;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
//
// panelContainer
//
this.panelContainer.BackColor = System.Drawing.SystemColors.Control;
this.panelContainer.Location = new System.Drawing.Point(0, 52);
this.panelContainer.Name = "panelContainer";
this.panelContainer.Size = new System.Drawing.Size(524, 258);
this.panelContainer.TabIndex = 0;
//
// btnNext
//
this.btnNext.Enabled = false;
this.btnNext.Location = new System.Drawing.Point(357, 328);
this.btnNext.Name = "btnNext";
this.btnNext.Size = new System.Drawing.Size(75, 23);
this.btnNext.TabIndex = 4;
this.btnNext.Text = "Next >";
this.btnNext.UseVisualStyleBackColor = true;
//
// btnBack
//
this.btnBack.Enabled = false;
this.btnBack.Location = new System.Drawing.Point(276, 328);
this.btnBack.Name = "btnBack";
this.btnBack.Size = new System.Drawing.Size(75, 23);
this.btnBack.TabIndex = 5;
this.btnBack.Text = "< Back";
this.btnBack.UseVisualStyleBackColor = true;
//
// lblPanelTitle
//
this.lblPanelTitle.AutoSize = true;
this.lblPanelTitle.BackColor = System.Drawing.SystemColors.Window;
this.lblPanelTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblPanelTitle.Location = new System.Drawing.Point(13, 13);
this.lblPanelTitle.Name = "lblPanelTitle";
this.lblPanelTitle.Size = new System.Drawing.Size(103, 16);
this.lblPanelTitle.TabIndex = 6;
this.lblPanelTitle.Text = "BetterDiscord";
//
// FormMain
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 261);
this.ClientSize = new System.Drawing.Size(524, 361);
this.Controls.Add(this.lblPanelTitle);
this.Controls.Add(this.btnBack);
this.Controls.Add(this.panelContainer);
this.Controls.Add(this.btnCancel);
this.Controls.Add(this.btnNext);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
this.Name = "FormMain";
this.Text = "BetterDiscord Installer";
this.Text = "Setup - BetterDiscord ";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button btnCancel;
private System.Windows.Forms.Panel panelContainer;
public System.Windows.Forms.Button btnNext;
public System.Windows.Forms.Button btnBack;
public System.Windows.Forms.Label lblPanelTitle;
}
}

View File

@ -1,20 +1,101 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using BetterDiscordWI.panels;
namespace BetterDiscordWI
{
public partial class FormMain : Form
{
private readonly IPanel[] _panels = { new Panel0(), new Panel1(), new Panel2() };
private int _index;
public String DiscordPath;
public String Sha;
public XmlNodeList ResourceList;
public FormMain()
{
InitializeComponent();
Sha = Utils.GetHash();
if (Sha.Length < 1)
{
MessageBox.Show("Failed to get sha", "Error", MessageBoxButtons.OK);
Environment.Exit(0);
}
/* ZipArchive archive = ZipFile.OpenRead(@"C:\Users\Jiiks\AppData\Roaming\BetterDiscord\temp\asar.zip");
archive.ExtractToDirectory("C:/Users/Jiiks/AppData/Roaming/BetterDiscord/temp/");*/
//Load installer config
XmlDocument doc = new XmlDocument();
doc.Load(@"G:\Git\BetterDiscordApp\BetterDiscordApp\WindowsInstaller\config.xml");
String latestVersion = doc.GetElementsByTagName("latestversion")[0].InnerText;
ResourceList = doc.GetElementsByTagName("resource");
foreach (IPanel ipanel in _panels)
{
panelContainer.Controls.Add((UserControl)ipanel);
((UserControl)ipanel).Dock = DockStyle.Fill;
((UserControl)ipanel).Hide();
}
((UserControl)_panels[_index]).Show();
_panels[_index].SetVisible();
btnCancel.Click += (sender, args) => Close();
btnNext.Click += (sender, args) => _panels[_index].BtnNext();
btnBack.Click += (sender, args) => _panels[_index].BtnPrev();
}
public void SwitchPanel(int index)
{
((UserControl)_panels[_index]).Hide();
_index = index;
((UserControl)_panels[_index]).Show();
_panels[_index].SetVisible();
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
DialogResult dr = MessageBox.Show("Setup is not complete. If you exit now, BetterDiscord will not be installed.\n\nExit Setup?", "Exit Setup?", MessageBoxButtons.YesNo);
if (dr == DialogResult.No)
{
e.Cancel = true;
}
}
readonly Pen borderPen = new Pen(Color.FromArgb(160,160,160));
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
g.FillRectangle(SystemBrushes.Window, new Rectangle(0,0, Width, 50) );
g.DrawLine(borderPen, 0, 50, Width, 50);
g.DrawLine(SystemPens.Window, 0, 51, Width, 51);
g.DrawLine(borderPen, 0, 310, Width, 310);
g.DrawLine(SystemPens.Window, 0, 311, Width, 311);
base.OnPaint(e);
}
}
}

View File

@ -8,10 +8,10 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace BetterDiscordWI.Properties
{
namespace BetterDiscordWI.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
@ -22,48 +22,40 @@ namespace BetterDiscordWI.Properties
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BetterDiscordWI.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set
{
set {
resourceCulture = value;
}
}

View File

@ -8,21 +8,17 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace BetterDiscordWI.Properties
{
namespace BetterDiscordWI.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
public static Settings Default {
get {
return defaultInstance;
}
}

View File

@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BetterDiscordWI
{
class Utils
{
public void StartDownload(ProgressBar pb, String url, String name)
{
Thread t = new Thread(() =>
{
Debug.Print("Starting thread?");
WebClient webClient = new WebClient();
webClient.Headers["User-Agent"] = "Mozilla/5.0";
webClient.DownloadProgressChanged += delegate(object sender, DownloadProgressChangedEventArgs args)
{
double percentage = (double.Parse(args.BytesReceived.ToString()) /double.Parse(args.TotalBytesToReceive.ToString())) * 100;
Debug.Print(percentage.ToString());
pb.Invoke((MethodInvoker) delegate
{
pb.Value = (int)Math.Truncate(percentage);
});
};
if (name.Contains(".exe"))
{
webClient.DownloadFile(new Uri(url),
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\BetterDiscord\\" +
name);
}
else
{
webClient.DownloadFile(new Uri(url), Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\BetterDiscord\\temp\\" + name);
}
});
t.Start();
}
public static String GetHash()
{
WebClient wc = new WebClient();
wc.Headers["User-Agent"] = "Mozilla/5.0";
String result = wc.DownloadString("https://api.github.com/repos/Jiiks/BetterDiscordApp/commits/master");
int start = result.IndexOf("{\"sha\":");
int end = result.IndexOf("\",\"");
return result.Substring(start + 8, end - 8);
}
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BetterDiscordWI.components
{
class CTextBox : TextBox
{
public bool CAutoSize
{
get { return AutoSize; }
set { AutoSize = value; }
}
}
}

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
namespace BetterDiscordWI.panels
{
interface IPanel
{
void SetVisible();
FormMain GetParent();
void BtnNext();
void BtnPrev();
}
}

View File

@ -0,0 +1,100 @@
namespace BetterDiscordWI.panels
{
partial class Panel0
{
/// <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 Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Panel0));
this.label2 = new System.Windows.Forms.Label();
this.richTextBox1 = new System.Windows.Forms.RichTextBox();
this.radioDeclineLicense = new System.Windows.Forms.RadioButton();
this.radioAcceptLicense = new System.Windows.Forms.RadioButton();
this.SuspendLayout();
//
// label2
//
this.label2.Location = new System.Drawing.Point(35, 18);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(455, 31);
this.label2.TabIndex = 5;
this.label2.Text = "Please read the following License Agreement and accept the terms before continuin" +
"g the installation.";
//
// richTextBox1
//
this.richTextBox1.Location = new System.Drawing.Point(38, 54);
this.richTextBox1.Name = "richTextBox1";
this.richTextBox1.ReadOnly = true;
this.richTextBox1.Size = new System.Drawing.Size(452, 169);
this.richTextBox1.TabIndex = 4;
this.richTextBox1.Text = resources.GetString("richTextBox1.Text");
//
// radioDeclineLicense
//
this.radioDeclineLicense.AutoSize = true;
this.radioDeclineLicense.Checked = true;
this.radioDeclineLicense.Location = new System.Drawing.Point(108, 229);
this.radioDeclineLicense.Name = "radioDeclineLicense";
this.radioDeclineLicense.Size = new System.Drawing.Size(61, 17);
this.radioDeclineLicense.TabIndex = 8;
this.radioDeclineLicense.TabStop = true;
this.radioDeclineLicense.Text = "Decline";
this.radioDeclineLicense.UseVisualStyleBackColor = true;
//
// radioAcceptLicense
//
this.radioAcceptLicense.AutoSize = true;
this.radioAcceptLicense.Location = new System.Drawing.Point(38, 229);
this.radioAcceptLicense.Name = "radioAcceptLicense";
this.radioAcceptLicense.Size = new System.Drawing.Size(59, 17);
this.radioAcceptLicense.TabIndex = 7;
this.radioAcceptLicense.Text = "Accept";
this.radioAcceptLicense.UseVisualStyleBackColor = true;
//
// Panel0
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.radioDeclineLicense);
this.Controls.Add(this.radioAcceptLicense);
this.Controls.Add(this.label2);
this.Controls.Add(this.richTextBox1);
this.Name = "Panel0";
this.Size = new System.Drawing.Size(524, 258);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label2;
private System.Windows.Forms.RichTextBox richTextBox1;
private System.Windows.Forms.RadioButton radioDeclineLicense;
private System.Windows.Forms.RadioButton radioAcceptLicense;
}
}

View File

@ -0,0 +1,41 @@
using System.Windows.Forms;
namespace BetterDiscordWI.panels
{
public partial class Panel0 : UserControl, IPanel
{
public Panel0()
{
InitializeComponent();
radioAcceptLicense.CheckedChanged += (sender, args) =>
{
GetParent().btnNext.Enabled = radioAcceptLicense.Checked;
};
}
public void SetVisible()
{
GetParent().btnBack.Visible = false;
GetParent().btnNext.Enabled = false;
GetParent().btnNext.Text = "Next >";
GetParent().lblPanelTitle.Text = "BetterDiscord License Agreement";
GetParent().btnNext.Enabled = radioAcceptLicense.Checked;
}
public FormMain GetParent()
{
return (FormMain) ParentForm;
}
public void BtnNext()
{
GetParent().SwitchPanel(1);
}
public void BtnPrev()
{
throw new System.NotImplementedException();
}
}
}

View File

@ -0,0 +1,131 @@
<?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="richTextBox1.Text" xml:space="preserve">
<value>Copyright (c) 2015 Jiiks
http://jiiks.net
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</value>
</data>
</root>

View File

@ -0,0 +1,99 @@
namespace BetterDiscordWI.panels
{
partial class Panel1
{
/// <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 Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.label1 = new System.Windows.Forms.Label();
this.btnBrowser = new System.Windows.Forms.Button();
this.label2 = new System.Windows.Forms.Label();
this.tbPath = new BetterDiscordWI.components.CTextBox();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(20, 17);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(380, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Setup will install BetterDiscord to the following location. Click Install to cont" +
"inue.";
//
// btnBrowser
//
this.btnBrowser.Location = new System.Drawing.Point(406, 46);
this.btnBrowser.Name = "btnBrowser";
this.btnBrowser.Size = new System.Drawing.Size(75, 26);
this.btnBrowser.TabIndex = 2;
this.btnBrowser.Text = "Browse";
this.btnBrowser.UseVisualStyleBackColor = true;
this.btnBrowser.Click += new System.EventHandler(this.btnBrowser_Click);
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(20, 75);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(422, 13);
this.label2.TabIndex = 3;
this.label2.Text = "*If the path is not pointing to the latest version of Discord then click browse a" +
"nd select it.";
//
// tbPath
//
this.tbPath.CAutoSize = false;
this.tbPath.Font = new System.Drawing.Font("Microsoft Sans Serif", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.tbPath.Location = new System.Drawing.Point(23, 46);
this.tbPath.Name = "tbPath";
this.tbPath.Size = new System.Drawing.Size(377, 26);
this.tbPath.TabIndex = 4;
this.tbPath.Text = "feawfewafewa";
//
// Panel1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.tbPath);
this.Controls.Add(this.label2);
this.Controls.Add(this.btnBrowser);
this.Controls.Add(this.label1);
this.Name = "Panel1";
this.Size = new System.Drawing.Size(524, 258);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button btnBrowser;
private System.Windows.Forms.Label label2;
private components.CTextBox tbPath;
}
}

View File

@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BetterDiscordWI.panels
{
public partial class Panel1 : UserControl, IPanel
{
public Panel1()
{
InitializeComponent();
}
public void SetVisible()
{
GetParent().btnBack.Visible = true;
GetParent().btnNext.Enabled = true;
GetParent().btnBack.Enabled = true;
GetParent().btnNext.Text = "Install";
GetParent().lblPanelTitle.Text = "BetterDiscord Installation";
String[] directories = Directory.GetDirectories(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Discord");
String highestVersion = null;
foreach(String s in directories)
{
Debug.Print(s);
if (s.Contains("app-"))
{
if (highestVersion == null)
{
highestVersion = s;
continue;
}
if (String.CompareOrdinal(s, highestVersion) > 0)
{
highestVersion = s;
}
}
}
tbPath.Text = highestVersion;
}
public FormMain GetParent()
{
return (FormMain) ParentForm;
}
public void BtnNext()
{
GetParent().DiscordPath = tbPath.Text;
GetParent().SwitchPanel(2);
}
public void BtnPrev()
{
GetParent().SwitchPanel(0);
}
private void btnBrowser_Click(object sender, EventArgs e)
{
FolderBrowserDialog fbd = new FolderBrowserDialog {SelectedPath = tbPath.Text};
fbd.ShowDialog(GetParent());
tbPath.Text = fbd.SelectedPath;
}
}
}

View File

@ -0,0 +1,120 @@
<?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>
</root>

View File

@ -0,0 +1,67 @@
namespace BetterDiscordWI.panels
{
partial class Panel2
{
/// <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 Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.pbMain = new System.Windows.Forms.ProgressBar();
this.rtLog = new System.Windows.Forms.RichTextBox();
this.SuspendLayout();
//
// pbMain
//
this.pbMain.Location = new System.Drawing.Point(3, 238);
this.pbMain.Name = "pbMain";
this.pbMain.Size = new System.Drawing.Size(518, 16);
this.pbMain.TabIndex = 0;
//
// rtLog
//
this.rtLog.Location = new System.Drawing.Point(3, 3);
this.rtLog.Name = "rtLog";
this.rtLog.Size = new System.Drawing.Size(518, 229);
this.rtLog.TabIndex = 1;
this.rtLog.Text = "";
//
// Panel2
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.rtLog);
this.Controls.Add(this.pbMain);
this.Name = "Panel2";
this.Size = new System.Drawing.Size(524, 258);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ProgressBar pbMain;
private System.Windows.Forms.RichTextBox rtLog;
}
}

View File

@ -0,0 +1,175 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Security.AccessControl;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using System.Xml;
namespace BetterDiscordWI.panels
{
public partial class Panel2 : UserControl, IPanel
{
private String _dataPath, _tempPath;
private Utils _utils;
public Panel2()
{
InitializeComponent();
}
public void SetVisible()
{
GetParent().btnBack.Enabled = false;
GetParent().btnNext.Enabled = false;
CreateDirectories();
}
private void CreateDirectories()
{
_dataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "\\BetterDiscord";
_tempPath = _dataPath + "\\temp";
if (!Directory.Exists(_dataPath))
{
AppendLog("Creating Directory: " + _dataPath);
Directory.CreateDirectory(_dataPath);
}
if (!Directory.Exists(_dataPath))
{
AppendLog("ERROR: Directory does not exist: " + _dataPath);
return;
}
if (!Directory.Exists(_tempPath))
{
AppendLog("Creating Directory: " + _tempPath);
Directory.CreateDirectory(_tempPath);
}
else
{
AppendLog("Directory already exists: " + _tempPath);
AppendLog("Deleting Directory: " + _tempPath);
Directory.Delete(_tempPath, true);
}
if (!Directory.Exists(_tempPath))
{
AppendLog("Creating Directory: " + _tempPath);
Directory.CreateDirectory(_tempPath);
}
if (!Directory.Exists(_tempPath))
{
AppendLog("ERROR: Directory does not exists: " + _tempPath);
return;
}
CheckNode();
}
private void CheckNode()
{
AppendLog("Checking if node exists");
bool nodeExists = false;
String nodePath = "";
Process p = new Process
{
StartInfo = { UseShellExecute = false, RedirectStandardOutput = true, FileName = "cmd.exe", Arguments = "/C where node" }
};
p.Start();
String output = p.StandardOutput.ReadToEnd();
if (File.Exists(output))
{
nodeExists = true;
nodePath = output;
}
if (!nodeExists)
{
if (File.Exists(_dataPath + "\\node.exe")) ;
nodePath = _dataPath + "\\node.exe";
nodeExists = true;
}
if (nodeExists)
{
AppendLog("Node located at: " + nodePath);
}
DownloadResources(nodeExists);
}
private void DownloadResources(bool node)
{
_utils = new Utils();
foreach (XmlNode resource in GetParent().ResourceList)
{
String name = resource["name"].InnerText;
String url = resource["url"].InnerText;
if (name.ToLower().Equals("node"))
{
if (!node)
{
DownloadResource(".exe", name, url);
}
}
else
{
DownloadResource(".zip", name, url);
}
}
}
private void DownloadResource(String extension, String resource, String url)
{
AppendLog("Downloading Resource: " + resource);
_utils.StartDownload(pbMain, url, resource + extension);
}
public FormMain GetParent()
{
return (FormMain)ParentForm;
}
public void BtnNext()
{
throw new NotImplementedException();
}
public void BtnPrev()
{
throw new NotImplementedException();
}
private void AppendLog(String message)
{
rtLog.AppendText(message + "\n");
rtLog.SelectionStart = rtLog.Text.Length;
rtLog.ScrollToCaret();
}
}
}

View File

@ -0,0 +1,120 @@
<?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>
</root>

View File

@ -0,0 +1,37 @@
namespace BetterDiscordWI.panels
{
partial class Panel3
{
/// <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 Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
}
#endregion
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BetterDiscordWI.panels
{
public partial class Panel3 : UserControl
{
public Panel3()
{
InitializeComponent();
}
}
}

View File

@ -1,21 +0,0 @@
<config>
<latestversion>1.0</latestversion>
<resources>
<resource>
<name>Node</name>
<url>https://nodejs.org/dist/v4.2.2/win-x64/node.exe</url>
</resource>
<resource>
<name>asar</name>
<url>https://github.com/atom/asar/archive/master.zip</url>
</resource>
<resource>
<name>wrench</name>
<url>https://github.com/ryanmcgrath/wrench-js/archive/master.zip</url>
</resource>
<resource>
<name>BetterDiscord</name>
<url>https://github.com/Jiiks/BetterDiscordApp/archive/stable.zip</url>
</resource>
</resources>
</config>