Compare commits

...

6 Commits

24 changed files with 2011 additions and 270 deletions

View File

@ -89,7 +89,6 @@ namespace KattekerCreator
return semanticVersion?.Change(build: string.Empty);
Version.TryParse(productVersion, out var version);
return SemanticVersion.Parse(version.ToString(3));
}
}
}

View File

@ -2,8 +2,6 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Cryptography.X509Certificates;
using Vestris.ResourceLib;
namespace KattekerCreator.Helper

View File

@ -54,6 +54,7 @@
<Compile Include="IconExtractor\IconExtractor.cs" />
<Compile Include="IconExtractor\IconUtil.cs" />
<Compile Include="IconExtractor\NativeMethods.cs" />
<Compile Include="PathFragments.cs" />
<Compile Include="PhysicalFile.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />

25
Creator/PathFragments.cs Normal file
View File

@ -0,0 +1,25 @@
using System.IO;
using System.Linq;
namespace KattekerCreator
{
public class PathFragments
{
private readonly string[] _fragments;
public PathFragments(string path)
{
_fragments = path.Split(Path.DirectorySeparatorChar);
}
public int FragmentLength => _fragments.Length;
public override bool Equals(object obj) => string.Equals(ToString(), obj?.ToString());
public override int GetHashCode() => (_fragments != null ? _fragments.GetHashCode() : 0);
public override string ToString() => string.Join(Path.DirectorySeparatorChar.ToString(), _fragments.Take(_fragments.Length - 1));
protected bool Equals(PathFragments other) => Equals(_fragments, other._fragments);
}
}

View File

@ -2,13 +2,13 @@
{
public class PhysicalFile
{
public PhysicalFile(string sourcePath, string targetPath)
public PhysicalFile(string source, string target)
{
SourcePath = sourcePath;
TargetPath = targetPath;
Source = source;
Target = target;
}
public string SourcePath { get; }
public string TargetPath { get; }
public string Source { get; }
public string Target { get; }
}
}

View File

@ -69,14 +69,11 @@ namespace KattekerCreator
//Start makensis.exe
var setupFilePath = CompileSetupScript(templateFile);
//Copy to Output-Folder
if (CopyToOutputFolder(setupFilePath))
{
//Create/Modify RELEASE File
var releaseEntry = AddPackageToReleaseFile(setupFilePath);
//Copy installer as setup.exe
CopyAsSetup(setupFilePath, releaseEntry);
}
CopyToOutputFolder(setupFilePath);
//Create/Modify RELEASE File
var releaseEntry = AddPackageToReleaseFile(setupFilePath);
//Copy installer as setup.exe
CopyAsSetup(setupFilePath, releaseEntry);
return 0;
}
@ -103,31 +100,20 @@ namespace KattekerCreator
}
}
private bool CopyToOutputFolder(string setupFilePath)
private void CopyToOutputFolder(string setupFilePath)
{
try
if (setupFilePath == null) throw new ArgumentNullException(nameof(setupFilePath));
var setupFile = Path.GetFileName(setupFilePath);
if (string.IsNullOrEmpty(setupFile)) throw new ArgumentException();
if (!File.Exists(setupFilePath)) throw new FileNotFoundException(setupFile);
if (!Directory.Exists(_appArguments.OutputDir)) Directory.CreateDirectory(_appArguments.OutputDir);
if (!string.IsNullOrEmpty(_appArguments.ChangeLog))
{
if (setupFilePath == null) throw new ArgumentNullException(nameof(setupFilePath));
var setupFile = Path.GetFileName(setupFilePath);
if (string.IsNullOrEmpty(setupFile)) throw new ArgumentException();
if (!File.Exists(setupFilePath)) throw new FileNotFoundException(setupFile);
if (!string.IsNullOrEmpty(_appArguments.ChangeLog))
{
var changeLogPath = Path.Combine(Path.GetDirectoryName(_appArguments.ProgramFile), _appArguments.ChangeLog);
if (!File.Exists(changeLogPath)) throw new FileNotFoundException(changeLogPath);
File.Copy(changeLogPath, Path.Combine(_appArguments.OutputDir, Path.GetFileName(_appArguments.ChangeLog) ?? throw new InvalidOperationException()), true);
}
if (!Directory.Exists(_appArguments.OutputDir)) Directory.CreateDirectory(_appArguments.OutputDir);
File.Copy(setupFilePath, Path.Combine(_appArguments.OutputDir, setupFile), true);
return true;
}
catch (Exception e)
{
Log.WriteErrorLine(e.Message);
return false;
var changeLogPath = Path.Combine(Path.GetDirectoryName(_appArguments.ProgramFile), _appArguments.ChangeLog);
if (!File.Exists(changeLogPath)) throw new FileNotFoundException(changeLogPath);
File.Copy(changeLogPath, Path.Combine(_appArguments.OutputDir, _appArguments.ChangeLog), true);
}
File.Copy(setupFilePath, Path.Combine(_appArguments.OutputDir, setupFile), true);
}
private static string CompileSetupScript(string templateFile)

View File

@ -56,7 +56,7 @@ Section "install" ;No components page, name is not important
<# foreach(var directory in Directories) { #><#= $" CreateDirectory \"$INSTDIR\\{directory}\"{Environment.NewLine}" #><# } #>
; Put file there
<#foreach(var file in Files) { #><#= $" File \"/oname={file.TargetPath}\" \"{file.SourcePath}\"{Environment.NewLine}" #><# } #>
<#foreach(var file in Files) { #><#= $" File \"/oname={file.Target}\" \"{file.Source}\"{Environment.NewLine}" #><# } #>
WriteUninstaller "$INSTDIR\uninstall.exe"
; Desktop

View File

@ -30,55 +30,21 @@ namespace KattekerCreator
public string UninstallIcon { get; set; }
public string ReleaseChannel { get; set; }
private readonly List<DirSplit> _directoriesList = new List<DirSplit>();
private readonly List<PathFragments> _directoriesList = new List<PathFragments>();
private string _appName;
private IEnumerable<string> DirectoriesToCreate()
{
foreach (var physicalFile in Files)
{
var dirSplit = new DirSplit(physicalFile.TargetPath);
if (dirSplit.SplitCount > 1 && !_directoriesList.Contains(dirSplit))
var dirSplit = new PathFragments(physicalFile.Target);
if (dirSplit.FragmentLength > 1 && !_directoriesList.Contains(dirSplit))
{
_directoriesList.Add(dirSplit);
}
}
return _directoriesList.Select(x=> x.ToString());
}
private class DirSplit
{
private const char SplitChar = '\\';
private readonly string[] _splits;
public int SplitCount => _splits.Length;
public DirSplit(string path)
{
_splits = path.Split(SplitChar);
}
public override string ToString()
{
return string.Join(SplitChar.ToString(), _splits.Take(_splits.Length - 1));
}
public override bool Equals(object obj)
{
return string.Equals(ToString(), obj?.ToString());
}
protected bool Equals(DirSplit other)
{
return Equals(_splits, other._splits);
}
public override int GetHashCode()
{
return (_splits != null ? _splits.GetHashCode() : 0);
}
return _directoriesList.Select(x => x.ToString());
}
}
}

View File

@ -8,10 +8,11 @@
Title="MainWindow"
Width="800"
Height="450"
Background="DarkBlue"
Background="Chartreuse"
ContentRendered="MainWindow_OnContentRendered"
mc:Ignorable="d">
<StackPanel>
<Button Margin="10" FontSize="24" Content="Update" Click="ButtonBase_OnClick"></Button>
<TextBlock Text=":-(" FontSize="60" HorizontalAlignment="Center" />
</StackPanel>
</Window>

View File

@ -49,5 +49,5 @@ using System.Windows;
// 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.36.0")]
[assembly: AssemblyFileVersion("1.0.36.0")]
[assembly: AssemblyVersion("1.0.48")]
[assembly: AssemblyFileVersion("1.0.48")]

View File

@ -34,9 +34,6 @@
<DocumentationFile>bin\Release\Katteker.Gui.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="CommonMark, Version=0.1.0.0, Culture=neutral, PublicKeyToken=001ef8810438905d, processorArchitecture=MSIL">
<HintPath>..\packages\CommonMark.NET.0.15.1\lib\net45\CommonMark.dll</HintPath>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System" />
<Reference Include="System.Core" />
@ -45,7 +42,6 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ChangelogHelper.cs" />
<Compile Include="Wrapper.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs">
@ -62,7 +58,6 @@
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Properties\Resources.resx">

View File

@ -31,6 +31,5 @@ using System.Runtime.InteropServices;
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
// übernehmen, indem Sie "*" eingeben:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyVersion("1.0.0")]
[assembly: AssemblyFileVersion("1.0.0")]

View File

@ -60,6 +60,15 @@ namespace Katteker.Gui.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Could not update your application..
/// </summary>
internal static string CouldNotUpdateYourApplication {
get {
return ResourceManager.GetString("CouldNotUpdateYourApplication", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Installed new Version! Would you like to restart the Application?.
/// </summary>
@ -123,6 +132,15 @@ namespace Katteker.Gui.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Updater.
/// </summary>
internal static string Updater {
get {
return ResourceManager.GetString("Updater", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to You can update to Version: .
/// </summary>

View File

@ -144,4 +144,10 @@
<data name="SquirrelWrapper_CheckForUpdate_AskYourLocalDistributor" xml:space="preserve">
<value> Ask your local distributor.</value>
</data>
<data name="Updater" xml:space="preserve">
<value>Updater</value>
</data>
<data name="CouldNotUpdateYourApplication" xml:space="preserve">
<value>Could not update your application.</value>
</data>
</root>

View File

@ -21,7 +21,6 @@ namespace Katteker.Gui
[STAThread]
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(UpdateWindow));
this.mainSplitContainer = new System.Windows.Forms.SplitContainer();
this.titleLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
this.closeWindowBtn = new System.Windows.Forms.Button();
@ -85,6 +84,7 @@ namespace Katteker.Gui
this.titleLayoutPanel.Controls.Add(this.minimizeBtn, 2, 0);
this.titleLayoutPanel.Controls.Add(this.label1, 0, 0);
this.titleLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
this.titleLayoutPanel.ForeColor = System.Drawing.SystemColors.Control;
this.titleLayoutPanel.Location = new System.Drawing.Point(0, 0);
this.titleLayoutPanel.Name = "titleLayoutPanel";
this.titleLayoutPanel.RowCount = 1;
@ -101,7 +101,6 @@ namespace Katteker.Gui
this.closeWindowBtn.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Red;
this.closeWindowBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.closeWindowBtn.Font = new System.Drawing.Font("Segoe UI Symbol", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.closeWindowBtn.ForeColor = System.Drawing.SystemColors.ControlLightLight;
this.closeWindowBtn.Location = new System.Drawing.Point(658, 0);
this.closeWindowBtn.Margin = new System.Windows.Forms.Padding(0);
this.closeWindowBtn.Name = "closeWindowBtn";
@ -118,7 +117,6 @@ namespace Katteker.Gui
this.maximizeBtn.FlatAppearance.BorderSize = 0;
this.maximizeBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.maximizeBtn.Font = new System.Drawing.Font("Segoe UI Symbol", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.maximizeBtn.ForeColor = System.Drawing.SystemColors.ControlLightLight;
this.maximizeBtn.Location = new System.Drawing.Point(618, 0);
this.maximizeBtn.Margin = new System.Windows.Forms.Padding(0);
this.maximizeBtn.Name = "maximizeBtn";
@ -133,12 +131,11 @@ namespace Katteker.Gui
//
this.titlebar.Dock = System.Windows.Forms.DockStyle.Fill;
this.titlebar.Font = new System.Drawing.Font("Segoe UI", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.titlebar.ForeColor = System.Drawing.SystemColors.ControlLightLight;
this.titlebar.Location = new System.Drawing.Point(123, 0);
this.titlebar.Name = "titlebar";
this.titlebar.Size = new System.Drawing.Size(452, 30);
this.titlebar.TabIndex = 0;
this.titlebar.Text = "titleBar";
this.titlebar.Text = "Updater";
this.titlebar.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.titlebar.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Titlebar_MouseDown);
//
@ -148,7 +145,6 @@ namespace Katteker.Gui
this.minimizeBtn.FlatAppearance.BorderSize = 0;
this.minimizeBtn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.minimizeBtn.Font = new System.Drawing.Font("Segoe UI Symbol", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.minimizeBtn.ForeColor = System.Drawing.SystemColors.ControlLightLight;
this.minimizeBtn.Location = new System.Drawing.Point(578, 0);
this.minimizeBtn.Margin = new System.Windows.Forms.Padding(0);
this.minimizeBtn.Name = "minimizeBtn";
@ -163,7 +159,6 @@ namespace Katteker.Gui
//
this.label1.Dock = System.Windows.Forms.DockStyle.Fill;
this.label1.Font = new System.Drawing.Font("Segoe UI Symbol", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.ForeColor = System.Drawing.SystemColors.Window;
this.label1.Location = new System.Drawing.Point(3, 0);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(114, 30);
@ -276,11 +271,13 @@ namespace Katteker.Gui
this.DoubleBuffered = true;
this.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "UpdateWindow";
this.ShowIcon = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Activated += new System.EventHandler(this.UpdateWindow_Activated);
this.Deactivate += new System.EventHandler(this.UpdateWindow_Deactivate);
this.Load += new System.EventHandler(this.UpdateWindow_Load);
this.mainSplitContainer.Panel1.ResumeLayout(false);
this.mainSplitContainer.Panel2.ResumeLayout(false);

View File

@ -1,5 +1,6 @@
using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Katteker.Gui.Properties;
@ -8,14 +9,18 @@ namespace Katteker.Gui
{
public sealed partial class UpdateWindow : Form
{
private readonly UpdateManager _updateManager;
private readonly ReleaseEntry _entry;
private const int HTCAPTION = 0x2;
private const int WM_NCLBUTTONDOWN = 0xA1;
/// <summary>
/// The Update Window
/// </summary>
public UpdateWindow()
public UpdateWindow(UpdateManager updateManager, ReleaseEntry entry)
{
_updateManager = updateManager;
_entry = entry;
Font = SystemFonts.MessageBoxFont;
Application.EnableVisualStyles();
if (Environment.OSVersion.Version.Major >= 6)
@ -23,19 +28,9 @@ namespace Katteker.Gui
InitializeComponent();
}
private string Changelog => UpdateManager.ChangelogFilename;
/// <summary>
/// Last release entry.
/// </summary>
public ReleaseEntry ReleaseEntry { get; set; }
private string Changelog => _updateManager.ChangelogFilename;
/// <summary>
/// Update manager
/// </summary>
public UpdateManager UpdateManager { get; set; }
private string PublishPath => UpdateManager.UrlOrPath;
private string PublishPath => _updateManager.UrlOrPath;
/// <inheritdoc />
/// <summary>
@ -76,22 +71,41 @@ namespace Katteker.Gui
private void Titlebar_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && e.Clicks >= 2)
{
MaximizeBtn_Click(sender, e);
return;
}
if (e.Button != MouseButtons.Left) return;
ReleaseCapture();
SendMessage(Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);
}
private void UpdateWindow_Activated(object sender, EventArgs e)
{
titleLayoutPanel.BackColor = SystemColors.ControlDarkDark;
titleLayoutPanel.ForeColor = SystemColors.Control;
}
private void UpdateWindow_Deactivate(object sender, EventArgs e)
{
titleLayoutPanel.BackColor = SystemColors.Control;
titleLayoutPanel.ForeColor = SystemColors.ControlText;
}
private async void UpdateWindow_Load(object sender, EventArgs e)
{
var changelog = await ChangelogHelper.LoadChangelogAsync(Changelog, PublishPath).ConfigureAwait(false);
Invoke(new Action(() => changelogBrowser.DocumentText = changelog));
if (ReleaseEntry == null)
var changelogContent = await ChangelogHelper.LoadChangelogAsync(Changelog, PublishPath).ConfigureAwait(false);
changelogContent = changelogContent.ChangelogAsHtml(Path.GetExtension(Changelog));
Invoke(new Action(() => changelogBrowser.DocumentText = changelogContent));
if (_entry == null)
{
Invoke(new Action(() => { WriteTitle(Resources.No_update_available); }));
}
else
{
var latest = ReleaseEntry.Version;
var latest = _entry.Version;
Invoke(new Action(() =>
{
WriteTitle(Resources.You_can_update_to_Version + latest);
@ -107,13 +121,25 @@ namespace Katteker.Gui
try
{
var progress = new Progress<int>(x => Invoke(new Action(() => { progressBar1.Value = x; })));
await UpdateManager.UpdateAppAsync(progress).ConfigureAwait(false);
await _updateManager.UpdateAppAsync(progress).ConfigureAwait(false);
WriteTitle(Resources.You_re_up_to_date);
var messResult = MessageBox.Show(
Resources.Installed_new_Version,
Resources.New_Version,
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (messResult == DialogResult.Yes)
{
DialogResult = DialogResult.OK;
Close();
}
}
catch (Exception ex)
{
WriteTitle(ex.Message);
MessageBox.Show(Resources.CouldNotUpdateYourApplication + Environment.NewLine + ex.Message, Gui.Properties.Resources.Updater, MessageBoxButtons.OK, MessageBoxIcon.Error);
WriteTitle(Resources.Updater);
}
finally
{
@ -121,19 +147,10 @@ namespace Katteker.Gui
{
progressBar1.Visible = false;
updBtn.Visible = false;
var messResult = MessageBox.Show(
Resources.Installed_new_Version,
Resources.New_Version,
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (messResult == DialogResult.Yes)
{
DialogResult = DialogResult.OK;
Close();
}
}));
}
}
private void WriteTitle(string text)
{
Invoke(new Action(() =>

View File

@ -117,81 +117,4 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABYYGwFCSVQrTlloXjZEUYFIV2iiUmqFt1h2
m8o1UHHcEShHPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhgcBiQuPs5khK7/fajd/3up
4P94q+b/fa3p/0Jml/8NIkVQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEB80eUdy
qv9+rOj/eqfg/3Sk3f96p+D/SG2f/xMZKWMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAMGS45OWCR/1yOzf9Gdar/SXyr/0uBtP85bqT/IUBk3ilBU2JzhZUaAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAADZHWDwwUX3/Y5e//5vI1P+dvMX/k6+4/5avtf+Rtsb/i7jF/3ibsfJcdZmyHjpgYD5T
Wg8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAB5g5YIZYiZuqzb6P+u1s//fIud/4CBsf+Pjsn/jZHE/4KKuf+JlbX/nb7F/7vq
9P+WwNT/Wnqf126KkG+ZqqQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAOzUyC1Ntjqm56vP/ncDB/3Z4pP+snur/opvb/4mHwP+Cgq7/eniW/6Sb
3v9eXYT/U11t/7/k5//S////jsDR/16Bnc5ufItFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABLX22flMfc/7HVzv97d5//m5Hh/4KGof+coqb/yc3O//Xz
7v/j4Nv/TE9g/y0uXf81KmL/Pj1n/6LLyv/i////w/L4/3mmv/txfJd7AAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjqCWVX6owf/P+fn/coCa/7qx+v+Mhrr/ra+v////
///l5+j/4OPh//////+Qkpj/KiRl/zgyfv83LG7/Ojde/6rGyv/h////0v///4y7zf9pg5R2AAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAImhuCldiqDm0P///5q4tv9WSnb/fn64/2ht
lf9ZVG3//Pv3//Lw8v+xsLT//////+jm4f9ANFX/JyJn/ycrX/8nHWL/PD5i/5m3tP+76ez/1P///3+f
rda5upINAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADD0KwKaIOVv7Dj7f/f////XHF4/yki
Yv8vK2L/LS5m/ykjVP+yr7X//////5yan/+Mk5T/mqWq/3qMlP95lKL/gZqp/32Po/9JVWn/ZG9u/837
/P/S////hay3/7i5lVEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHiOkn2YwtT/2////8fm
6v85Q1//Ni15/zYzeP8yMX7/KiNe/0pMUv+To5n/k6+2/7vc3v+339f/xPXv/9r////Z////2f///6DG
w/+22d7/2v///8X4/f9ehZvPubuYAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACYnpg7apO398//
///T////p8bM/y8sX/8/MH3/NTBx/zAmXP9bZHv/psbK/8z4+f/Y////jau2/3B7ov98gqf/hZWd/7/m
4f/a////xe30/8L7/f/a////eqfG/3WEk4EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGR3
lbWw5/L/0v///9P///+Jp67/Lydl/zgubP8xOFv/kKmx/9T++//N////1v///6S8wf97d6r/trD//7Wv
//+gm+H/X3GM/7DY3v/N/Pn/1////4691/9Nboa3xMKtBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALTF
mw2Ln5NQfqPD/9P////N+f//2f///3WKlP8rImH/Nz5m/6zN0P/a////yfv//8z7///N9uj/cn6d/7Wx
+v+srPj/n5ve/3t3ov9JWoD/W4i0/2aax/9chrf/UnKM1K64lRoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAmpuYUnOEmKuv3+n/z/7//8z8/P/a////b3iN/yYpS/+iw87/1////8z8/P/O/P3/2P///5i9
0P9SXoT/doOz/19rkf9IS2D/Z2ls/5GWnP91gpr/ZJDE/0hytf+KlYiDAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAABje5eGbY6k2cX9/v/P/f//yfj7/5/Awv8+SVL/bH2B/+D////J+f//0f///8Pz
+v9smLD/Pl59/2Jmdv9ecZT/ZX6f/6Ouuf////////////r49P+RoKv/UXiw/159lJwAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGF9nYltlq3cx////9D7///L+f3/v+Pm/6nDyP94nJn/vevn/9f/
//+75+7/Tnmi/1Jpiv/V2df/9vr4/9Pc4/+CiY3/5ubn/8XHx/+YnJ///////+no4/9aeJz/P2abtgAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmJyVU3yTl6u97vb/z/3//8z7/f/M////1f///8/5
+//Q/f7/uefs/0l6rv9bbY7/4Nzi/////P/q7en//////+fm5f/HxMP/fHl4/zEvMf/4+Pz/7+7s/2J/
mv9WdqDNs6yOAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC6uqAElp6UQoSqxf/Q////z/3//838
///N/v3/2f///7zm8f9HdqT/V4nE/3uFl///////kpeU/yIhJv/n4+H//////7a0s//v7u3/6enm////
//+4t7X/X4Sn/1N8s/ylraAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADI0LgCdYqWmXeh
vP656/j/yvn//8n1/v+czNr/R3Sg/1aHyP94p+L/dYKP//v7+f/IyMv/gICE//Tx8///////f4SL/7q4
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
A///wA///8H////A////wP///8H////j//8=
</value>
</data>
</root>

View File

@ -1,5 +1,5 @@
using System;
using System.Linq;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Katteker.Gui.Properties;
@ -11,6 +11,8 @@ namespace Katteker.Gui
/// </summary>
public static class Wrapper
{
private static UpdateManager _manager;
/// <summary>
/// Checks for Updates.
/// </summary>
@ -24,35 +26,36 @@ namespace Katteker.Gui
/// <returns>Task</returns>
public static async Task CheckForUpdateAsync(bool isStartup)
{
using (var window = new UpdateWindow())
if (_manager == null && !UpdateManager.TryCreate(out _manager))
{
var dialogResult = DialogResult.Cancel;
if (!UpdateManager.TryCreate(out var manager) && !isStartup)
if (!isStartup)
{
MessageBox.Show(Resources.SquirrelWrapper_CheckForUpdate,
Resources.SquirrelWrapper_CheckForUpdate_Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
var releases = (await manager.CheckForUpdateAsync().ConfigureAwait(true)).ToArray();
window.UpdateManager = manager;
window.ReleaseEntry = releases.LastOrDefault();
if (isStartup)
{
if (releases?.Any() == true)
{
dialogResult = window.ShowDialog();
}
}
else
{
dialogResult = window.ShowDialog();
}
return;
}
var releases = (await _manager.CheckForUpdateAsync().ConfigureAwait(false)).ToArray();
if (releases.Any() || !isStartup)
{
var thread = new Thread(ThreadProcess);
thread.SetApartmentState(ApartmentState.STA);
thread.Start(releases.LastOrDefault());
thread.Join();
}
}
private static void ThreadProcess(object argument)
{
var entry = (ReleaseEntry) argument;
using (var window = new UpdateWindow(_manager, entry))
{
var dialogResult = window.ShowDialog();
if (dialogResult == DialogResult.OK)
{
manager.RestartApp();
_manager.RestartApp();
}
}
}

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CommonMark.NET" version="0.15.1" targetFramework="net45" />
</packages>

View File

@ -3,11 +3,11 @@ using System.IO;
using System.Net;
using System.Threading.Tasks;
namespace Katteker.Gui
namespace Katteker
{
internal static class ChangelogHelper
public static class ChangelogHelper
{
private static string GenerateHtmlifyChangelog(string text, string extension)
public static string ChangelogAsHtml(this string text, string extension)
{
string result;
switch (extension)
@ -17,7 +17,7 @@ namespace Katteker.Gui
result = plainText.Replace(Environment.NewLine, "<br />");
break;
case ".md":
result = CommonMark.CommonMarkConverter.Convert(text);
result = new MarkdownSharp.Markdown().Transform(text);
break;
default:
result = text;
@ -27,7 +27,7 @@ namespace Katteker.Gui
return result;
}
internal static async Task<string> LoadChangelogAsync(string filename, string path)
public static async Task<string> LoadChangelogAsync(string filename, string path)
{
if (!string.IsNullOrEmpty(filename) || !string.IsNullOrEmpty(path))
{
@ -39,23 +39,30 @@ namespace Katteker.Gui
using (var response = await webReq.GetResponseAsync().ConfigureAwait(false))
using (var sr = new StreamReader(response.GetResponseStream()))
{
return GenerateHtmlifyChangelog(await sr.ReadToEndAsync().ConfigureAwait(false),
Path.GetExtension(filename));
return await sr.ReadToEndAsync().ConfigureAwait(false);
}
}
catch (WebException)
catch (Exception)
{
var changelogFilename = Path.GetFileName(filename);
if (changelogFilename == null) return GenerateHtmlifyChangelog("Changelog not found", ".txt");
var currentChangelogPath = Path.Combine(Environment.CurrentDirectory, changelogFilename);
if (File.Exists(currentChangelogPath))
try
{
return GenerateHtmlifyChangelog(File.ReadAllText(currentChangelogPath), Path.GetExtension(filename));
var changelogFilename = Path.GetFileName(filename);
if (changelogFilename == null) return null;
var currentChangelogPath = Path.Combine(Environment.CurrentDirectory, changelogFilename);
if (File.Exists(currentChangelogPath))
{
return File.ReadAllText(currentChangelogPath);
}
}
catch (Exception)
{
// ignore;
}
}
}
return GenerateHtmlifyChangelog("Changelog not found", ".txt");
return null;
}
}
}

View File

@ -38,8 +38,10 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ChangelogHelper.cs" />
<Compile Include="Constants.cs" />
<Compile Include="KattekerConfig.cs" />
<Compile Include="MarkdownSharp.cs" />
<Compile Include="SemanticVersion.cs" />
<Compile Include="UpdateInfo.cs" />
<Compile Include="UpdateManager.cs" />

1779
Katteker/MarkdownSharp.cs Normal file

File diff suppressed because it is too large Load Diff

View File

@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
// indem Sie "*" wie unten gezeigt eingeben:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyVersion("1.0.3")]
[assembly: AssemblyFileVersion("1.0.3")]

View File

@ -10,6 +10,9 @@ using System.Threading.Tasks;
namespace Katteker
{
/// <summary>
/// Update manager, which handles the updates.
/// </summary>
public class UpdateManager
{
private static readonly string _baseDir = AppDomain.CurrentDomain.BaseDirectory;
@ -40,6 +43,13 @@ namespace Katteker
/// </summary>
public string UrlOrPath => _urlOrPath;
/// <summary>
/// Create the update manager.
/// </summary>
/// <param name="urlOrPath">path to the publishing directory</param>
/// <param name="applicationName">name of the application to update.</param>
/// <param name="rootDirectory">root directory.</param>
/// <returns>the update manager.</returns>
public static UpdateManager Create(string urlOrPath = null, string applicationName = null, string rootDirectory = null)
{
_config = ReadConfigFile();
@ -49,6 +59,14 @@ namespace Katteker
return new UpdateManager(urlOrPath, appName, rootAppDirectory);
}
/// <summary>
/// Try to create the update manager.
/// </summary>
/// <param name="manager">update manager</param>
/// <param name="urlOrPath">path to the publishing directory</param>
/// <param name="applicationName">name of the application to update.</param>
/// <param name="rootDirectory">root directory.</param>
/// <returns>true if the creation success, false otherwise.</returns>
public static bool TryCreate(out UpdateManager manager, string urlOrPath = null, string applicationName = null, string rootDirectory = null)
{
try
@ -62,6 +80,7 @@ namespace Katteker
return false;
}
}
public async Task<IEnumerable<ReleaseEntry>> CheckForUpdateAsync()
{
_releases = Utility.IsWebUrl(_urlOrPath) ? await DownloadIndexAsync(_urlOrPath).ConfigureAwait(false) : GetFromFilesystem(_urlOrPath);
@ -69,6 +88,11 @@ namespace Katteker
return updateInfo.ReleasesToApply;
}
/// <summary>
/// Restart the application.
/// </summary>
/// <param name="exeToStart"></param>
/// <param name="arguments"></param>
public void RestartApp(string exeToStart = null, string arguments = null)
{
exeToStart = exeToStart ?? Path.GetFileName(Assembly.GetEntryAssembly().Location);
@ -81,6 +105,11 @@ namespace Katteker
}
}
/// <summary>
/// Update application.
/// </summary>
/// <param name="progress">The updating process.</param>
/// <returns></returns>
public async Task<bool> UpdateAppAsync(IProgress<int> progress = null)
{
progress?.Report(0);
@ -96,7 +125,7 @@ namespace Katteker
var url = urlOrPath.TrimEnd('/');
url += "/" + Constants.RELEASE;
var content = await new WebClient().DownloadStringTaskAsync(url).ConfigureAwait(false);
var lines = content.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
var lines = content.Split(new[] {'\r', '\n'}, StringSplitOptions.RemoveEmptyEntries);
return new Releases(lines);
}
@ -108,6 +137,7 @@ namespace Katteker
if (!File.Exists(configPath)) throw new FileNotFoundException("Configuration file not found.", configPath);
return KattekerConfig.ReadFromFile(configPath);
}
private static bool VerifyFileChecksum(string targetFile, string lastEntrySha1)
{
var hash = Utility.ComputeFileHash(targetFile);
@ -147,35 +177,28 @@ namespace Katteker
private async Task<bool> UpdateAppImplAsync(ReleaseEntry lastEntry, IProgress<int> progress)
{
try
var targetFile = Path.Combine(_packageDir, lastEntry.Filename);
//download file.
await PutFileInPackageFolderAsync(lastEntry.Filename).ConfigureAwait(false);
progress?.Report(60);
if (!VerifyFileChecksum(targetFile, lastEntry.SHA1)) throw new FileLoadException();
progress?.Report(70);
await KillAppStubAsync().ConfigureAwait(false);
progress?.Report(80);
using (var updater = new Process())
{
var targetFile = Path.Combine(_packageDir, lastEntry.Filename);
//download file.
await PutFileInPackageFolderAsync(lastEntry.Filename).ConfigureAwait(false);
progress?.Report(60);
if (!VerifyFileChecksum(targetFile, lastEntry.SHA1)) throw new FileLoadException();
progress?.Report(70);
await KillAppStubAsync().ConfigureAwait(false);
progress?.Report(80);
using (var updater = new Process())
{
updater.StartInfo = new ProcessStartInfo(targetFile, "/S");
updater.Start();
updater.WaitForExit();
}
progress?.Report(100);
return true;
}
catch (Exception e)
{
Console.WriteLine(e);
updater.StartInfo = new ProcessStartInfo(targetFile, "/S");
updater.Start();
updater.WaitForExit();
}
return false;
progress?.Report(100);
return true;
}
}
}