From dcd26b83aaee31c4f78057992ba6c90621a91c64 Mon Sep 17 00:00:00 2001 From: BlubbFish Date: Tue, 25 Apr 2017 20:44:17 +0000 Subject: [PATCH] [WP] Update functionality --- CmdArgs.cs | 5 ++- EventArgsHelper.cs | 35 ++++++++++++++++++ OwnObject.cs | 14 ------- Properties/AssemblyInfo.cs | 4 +- Updater.cs | 73 ++++++++++++++++++++----------------- Utils.csproj | 1 + bin/Release/Utils.dll | Bin 22016 -> 23552 bytes 7 files changed, 81 insertions(+), 51 deletions(-) create mode 100644 EventArgsHelper.cs diff --git a/CmdArgs.cs b/CmdArgs.cs index fb6f2cc..78cd539 100644 --- a/CmdArgs.cs +++ b/CmdArgs.cs @@ -12,7 +12,7 @@ namespace BlubbFish.Utils Touple } #region Classes - public class VaildArguments + public struct VaildArguments { public VaildArguments(ArgLength length, Boolean required) { @@ -28,7 +28,7 @@ namespace BlubbFish.Utils public ArgLength Length { get; private set; } public Boolean Required { get; private set; } } - private class ArgTouple + private struct ArgTouple { public ArgTouple(String type, String data) { @@ -38,6 +38,7 @@ namespace BlubbFish.Utils public ArgTouple(String type) { this.Type = type; + this.Data = ""; } public String Type { get; private set; } public String Data { get; private set; } diff --git a/EventArgsHelper.cs b/EventArgsHelper.cs new file mode 100644 index 0000000..ea64ba7 --- /dev/null +++ b/EventArgsHelper.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; + +namespace BlubbFish.Utils { + public class UpdaterEventArgs : EventArgs { + public UpdaterEventArgs(Boolean hasUpdates, String message) { + this.HasUpdates = hasUpdates; + this.Message = message; + } + public String Message { get; private set; } + public Boolean HasUpdates { get; private set; } + } + + public class UpdaterFailEventArgs : EventArgs { + public UpdaterFailEventArgs(Exception e) { + this.Except = e; + } + + public Exception Except { get; private set; } + } + + public class LogEventArgs : EventArgs { + public LogEventArgs(String location, String message, OwnObject.LogLevel level, DateTime date) { + this.Location = location; + this.Message = message; + this.Level = level; + this.Date = date; + } + + public String Location { get; private set; } + public String Message { get; private set; } + public OwnObject.LogLevel Level { get; private set; } + public DateTime Date { get; private set; } + } +} diff --git a/OwnObject.cs b/OwnObject.cs index 4c446f6..6d95211 100644 --- a/OwnObject.cs +++ b/OwnObject.cs @@ -37,20 +37,6 @@ namespace BlubbFish.Utils } } - public class LogEventArgs : EventArgs { - public LogEventArgs(String location, String message, LogLevel level, DateTime date) { - this.Location = location; - this.Message = message; - this.Level = level; - this.Date = date; - } - - public String Location { get; private set; } - public String Message { get; private set; } - public LogLevel Level { get; private set; } - public DateTime Date { get; private set; } - } - private List loglist = new List(); public delegate void LogEvent(Object sender, LogEventArgs e); diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 96a6ef3..bac759f 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -32,5 +32,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.2.6")] -[assembly: AssemblyFileVersion("1.0.2.6")] +[assembly: AssemblyVersion("1.0.3.1")] +[assembly: AssemblyFileVersion("1.0.3.1")] diff --git a/Updater.cs b/Updater.cs index 784b191..3bd3631 100644 --- a/Updater.cs +++ b/Updater.cs @@ -1,5 +1,6 @@  using System; +using System.Collections.Generic; using System.IO; using System.Net; using System.Reflection; @@ -13,40 +14,29 @@ namespace BlubbFish.Utils { private static Updater instances; private String url; private VersionInfo[] versions; - - public class UpdaterEventArgs : EventArgs { - public UpdaterEventArgs(Boolean hasUpdates, String message) { - this.HasUpdates = hasUpdates; - this.Message = message; - } - - public String Message { get; private set; } - public Boolean HasUpdates { get; private set; } - } + private Thread t; public struct VersionInfo { - public VersionInfo(String name, String version, String filename, String guid) { - this.Name = name; - this.Version = version; - this.Filename = filename; - this.GUID = guid; - } public VersionInfo(Type type) { this.Name = type.Assembly.GetName().Name; this.Version = type.Assembly.GetName().Version.ToString(); this.Filename = type.Assembly.ManifestModule.Name; this.GUID = ((GuidAttribute)type.Assembly.GetCustomAttribute(typeof(GuidAttribute))).Value; + this.HasUpdate = false; } public String Name { get; private set; } public String Version { get; private set; } public String Filename { get; private set; } public String GUID { get; private set; } + public Boolean HasUpdate { get; set; } } public delegate void UpdateStatus(Object sender, UpdaterEventArgs e); + public delegate void UpdateFail(Object sender, UpdaterFailEventArgs e); public event UpdateStatus UpdateResult; + public event UpdateFail ErrorRaised; private Updater() { } @@ -66,7 +56,7 @@ namespace BlubbFish.Utils { /// Waits for the Result of the Updater thread. /// public void WaitForExit() { - throw new NotImplementedException(); + while (this.t.ThreadState == ThreadState.Running) { } } /// @@ -104,41 +94,58 @@ namespace BlubbFish.Utils { /// public void Check() { if(this.url == "") { - throw new ArgumentException("You must set url first."); + throw new ArgumentException("Zuerst eine URL setzen!"); } if(this.versions.Length == 0) { - throw new ArgumentException("You must set a Version number first."); + throw new ArgumentException("Zuerst Dateien registrieren!"); } if(this.UpdateResult == null) { - throw new ArgumentNullException("You must attach an event first."); + throw new ArgumentNullException("Zuerst das Update Event anhängen."); } - Thread t = new Thread(this.Runner); - t.Start(); + this.t = new Thread(this.Runner); + this.t.Start(); } private void Runner() { - Thread.Sleep(1000); - WebRequest request = WebRequest.Create(this.url + "version.xml"); - WebResponse response = null; + Thread.Sleep(1); try { - response = request.GetResponse(); - } catch(WebException e) { - this.UpdateResult(this, new UpdaterEventArgs(false, e.Message)); + Stream stream = WebRequest.Create(this.url + "version.xml").GetResponse().GetResponseStream(); + String content = new StreamReader(stream).ReadToEnd(); + List updates = new List(); + XmlDocument doc = new XmlDocument(); + doc.LoadXml(content); + foreach (XmlNode node in doc.DocumentElement.ChildNodes) { + String guid = node.Attributes["GUID"].Value; + String version = node.Attributes["Version"].Value; + for(Int32 i=0;i 0) { + this.UpdateResult(this, new UpdaterEventArgs(true, "Update verfügbar")); + return; + } + } catch (Exception e) { + this.ErrorRaised?.Invoke(this, new UpdaterFailEventArgs(e)); return; } - Stream stream = response.GetResponseStream(); - StreamReader reader = new StreamReader(stream); - String content = reader.ReadToEnd(); + this.UpdateResult(this, new UpdaterEventArgs(false, "Kein Update verfügbar")); } /// /// Update the file /// - /// The filename of the targetfile - /// The url of the sourcefile /// Updates the Programm after it has been closed /// public Boolean Update(Boolean afterExit = true) { + try { + + } catch(Exception e) { + this.ErrorRaised?.Invoke(this, new UpdaterFailEventArgs(e)); + return false; + } return true; } } diff --git a/Utils.csproj b/Utils.csproj index 71406a3..cc29b82 100644 --- a/Utils.csproj +++ b/Utils.csproj @@ -41,6 +41,7 @@ + diff --git a/bin/Release/Utils.dll b/bin/Release/Utils.dll index b21d53cec5e6330b8eab1caded4e0f6ce44f56a2..c6d2cdc74684bbe4084fe275b42a90dd43d2b87d 100644 GIT binary patch literal 23552 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 literal 22016 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