diff --git a/GitInstaller/GitInstaller.sln b/GitInstaller/GitInstaller.sln
index a4773ae..8b986f4 100644
--- a/GitInstaller/GitInstaller.sln
+++ b/GitInstaller/GitInstaller.sln
@@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.30320.27
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitInstaller", "GitInstaller\GitInstaller.csproj", "{6B88A56A-98E2-450D-A059-65BD18919AE1}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GitInstallerNET5", "..\GitInstallerNET5\GitInstallerNET5\GitInstallerNET5.csproj", "{40E2DF0D-A017-4EBD-844A-92708E425293}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -15,6 +17,10 @@ Global
{6B88A56A-98E2-450D-A059-65BD18919AE1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6B88A56A-98E2-450D-A059-65BD18919AE1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B88A56A-98E2-450D-A059-65BD18919AE1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {40E2DF0D-A017-4EBD-844A-92708E425293}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {40E2DF0D-A017-4EBD-844A-92708E425293}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {40E2DF0D-A017-4EBD-844A-92708E425293}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {40E2DF0D-A017-4EBD-844A-92708E425293}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/GitInstaller/GitInstaller/GitInstaller.csproj b/GitInstaller/GitInstaller/GitInstaller.csproj
index 84e606b..4f865ac 100644
--- a/GitInstaller/GitInstaller/GitInstaller.csproj
+++ b/GitInstaller/GitInstaller/GitInstaller.csproj
@@ -71,11 +71,18 @@
MSBuild:Compile
Designer
+
+ LicenseWindow.xaml
+
ManualWindow.xaml
+
+ Designer
+ MSBuild:Compile
+
MSBuild:Compile
Designer
diff --git a/GitInstaller/GitInstaller/Installer.cs b/GitInstaller/GitInstaller/Installer.cs
index 50e4424..c4ac1a5 100644
--- a/GitInstaller/GitInstaller/Installer.cs
+++ b/GitInstaller/GitInstaller/Installer.cs
@@ -120,11 +120,30 @@ async void GetVersions()
/// The installation directory
internal void StartInstallation(int releaseindex, string installdir)
{
- _window.bt_install.IsEnabled = false;
- _installrelease = Releases[releaseindex];
- _window.WriteLog("Starting installation of release \"" + _installrelease.Tag + "\" to \"" + installdir + "\"...");
- _installdir = installdir;
- DownloadAssets();
+ if(Settings.ShowLicense)
+ {
+ LicenseWindow licenseWindow = new LicenseWindow();
+ if (licenseWindow.ShowDialog() == true)
+ {
+ _window.bt_install.IsEnabled = false;
+ _installrelease = Releases[releaseindex];
+ _window.WriteLog("Starting installation of release \"" + _installrelease.Tag + "\" to \"" + installdir + "\"...");
+ _installdir = installdir;
+ DownloadAssets();
+ }
+ else
+ {
+ _window.WriteLog("You need to accept the license to proceed with the installation.");
+ }
+ }
+ else
+ {
+ _window.bt_install.IsEnabled = false;
+ _installrelease = Releases[releaseindex];
+ _window.WriteLog("Starting installation of release \"" + _installrelease.Tag + "\" to \"" + installdir + "\"...");
+ _installdir = installdir;
+ DownloadAssets();
+ }
}
///
diff --git a/GitInstaller/GitInstaller/LicenseWindow.xaml b/GitInstaller/GitInstaller/LicenseWindow.xaml
new file mode 100644
index 0000000..f5b77ce
--- /dev/null
+++ b/GitInstaller/GitInstaller/LicenseWindow.xaml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Loading License
+ Please wait...
+
+
+
+
+
+
diff --git a/GitInstaller/GitInstaller/LicenseWindow.xaml.cs b/GitInstaller/GitInstaller/LicenseWindow.xaml.cs
new file mode 100644
index 0000000..d35cd43
--- /dev/null
+++ b/GitInstaller/GitInstaller/LicenseWindow.xaml.cs
@@ -0,0 +1,70 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace GitInstaller
+{
+ ///
+ /// Interaktionslogik für LicenseWindow.xaml
+ ///
+ public partial class LicenseWindow : Window
+ {
+ public LicenseWindow()
+ {
+ InitializeComponent();
+ LoadLicense();
+ bt_accept.Click += AcceptClick;
+ bt_decline.Click += DeclineClick;
+
+ bt_accept.IsEnabled = false;
+ }
+
+ private void DeclineClick(object sender, RoutedEventArgs e)
+ {
+ DialogResult = false;
+ Close();
+ }
+
+ private void AcceptClick(object sender, RoutedEventArgs e)
+ {
+ DialogResult = true;
+ Close();
+ }
+
+ async void LoadLicense()
+ {
+ using (var client = new WebClient())
+ {
+ client.Headers.Add("user-agent", "GitInstaller");
+ string licenseJson = await client.DownloadStringTaskAsync(Settings.LicenseUrl.AbsoluteUri);
+ JObject job = JsonConvert.DeserializeObject(licenseJson);
+ //License
+ JToken license = job.Value("license");
+ client.Headers["user-agent"] = "gitinstaller";
+ client.Headers.Add("accept", "application/vnd.github.v3+json");
+ string licJson = await client.DownloadStringTaskAsync(new Uri(license.Value("url")).AbsoluteUri);
+ JObject licobj = JsonConvert.DeserializeObject(licJson);
+ string licenseBody = licobj.Value("body");
+ rtb_license.Document.Blocks.Clear();
+ Paragraph para = new Paragraph();
+ para.Inlines.Add(licenseBody);
+ rtb_license.Document.Blocks.Add(para);
+ }
+
+ bt_accept.IsEnabled = true;
+ }
+ }
+}
diff --git a/GitInstaller/GitInstaller/ManualWindow.xaml b/GitInstaller/GitInstaller/ManualWindow.xaml
index c5249f3..0b5b4b7 100644
--- a/GitInstaller/GitInstaller/ManualWindow.xaml
+++ b/GitInstaller/GitInstaller/ManualWindow.xaml
@@ -5,7 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:GitInstaller"
mc:Ignorable="d"
- Title="ManualWindow" Height="125" Width="400" ResizeMode="NoResize" WindowStartupLocation="CenterOwner">
+ Title="Select Repository:" Height="125" Width="400" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
diff --git a/GitInstaller/GitInstaller/ManualWindow.xaml.cs b/GitInstaller/GitInstaller/ManualWindow.xaml.cs
index b77c7ce..eae74c4 100644
--- a/GitInstaller/GitInstaller/ManualWindow.xaml.cs
+++ b/GitInstaller/GitInstaller/ManualWindow.xaml.cs
@@ -14,6 +14,7 @@ public partial class ManualWindow : Window
public ManualWindow()
{
InitializeComponent();
+ Title = "Select a Repository:";
bt_confirm.Click += ClickConfirm;
}
diff --git a/GitInstaller/GitInstaller/Properties/AssemblyInfo.cs b/GitInstaller/GitInstaller/Properties/AssemblyInfo.cs
index 52ab8bb..978a568 100644
--- a/GitInstaller/GitInstaller/Properties/AssemblyInfo.cs
+++ b/GitInstaller/GitInstaller/Properties/AssemblyInfo.cs
@@ -51,5 +51,5 @@
// 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.8.4.0")]
-[assembly: AssemblyFileVersion("1.8.4.0")]
+[assembly: AssemblyVersion("1.9.1.0")]
+[assembly: AssemblyFileVersion("1.9.1.0")]
diff --git a/GitInstaller/GitInstaller/Settings.cs b/GitInstaller/GitInstaller/Settings.cs
index 005c0fe..e1e69b2 100644
--- a/GitInstaller/GitInstaller/Settings.cs
+++ b/GitInstaller/GitInstaller/Settings.cs
@@ -31,6 +31,7 @@ internal enum SettingsState
internal static bool Unzip { get { return file.unzip; } }
internal static bool Preview { get { return file.preview; } }
internal static bool Uninstall { get { return file.uninstall; } }
+ internal static bool ShowLicense { get { return file.showlicense; } }
internal static string[] Ignored_Tags { get { return file.ignored_tags; } }
internal static string[] Ignored_Files { get { return file.ignored_files; } }
@@ -42,6 +43,11 @@ internal static Uri ApiUrl
get { if (State == SettingsState.Loaded) { return new Uri($"https://api.github.com/repos/{file.user}/{file.repo}/releases"); } else { return null; } }
}
+ internal static Uri LicenseUrl
+ {
+ get { if (State == SettingsState.Loaded) { return new Uri($"https://api.github.com/repos/{file.user}/{file.repo}/license"); } else { return null; } }
+ }
+
///
/// Loads the settings from the config.json inside the applications directory
///
@@ -92,6 +98,7 @@ public class SettingsFile
public bool unzip;
public bool preview;
public bool uninstall;
+ public bool showlicense;
[JsonProperty("ignored-tags")]
public string[] ignored_tags;
[JsonProperty("ignored-files")]
diff --git a/GitInstaller/GitInstaller/config.json b/GitInstaller/GitInstaller/config.json
index 4cc3ffb..6e1f1a6 100644
--- a/GitInstaller/GitInstaller/config.json
+++ b/GitInstaller/GitInstaller/config.json
@@ -5,6 +5,7 @@
"unzip": true,
"preview": true,
"uninstall": true,
- "ignored-tags": ["v1.0"],
- "ignored-files": ["somefiletoignore.zip"]
+ "showlicense": true,
+ "ignored-tags": [ "v1.0" ],
+ "ignored-files": [ "somefiletoignore.zip" ]
}
\ No newline at end of file
diff --git a/GitInstallerNET5/GitInstallerNET5/App.xaml b/GitInstallerNET5/GitInstallerNET5/App.xaml
new file mode 100644
index 0000000..a02a578
--- /dev/null
+++ b/GitInstallerNET5/GitInstallerNET5/App.xaml
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/GitInstallerNET5/GitInstallerNET5/App.xaml.cs b/GitInstallerNET5/GitInstallerNET5/App.xaml.cs
new file mode 100644
index 0000000..85d0be7
--- /dev/null
+++ b/GitInstallerNET5/GitInstallerNET5/App.xaml.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace GitInstallerNET5
+{
+ ///
+ /// Interaction logic for App.xaml
+ ///
+ public partial class App : Application
+ {
+ }
+}
diff --git a/GitInstallerNET5/GitInstallerNET5/AssemblyInfo.cs b/GitInstallerNET5/GitInstallerNET5/AssemblyInfo.cs
new file mode 100644
index 0000000..427f202
--- /dev/null
+++ b/GitInstallerNET5/GitInstallerNET5/AssemblyInfo.cs
@@ -0,0 +1,10 @@
+using System.Windows;
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,
+ // app, or any theme specific resource dictionaries)
+)]
diff --git a/GitInstallerNET5/GitInstallerNET5/GitInstallerNET5.csproj b/GitInstallerNET5/GitInstallerNET5/GitInstallerNET5.csproj
new file mode 100644
index 0000000..a1e2810
--- /dev/null
+++ b/GitInstallerNET5/GitInstallerNET5/GitInstallerNET5.csproj
@@ -0,0 +1,50 @@
+
+
+
+ WinExe
+ net5.0-windows
+ true
+ true
+ GitInstaller
+ GitInstallerNET5
+ Roman Wanner
+ Roman Wanner
+ Simple Installer for Github
+ © Roman Wanner 2020
+ https://github.com/daredloco/GitInstaller/
+ 1.9.0.0
+ 1.9.0.0
+ icon.ico
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ LicenseWindow.xaml
+
+
+
+
+
+ Always
+
+
+
+
+
+ Designer
+
+
+
+
diff --git a/GitInstallerNET5/GitInstallerNET5/Installer.cs b/GitInstallerNET5/GitInstallerNET5/Installer.cs
new file mode 100644
index 0000000..4db0d72
--- /dev/null
+++ b/GitInstallerNET5/GitInstallerNET5/Installer.cs
@@ -0,0 +1,315 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Threading.Tasks;
+using System.Windows;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System.IO.Compression;
+using System.ComponentModel;
+
+namespace GitInstallerNET5
+{
+ internal class Installer
+ {
+ readonly MainWindow _window;
+ readonly Uri _url;
+ string _releasesjson;
+ string _installdir;
+ GitRelease _installrelease;
+ ///
+ /// List of GitRelease objects fetched from Github
+ ///
+ internal List Releases = new List();
+
+ ///
+ /// Installer backend.
+ /// Enter the URL and the backend will start fetching the versions
+ ///
+ /// The url to the Github repo, will be created from the config.json content
+ internal Installer(Uri url)
+ {
+ _url = url;
+ _window = MainWindow.Instance;
+ GetVersions();
+ }
+
+ ///
+ /// Fetches the different versions/releases from the Githup repo
+ ///
+ async void GetVersions()
+ {
+ _window.WriteLog("Trying to fetch releases from GitHub...");
+ _window.prog_loading.IsIndeterminate = true;
+
+ using (var client = new WebClient())
+ {
+ client.Headers.Add("user-agent", "GitInstaller");
+
+ //Save as _releasesjson so you don't have to fetch it again
+ _releasesjson = await client.DownloadStringTaskAsync(_url.AbsoluteUri);
+ _window.WriteLog("Fetched all releases from GitHub...");
+
+ //Create GitRelease objects from the _releasesjson string
+ _window.WriteLog("Creating Release objects...");
+ JObject[] jobjs = JsonConvert.DeserializeObject(_releasesjson);
+ int idcount = 0;
+ Releases.Clear();
+ _window.cb_versions.Items.Clear();
+
+ foreach (JObject job in jobjs)
+ {
+ GitRelease robj = new GitRelease();
+ robj.Id = idcount;
+ robj.Name = job.Value("name");
+ robj.Tag = job.Value("tag_name");
+ robj.Body = job.Value("body");
+ robj.GitUrl = job.Value("html_url");
+ robj.IsPrerelease = job.Value("prerelease");
+ robj.CreationDate = job.Value("created_at");
+
+ //Author
+ JObject authorobj = job.Value("author");
+ robj.AuthorName = authorobj.Value("login");
+ robj.AuthorUrl = authorobj.Value("html_url");
+
+ //Assets
+ JToken assets = job.Value("assets");
+
+ foreach (JToken asset in assets.Children())
+ {
+ GitAsset newasset = new GitAsset();
+ newasset.Filename = asset.Value("name");
+ newasset.DownloadUrl = asset.Value("browser_download_url");
+ newasset.Size = asset.Value("size");
+ robj.Assets.Add(newasset);
+ }
+
+
+ foreach(string ignoredtags in Settings.Ignored_Tags)
+ {
+ if(!Utils.HasWildcard(robj.Tag,ignoredtags))
+ {
+ idcount++;
+ Releases.Add(robj);
+ }
+ }
+ }
+
+ _window.cb_versions.SelectedIndex = 0;
+ }
+ _window.prog_loading.IsIndeterminate = false;
+ if(Releases.Count < 1)
+ {
+ MessageBox.Show("No releases found for this repository! Can't progress with the installation...", "Warning!", MessageBoxButton.OK, MessageBoxImage.Warning);
+ Environment.Exit(2);
+ return;
+ }
+ _window.bt_install.IsEnabled = true;
+ _window.WriteLog("Done creating release objects, " + Releases.Count + " releases added...");
+
+ _window.UpdateVersions(Settings.Preview);
+ _window.UpdateChanges(Releases[0]);
+ }
+
+ ///
+ /// Starts the installation of the release
+ ///
+ /// The index of the release as in the Releases List
+ /// The installation directory
+ internal void StartInstallation(int releaseindex, string installdir)
+ {
+ if (Settings.ShowLicense)
+ {
+ LicenseWindow licenseWindow = new LicenseWindow();
+ if (licenseWindow.ShowDialog() == true)
+ {
+ _window.bt_install.IsEnabled = false;
+ _installrelease = Releases[releaseindex];
+ _window.WriteLog("Starting installation of release \"" + _installrelease.Tag + "\" to \"" + installdir + "\"...");
+ _installdir = installdir;
+ DownloadAssets();
+ }
+ else
+ {
+ _window.WriteLog("You need to accept the license to proceed with the installation.");
+ }
+ }
+ else
+ {
+ _window.bt_install.IsEnabled = false;
+ _installrelease = Releases[releaseindex];
+ _window.WriteLog("Starting installation of release \"" + _installrelease.Tag + "\" to \"" + installdir + "\"...");
+ _installdir = installdir;
+ DownloadAssets();
+ }
+ }
+
+ ///
+ /// Downloads the Assets from the actual Release
+ ///
+ async void DownloadAssets()
+ {
+
+ if(Settings.State != Settings.SettingsState.Loaded)
+ {
+ throw new Exception("Settings aren't loaded, can't progress!");
+ }
+ _window.prog_loading.IsIndeterminate = true;
+ int assetcount = 0;
+ int maxcount = _installrelease.Assets.Count;
+ bool haderror = false;
+ List downloadedfiles = new List();
+
+ foreach(GitAsset asset in _installrelease.Assets)
+ {
+ _window.WriteLog("Downloading asset \"" + asset.Filename + " (" + asset.Size + " bytes)\"");
+ using (var client = new WebClient())
+ {
+ client.Headers.Add("user-agent", "GitInstaller");
+ client.DownloadProgressChanged += FileDownloadChanged;
+ client.DownloadFileCompleted += FileDownloadCompleted;
+
+ try
+ {
+
+ foreach(string ignoredfile in Settings.Ignored_Files)
+ {
+ if(!Utils.HasWildcard(asset.Filename, ignoredfile))
+ {
+ string installfname = Path.Combine(_installdir, asset.Filename);
+ await client.DownloadFileTaskAsync(new Uri(asset.DownloadUrl), installfname);
+ downloadedfiles.Add(installfname);
+ assetcount++;
+ _window.WriteLog($"Asset downloaded... ({assetcount}/{maxcount})");
+ }
+ else
+ {
+ _window.WriteLog($"Asset \"{asset.Filename}\" will be ignored...");
+ assetcount++;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ _window.WriteLog("Error while downloading asset \"" + asset.Filename + "\": " + ex.Message);
+ haderror = true;
+ }
+ }
+ }
+
+ _window.prog_loading.IsIndeterminate = false;
+ if (haderror)
+ {
+ //TODO: Do something if the asset download wasn't successful
+ return;
+ }
+
+ if(Settings.Unzip)
+ UnzipInstalledData(downloadedfiles.ToArray());
+ }
+
+ private void FileDownloadCompleted(object sender, AsyncCompletedEventArgs e)
+ {
+ _window.prog_loading.IsIndeterminate = true;
+ }
+
+ private void FileDownloadChanged(object sender, DownloadProgressChangedEventArgs e)
+ {
+ _window.prog_loading.IsIndeterminate = false;
+ _window.prog_loading.Maximum = 100;
+ _window.prog_loading.Value = e.ProgressPercentage;
+ }
+
+ ///
+ /// Unpacks the files from downloadedfiles
+ ///
+ /// The locations of the downloaded files
+ async void UnzipInstalledData(string[] downloadedfiles)
+ {
+ bool wasSuccess = true;
+ if(IsUpdate(new FileInfo(downloadedfiles[0]).Directory.FullName))
+ {
+ _window.WriteLog("Deleting old files from project");
+ Uninstaller.DoUninstall(new FileInfo(downloadedfiles[0]).Directory.FullName);
+ }
+
+ _window.WriteLog("Unpack zip archives...");
+ _window.prog_loading.IsIndeterminate = true;
+ await Task.Run(() => {
+ foreach (string fname in downloadedfiles)
+ {
+ FileInfo fi = new FileInfo(fname);
+ if (fi.Extension == ".zip")
+ {
+ using(FileStream fs = new FileStream(fname, FileMode.Open))
+ {
+ using(ZipArchive archive = new ZipArchive(fs))
+ {
+ wasSuccess = ZipArchiveExtensions.ExtractWithSettings(archive, fi.DirectoryName, true);
+ }
+ }
+ File.Delete(fname);
+ }
+ }
+ });
+ if(!wasSuccess)
+ {
+ Uninstaller.DoUninstall(new FileInfo(downloadedfiles[0]).DirectoryName);
+ _window.WriteLog("There was an error while extracting the archive!");
+ }
+ else
+ {
+ _window.WriteLog("Installation complete!");
+ }
+ _window.prog_loading.IsIndeterminate = false;
+ _window.bt_install.IsEnabled = true;
+ }
+
+ ///
+ /// Checks if there already exists an installation inside the directory or if its a fresh installation
+ ///
+ /// The installation directory
+ /// True if a gituninstaller.cfg was found, else returns false
+ internal bool IsUpdate(string directory)
+ {
+ string fpath = Path.Combine(directory, "gituninstaller.cfg");
+ if (!File.Exists(fpath))
+ return false;
+
+ string[] flines = File.ReadAllLines(fpath);
+ string firstline = flines[0];
+ if (firstline.EndsWith("###") && firstline.StartsWith("###"))
+ {
+ firstline = firstline.TrimStart('#').TrimEnd('#').Replace(" Uninstaller", "");
+ if (Settings.Project != firstline)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ internal class GitRelease
+ {
+ public int Id; //is the number the release starts 0,1,2,3,4 etc
+ public string Name; //name:
+ public string Tag; //tag_name:
+ public string GitUrl; //html_url:
+ public string CreationDate; //created_at:
+ public bool IsPrerelease; //prerelease:
+ public string AuthorName; //author.login:
+ public string AuthorUrl; //author.html_url:
+ public string Body; //body:
+ public List Assets = new List();
+ }
+
+ internal class GitAsset
+ {
+ public string Filename; ////{assets.asset.}name:
+ public float Size; //{assets.asset.}size:
+ public string DownloadUrl; //{assets.asset.}browser_download_url:
+ }
+ }
+}
diff --git a/GitInstallerNET5/GitInstallerNET5/LicenseWindow.xaml b/GitInstallerNET5/GitInstallerNET5/LicenseWindow.xaml
new file mode 100644
index 0000000..f4e927f
--- /dev/null
+++ b/GitInstallerNET5/GitInstallerNET5/LicenseWindow.xaml
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Loading License
+ Please wait...
+
+
+
+
+
+
diff --git a/GitInstallerNET5/GitInstallerNET5/LicenseWindow.xaml.cs b/GitInstallerNET5/GitInstallerNET5/LicenseWindow.xaml.cs
new file mode 100644
index 0000000..e6f935c
--- /dev/null
+++ b/GitInstallerNET5/GitInstallerNET5/LicenseWindow.xaml.cs
@@ -0,0 +1,70 @@
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace GitInstallerNET5
+{
+ ///
+ /// Interaktionslogik für LicenseWindow.xaml
+ ///
+ public partial class LicenseWindow : Window
+ {
+ public LicenseWindow()
+ {
+ InitializeComponent();
+ LoadLicense();
+ bt_accept.Click += AcceptClick;
+ bt_decline.Click += DeclineClick;
+
+ bt_accept.IsEnabled = false;
+ }
+
+ private void DeclineClick(object sender, RoutedEventArgs e)
+ {
+ DialogResult = false;
+ Close();
+ }
+
+ private void AcceptClick(object sender, RoutedEventArgs e)
+ {
+ DialogResult = true;
+ Close();
+ }
+
+ async void LoadLicense()
+ {
+ using (var client = new WebClient())
+ {
+ client.Headers.Add("user-agent", "GitInstaller");
+ string licenseJson = await client.DownloadStringTaskAsync(Settings.LicenseUrl.AbsoluteUri);
+ JObject job = JsonConvert.DeserializeObject(licenseJson);
+ //License
+ JToken license = job.Value("license");
+ client.Headers["user-agent"] = "gitinstaller";
+ client.Headers.Add("accept", "application/vnd.github.v3+json");
+ string licJson = await client.DownloadStringTaskAsync(new Uri(license.Value("url")).AbsoluteUri);
+ JObject licobj = JsonConvert.DeserializeObject(licJson);
+ string licenseBody = licobj.Value("body");
+ rtb_license.Document.Blocks.Clear();
+ Paragraph para = new Paragraph();
+ para.Inlines.Add(licenseBody);
+ rtb_license.Document.Blocks.Add(para);
+ }
+
+ bt_accept.IsEnabled = true;
+ }
+ }
+}
diff --git a/GitInstallerNET5/GitInstallerNET5/MainWindow.xaml b/GitInstallerNET5/GitInstallerNET5/MainWindow.xaml
new file mode 100644
index 0000000..e423e0a
--- /dev/null
+++ b/GitInstallerNET5/GitInstallerNET5/MainWindow.xaml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/GitInstallerNET5/GitInstallerNET5/MainWindow.xaml.cs b/GitInstallerNET5/GitInstallerNET5/MainWindow.xaml.cs
new file mode 100644
index 0000000..cf2a669
--- /dev/null
+++ b/GitInstallerNET5/GitInstallerNET5/MainWindow.xaml.cs
@@ -0,0 +1,320 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Text.RegularExpressions;
+using System.Windows.Navigation;
+using System.Diagnostics;
+using System.Windows.Media;
+using System.Net;
+using System.IO;
+using System.Drawing;
+using System.Windows.Media.Imaging;
+using Microsoft.Win32;
+
+namespace GitInstallerNET5
+{
+ ///
+ /// Interaktionslogik für MainWindow.xaml
+ ///
+ public partial class MainWindow : Window
+ {
+ readonly Installer installer;
+
+ public static MainWindow Instance;
+
+ public MainWindow()
+ {
+ InitializeComponent();
+ Instance = this;
+ cb_versions.SelectedValuePath = "Key";
+ cb_versions.DisplayMemberPath = "Value";
+ cb_versions.SelectionChanged += VersionChanged;
+ cb_preview.Checked += PreviewChecked;
+ cb_preview.Unchecked += PreviewUnchecked;
+ rtb_log.IsReadOnly = true;
+ bt_uninstall.Click += UninstallClicked;
+ bt_install.IsEnabled = false;
+ bt_install.Click += InstallClicked;
+
+ Settings.Load();
+ if(Settings.State == Settings.SettingsState.Loaded)
+ {
+ Title = Settings.Project + " - Powered by GitInstaller " + Assembly.GetExecutingAssembly().GetName().Version;
+ cb_preview.IsChecked = Settings.Preview;
+ installer = new Installer(Settings.ApiUrl);
+ }
+ else
+ {
+ ManualWindow mwin = new ManualWindow();
+ if(mwin.ShowDialog() == true)
+ {
+ return;
+ }
+ MessageBox.Show("The Installer can't progress because the settings file couldn't loaded!", "Warning!", MessageBoxButton.OK, MessageBoxImage.Warning);
+ Environment.Exit(1);
+ }
+ }
+
+ private void PreviewUnchecked(object sender, RoutedEventArgs e)
+ {
+ UpdateVersions(false);
+ }
+
+ private void PreviewChecked(object sender, RoutedEventArgs e)
+ {
+ UpdateVersions(true);
+ }
+ private void UninstallClicked(object sender, RoutedEventArgs e)
+ {
+ if (System.Windows.MessageBoxResult.Yes != System.Windows.MessageBox.Show("Do you really want to uninstall " + Settings.Project + "?","Are you sure?", System.Windows.MessageBoxButton.YesNo, System.Windows.MessageBoxImage.Question))
+ return;
+
+
+ using (System.Windows.Forms.FolderBrowserDialog fbd = new System.Windows.Forms.FolderBrowserDialog())
+ {
+ fbd.Description = "Choose the installation directory:";
+ var result = fbd.ShowDialog();
+ if (result == System.Windows.Forms.DialogResult.OK)
+ {
+ if (!Uninstaller.DoUninstall(fbd.SelectedPath))
+ MessageBox.Show("Couldn't uninstall the software, read the log for more informations!", "Warning!", MessageBoxButton.OK, MessageBoxImage.Warning);
+ else
+ WriteLog("Software was uninstalled successfuly!");
+ }
+ }
+ }
+
+ private void InstallClicked(object sender, RoutedEventArgs e)
+ {
+ int idx = cb_versions.SelectedIndex;
+ using (System.Windows.Forms.FolderBrowserDialog fbd = new System.Windows.Forms.FolderBrowserDialog())
+ {
+ fbd.Description = "Choose an installation directory:";
+ var result = fbd.ShowDialog();
+ if(result == System.Windows.Forms.DialogResult.OK)
+ {
+ installer.StartInstallation(idx, fbd.SelectedPath);
+ }
+ }
+ }
+
+ private void VersionChanged(object sender, SelectionChangedEventArgs e)
+ {
+ if(cb_versions.SelectedIndex == -1)
+ {
+ return;
+ }
+ KeyValuePair kvp = (KeyValuePair)cb_versions.Items[cb_versions.SelectedIndex];
+ int idx = kvp.Key;
+ if (idx == -1)
+ {
+ rtb_changes.Document.Blocks.Clear();
+ return;
+ }
+
+ try
+ {
+ UpdateChanges(installer.Releases[idx]);
+ }
+ catch(Exception ex)
+ {
+ if (ex.HResult != -2146233086)
+ {
+ MessageBox.Show("There was an unexpected error while changing the version!", "Error!", MessageBoxButton.OK, MessageBoxImage.Error);
+ throw ex;
+ }
+ }
+ }
+
+ public void WriteLog(string msg)
+ {
+ msg = DateTime.Now + ": " + msg;
+ Paragraph para = new Paragraph();
+ para.Inlines.Add(msg);
+ rtb_log.Document.Blocks.Add(para);
+ rtb_log.ScrollToEnd();
+ }
+
+ internal void UpdateChanges(Installer.GitRelease release)
+ {
+ string[] lines = release.Body.Split('\n');
+
+ rtb_changes.Document.Blocks.Clear();
+ foreach (string line in lines)
+ {
+ string newline = line.Replace("\n", "").Replace("\r","");
+ Paragraph para = new Paragraph();
+ para.Margin = new Thickness(0);
+ if (line.StartsWith("###### "))
+ {
+ newline = line.TrimStart('#');
+ para.FontWeight = FontWeights.Medium;
+ }
+ else if (line.StartsWith("##### "))
+ {
+ newline = line.TrimStart('#');
+ para.FontWeight = FontWeights.DemiBold;
+ }
+ else if(line.StartsWith("#### "))
+ {
+ newline = line.TrimStart('#');
+ para.FontWeight = FontWeights.Bold;
+ }
+ else if(line.StartsWith("### "))
+ {
+ newline = line.TrimStart('#');
+ para.FontWeight = FontWeights.ExtraBold;
+ }
+ else if(line.StartsWith("## "))
+ {
+ newline = line.TrimStart('#');
+ para.FontWeight = FontWeights.Black;
+ }
+ else if(line.StartsWith("# "))
+ {
+ newline = line.TrimStart('#');
+ para.FontWeight = FontWeights.ExtraBlack;
+ }
+
+ foreach(string newword in newline.Split(' '))
+ {
+ if(newword.StartsWith("https://") || newword.StartsWith("http://") || newword.StartsWith("www."))
+ {
+ Hyperlink hyperlink = new Hyperlink(new Run(newword)) { NavigateUri = new Uri(newword), IsEnabled = true };
+ hyperlink.RequestNavigate += HyperlinkPressedInChanges;
+ para.Inlines.Add(hyperlink);
+ }
+ else if(newword.StartsWith("#") && int.TryParse(newword.Replace("#", ""), out int n))
+ {
+ string url = $"https://github.com/{Settings.User}/{Settings.Repo}/issues/{newword.Replace("#","")}";
+ Hyperlink hyperlink = new Hyperlink(new Run(newword)) { NavigateUri = new Uri(url), IsEnabled = true };
+ hyperlink.RequestNavigate += HyperlinkPressedInChanges;
+ para.Inlines.Add(hyperlink);
+ }
+ else
+ {
+ //Get Links and Images
+ Match match = Regex.Match(newword, "!\\[.*\\]?\\(.*\\)");
+ bool isLink = false;
+ if(match.Success)
+ {
+ Regex Pattern = new Regex("\\(.*\\)");
+ Regex TitlePattern = new Regex("\\[.*\\]");
+ Match newmatch = Pattern.Match(match.Value);
+ Match newtitlematch = TitlePattern.Match(match.Value);
+ string link = newmatch.Value.Trim('(', ')');
+ string title = newtitlematch.Value.Trim('[', ']');
+ isLink = true;
+ match = match.NextMatch();
+ if (link.StartsWith("www."))
+ link = "http://" + link;
+ if (!link.StartsWith("https://") && !link.StartsWith("http://") && !link.StartsWith("www."))
+ {
+ link = $"https://github.com/{Settings.User}/{Settings.Repo}/{link}";
+ }
+
+ if (link.EndsWith(".jpg") || link.EndsWith(".png"))
+ {
+ try
+ {
+ BitmapImage bitmap = new BitmapImage(new Uri(link));
+ System.Windows.Controls.Image image = new System.Windows.Controls.Image
+ {
+ Source = bitmap
+ };
+ para.Inlines.Add(image);
+ }
+ catch(Exception ex)
+ {
+ WriteLog("Couldn't fetch image from URL '" + link + "', converted it to a link => " + ex.Message);
+ Hyperlink hyperlink = new Hyperlink(new Run(title)) { NavigateUri = new Uri(link), IsEnabled = true };
+ hyperlink.RequestNavigate += HyperlinkPressedInChanges;
+ para.Inlines.Add(hyperlink);
+ }
+
+ }
+ else
+ {
+ Hyperlink hyperlink = new Hyperlink(new Run(title)) { NavigateUri = new Uri(link), IsEnabled = true };
+ hyperlink.RequestNavigate += HyperlinkPressedInChanges;
+ para.Inlines.Add(hyperlink);
+ }
+ }
+
+ //OLD
+ //while (match.Success)
+ //{
+ // Regex Pattern = new Regex("\\(.*\\)");
+ // Regex TitlePattern = new Regex("\\[.*\\]");
+ // Match newmatch = Pattern.Match(match.Value);
+ // Match newtitlematch = TitlePattern.Match(match.Value);
+ // string link = newmatch.Value.Trim('(', ')');
+ // string title = newtitlematch.Value.Trim('[', ']');
+ // WriteLog(match.Value + " => " + link + "-" + title);
+ // isLink = true;
+ // match = match.NextMatch();
+ // if (!link.StartsWith("https://") && !link.StartsWith("http://") && !link.StartsWith("www."))
+ // {
+ // link = $"https://github.com/{Settings.User}/{Settings.Repo}/{link}";
+ // }
+
+ // if (link.EndsWith(".jpg") || link.EndsWith(".png"))
+ // {
+ // BitmapImage bitmap = new BitmapImage(new Uri(link));
+ // System.Windows.Controls.Image image = new System.Windows.Controls.Image
+ // {
+ // Source = bitmap
+ // };
+ // para.Inlines.Add(image);
+ // }
+ // else
+ // {
+ // Hyperlink hyperlink = new Hyperlink(new Run(title)) { NavigateUri = new Uri(link), IsEnabled = true };
+ // hyperlink.RequestNavigate += HyperlinkPressedInChanges;
+ // para.Inlines.Add(hyperlink);
+ // }
+ //}
+
+ if(!isLink)
+ para.Inlines.Add(new Run(newword));
+ }
+ para.Inlines.Add(" ");
+ }
+
+ rtb_changes.Document.Blocks.Add(para);
+ }
+ }
+
+ private void HyperlinkPressedInChanges(object sender, RequestNavigateEventArgs e)
+ {
+ Process.Start(e.Uri.ToString());
+ }
+
+ internal void UpdateVersions(bool withpreviews)
+ {
+ cb_versions.Items.Clear();
+ if (installer == null)
+ return;
+ foreach (Installer.GitRelease release in installer.Releases)
+ {
+ if (withpreviews)
+ cb_versions.Items.Add(new KeyValuePair(release.Id, release.Tag));
+ else if (!withpreviews && !release.IsPrerelease)
+ cb_versions.Items.Add(new KeyValuePair(release.Id, release.Tag));
+ }
+ if(cb_versions.Items.Count < 1)
+ {
+ cb_versions.Items.Add(new KeyValuePair(-1, "None"));
+ bt_install.IsEnabled = false;
+ }
+ else
+ {
+ bt_install.IsEnabled = true;
+ }
+ cb_versions.SelectedIndex = 0;
+ }
+ }
+}
diff --git a/GitInstallerNET5/GitInstallerNET5/ManualWindow.xaml b/GitInstallerNET5/GitInstallerNET5/ManualWindow.xaml
new file mode 100644
index 0000000..99ca102
--- /dev/null
+++ b/GitInstallerNET5/GitInstallerNET5/ManualWindow.xaml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/GitInstallerNET5/GitInstallerNET5/ManualWindow.xaml.cs b/GitInstallerNET5/GitInstallerNET5/ManualWindow.xaml.cs
new file mode 100644
index 0000000..2a257a5
--- /dev/null
+++ b/GitInstallerNET5/GitInstallerNET5/ManualWindow.xaml.cs
@@ -0,0 +1,59 @@
+using Newtonsoft.Json;
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Windows;
+
+namespace GitInstallerNET5
+{
+ ///
+ /// Interaktionslogik für ManualWindow.xaml
+ ///
+ public partial class ManualWindow : Window
+ {
+ public ManualWindow()
+ {
+ InitializeComponent();
+ Title = "Select a Repository:";
+ bt_confirm.Click += ClickConfirm;
+ }
+
+ private void ClickConfirm(object sender, RoutedEventArgs e)
+ {
+ try
+ {
+
+ Uri url = new Uri(tb_url.Text);
+ if (url.Host != "github.com" && url.Host != "www.github.com")
+ {
+ MessageBox.Show("Invalid URL. Needs to be a github.com url!", "Warning!", MessageBoxButton.OK, MessageBoxImage.Warning);
+ return;
+ }
+
+ string ustr = url.AbsoluteUri;
+ ustr = ustr.Replace("://", "");
+
+ Settings.SettingsFile sfile = new Settings.SettingsFile()
+ {
+ ignored_files = new string[] { "" },
+ ignored_tags = new string[] { "" },
+ project = ustr.Split('/')[2],
+ uninstall = false,
+ unzip = true,
+ preview = true,
+ user = ustr.Split('/')[1],
+ repo = ustr.Split('/')[2]
+ };
+ string jsondata = JsonConvert.SerializeObject(sfile);
+ File.WriteAllText("config.json", jsondata);
+ Process.Start("GitInstaller.exe");
+ Environment.Exit(4);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show("Error creating configuration file... => " + ex.Message, "Error!", MessageBoxButton.OK, MessageBoxImage.Error);
+ return;
+ }
+ }
+ }
+}
diff --git a/GitInstallerNET5/GitInstallerNET5/Settings.cs b/GitInstallerNET5/GitInstallerNET5/Settings.cs
new file mode 100644
index 0000000..e89805b
--- /dev/null
+++ b/GitInstallerNET5/GitInstallerNET5/Settings.cs
@@ -0,0 +1,110 @@
+using System;
+using System.IO;
+using System.Windows;
+using Newtonsoft.Json;
+
+namespace GitInstallerNET5
+{
+ internal static class Settings
+ {
+ internal enum SettingsState
+ {
+ NotLoaded,
+ Loaded,
+ NotFound,
+ Invalid
+ }
+
+ ///
+ /// The actual state of the settings.
+ ///
+ internal static SettingsState State { get; private set; } = SettingsState.NotLoaded;
+ static readonly string _path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"config.json");
+ ///
+ /// a representation of the settingsfile
+ ///
+ internal static SettingsFile file;
+
+ internal static string Project { get { return file.project; } }
+ internal static string User { get { return file.user; } }
+ internal static string Repo { get { return file.repo; } }
+ internal static bool Unzip { get { return file.unzip; } }
+ internal static bool Preview { get { return file.preview; } }
+ internal static bool Uninstall { get { return file.uninstall; } }
+ internal static bool ShowLicense { get { return file.showlicense; } }
+ internal static string[] Ignored_Tags { get { return file.ignored_tags; } }
+ internal static string[] Ignored_Files { get { return file.ignored_files; } }
+
+ ///
+ /// Returns the Url to the Releases of the GitHub Api or NULL if settings aren't loaded
+ ///
+ internal static Uri ApiUrl
+ {
+ get { if (State == SettingsState.Loaded) { return new Uri($"https://api.github.com/repos/{file.user}/{file.repo}/releases"); } else { return null; } }
+ }
+
+ internal static Uri LicenseUrl
+ {
+ get { if (State == SettingsState.Loaded) { return new Uri($"https://api.github.com/repos/{file.user}/{file.repo}/license"); } else { return null; } }
+ }
+
+ ///
+ /// Loads the settings from the config.json inside the applications directory
+ ///
+ internal static void Load()
+ {
+ switch(State)
+ {
+ case SettingsState.Loaded:
+ MessageBox.Show("Settings are already loaded!");
+ break;
+ case SettingsState.NotLoaded:
+ if(!File.Exists(_path))
+ {
+ State = SettingsState.NotFound;
+ Load();
+ return;
+ }
+ file = JsonConvert.DeserializeObject(File.ReadAllText(_path));
+ if(file == null)
+ {
+ State = SettingsState.Invalid;
+ Load();
+ return;
+ }
+ if(file.user == null || file.project == null || file.repo == null || file.ignored_tags == null)
+ {
+ State = SettingsState.Invalid;
+ Load();
+ return;
+ }
+ State = SettingsState.Loaded;
+ break;
+ case SettingsState.NotFound:
+ MessageBox.Show("Couldn't find settings file!");
+ break;
+ case SettingsState.Invalid:
+ MessageBox.Show("The settings file is invalid!");
+ break;
+ }
+ }
+
+ [Serializable]
+ public class SettingsFile
+ {
+ public string project;
+ public string user;
+ public string repo;
+ public bool unzip;
+ public bool preview;
+ public bool uninstall;
+ public bool showlicense;
+ [JsonProperty("ignored-tags")]
+ public string[] ignored_tags;
+ [JsonProperty("ignored-files")]
+ public string[] ignored_files;
+
+ public SettingsFile() { }
+ }
+ }
+}
diff --git a/GitInstallerNET5/GitInstallerNET5/Uninstaller.cs b/GitInstallerNET5/GitInstallerNET5/Uninstaller.cs
new file mode 100644
index 0000000..f778153
--- /dev/null
+++ b/GitInstallerNET5/GitInstallerNET5/Uninstaller.cs
@@ -0,0 +1,149 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+
+namespace GitInstallerNET5
+{
+ public class Uninstaller
+ {
+ public string location;
+ public List files = new List();
+ public List directories = new List();
+
+ public Uninstaller(string loca)
+ {
+ location = loca;
+ }
+
+ public Uninstaller(string loca, string[] fs, string[] dirs)
+ {
+ location = loca;
+ files.AddRange(fs);
+ directories.AddRange(dirs);
+ }
+
+ ///
+ /// Generates a gituninstaller.cfg file inside the installation directory
+ ///
+ public void GenerateFile()
+ {
+ string fname = Path.Combine(location, "gituninstaller.cfg");
+ List flines = new List() { $"###{Settings.Project} Uninstaller###" };
+ flines.Add("This is a file generated by GitInstaller, ");
+ flines.Add("to use it either install a newer version of the software installed with it");
+ flines.Add("or open the GitInstaller for this application, select this folder and press \"Uninstall\"");
+
+ flines.Add("###FILES###");
+ foreach (string f in files)
+ {
+ flines.Add(f);
+ }
+
+ flines.Add("###DIRECTORIES###");
+ foreach (string d in directories)
+ {
+ flines.Add(d);
+ }
+
+ File.WriteAllLines(fname, flines.ToArray());
+ }
+
+ ///
+ /// Uninstall the installation at the location. Won't work if it can't find a gituninstaller.cfg file!
+ ///
+ /// The location of the installation
+ /// True if uninstall was a success, else returns false
+ public static bool DoUninstall(string flocation)
+ {
+ MainWindow.Instance.prog_loading.IsIndeterminate = true;
+ flocation = Path.Combine(flocation, "gituninstaller.cfg");
+ if (!File.Exists(flocation))
+ {
+ MainWindow.Instance.prog_loading.IsIndeterminate = false;
+ MainWindow.Instance.WriteLog("Couldn't find gituninstaller.cfg, did you choose the right path?");
+ return false;
+ }
+
+ MainWindow.Instance.WriteLog("Starting uninstall process");
+ bool infiles = false;
+ bool indirs = false;
+ bool wassuccess = true;
+
+ string[] flines = File.ReadAllLines(flocation);
+ string firstline = flines[0];
+ if(firstline.EndsWith("###") && firstline.StartsWith("###"))
+ {
+ firstline = firstline.TrimStart('#').TrimEnd('#').Replace(" Uninstaller", "");
+ if (Settings.Project != firstline)
+ {
+ MainWindow.Instance.prog_loading.IsIndeterminate = false;
+ MainWindow.Instance.WriteLog("This is the invalid installation for this project!");
+ return false;
+ }
+ }
+ else
+ {
+ MainWindow.Instance.prog_loading.IsIndeterminate = false;
+ MainWindow.Instance.WriteLog("Cant check if this is the right directory because the gituninstaller.cfg is corrupted!");
+ return false;
+ }
+
+ foreach(string fline in flines)
+ {
+ if(fline != "")
+ {
+ if (infiles && fline != "###FILES###" && fline != "###DIRECTORIES###")
+ {
+ try
+ {
+ if (!File.Exists(fline))
+ throw new Exception("File \"" + fline + "\" does not exist");
+ FileInfo fi = new FileInfo(fline);
+ string folderpath = fi.Directory.FullName;
+ File.Delete(fline);
+ bool folderhasfiles = Directory.EnumerateFiles(folderpath).Any();
+ if (!folderhasfiles)
+ Directory.Delete(folderpath);
+ MainWindow.Instance.WriteLog("File \"" + fline + "\" deleted!");
+ }
+ catch (Exception ex)
+ {
+ MainWindow.Instance.WriteLog("Couldn't delete file \"" + fline + "\" => " + ex.Message);
+ wassuccess = false;
+ }
+ }
+ else if (indirs && fline != "###FILES###" && fline != "###DIRECTORIES###")
+ {
+ try
+ {
+ if (!Directory.Exists(fline))
+ throw new Exception("Directory \"" + fline + "\" does not exist");
+ Directory.Delete(fline, true);
+ MainWindow.Instance.WriteLog("Directory \"" + fline + "\" deleted!");
+ }
+ catch (Exception ex)
+ {
+ MainWindow.Instance.WriteLog("Couldn't delete directory \"" + fline + "\" => " + ex.Message);
+ wassuccess = false;
+ }
+ }
+ else if (fline == "###FILES###")
+ {
+ infiles = true;
+ indirs = false;
+ }
+ else if (fline == "###DIRECTORIES###")
+ {
+ infiles = false;
+ indirs = true;
+ }
+
+ }
+ }
+ File.Delete(flocation);
+ MainWindow.Instance.prog_loading.IsIndeterminate = false;
+ return wassuccess;
+ }
+ }
+}
diff --git a/GitInstallerNET5/GitInstallerNET5/Utils.cs b/GitInstallerNET5/GitInstallerNET5/Utils.cs
new file mode 100644
index 0000000..c193ccb
--- /dev/null
+++ b/GitInstallerNET5/GitInstallerNET5/Utils.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.IO;
+
+namespace GitInstallerNET5
+{
+ public static class Utils
+ {
+ public enum ZipType
+ {
+ File,
+ Directory,
+ None
+ }
+
+ ///
+ /// Checks if the ZipType of the path is ZipType.File or ZipType.Directory
+ ///
+ /// The path of the file/directory
+ /// A ZipType object (either ZipType.Directory or ZipType.File)
+ public static ZipType FileOrDir(string path)
+ {
+ if (path.EndsWith("/"))
+ return ZipType.Directory;
+ else
+ return ZipType.File;
+ }
+
+ ///
+ /// Checks if value has wildcard in it
+ ///
+ /// The value to check if the wildcard is inside
+ /// The wildcard search value
+ /// The character representing the wildcard
+ /// True if wildcard is inside value or false otherwise
+ public static bool HasWildcard(string value, string wildcard, string wildcardchar = "*")
+ {
+
+ if(wildcard.StartsWith(wildcardchar))
+ {
+ wildcard = wildcard.Remove(0, 1);
+ if (value.EndsWith(wildcard))
+ return true;
+ }
+ else if(wildcard.EndsWith(wildcardchar))
+ {
+ wildcard = wildcard.Remove(wildcard.Length - 1);
+ if (value.StartsWith(wildcard))
+ return true;
+ }
+ else
+ {
+ if (value == wildcard)
+ return true;
+ }
+ return false;
+ }
+
+ ///
+ /// Checks whether the file can be writte to or if its blocked by another process
+ ///
+ /// The filename
+ /// True if the file can be written to and false if it can't
+ public static bool CanBeWrittenTo(string fname)
+ {
+ if (!File.Exists(fname))
+ return true;
+ try
+ {
+ FileStream fs = new FileStream(fname, FileMode.Open, FileAccess.Write);
+ fs.Close();
+ return true;
+ }
+ catch (IOException)
+ {
+ return false;
+ }
+ catch (Exception ex)
+ {
+ throw ex;
+ }
+ }
+ }
+}
diff --git a/GitInstallerNET5/GitInstallerNET5/ZipArchiveExtensions.cs b/GitInstallerNET5/GitInstallerNET5/ZipArchiveExtensions.cs
new file mode 100644
index 0000000..fa42b02
--- /dev/null
+++ b/GitInstallerNET5/GitInstallerNET5/ZipArchiveExtensions.cs
@@ -0,0 +1,123 @@
+using System;
+using System.IO;
+using System.IO.Compression;
+using System.Windows;
+
+namespace GitInstallerNET5
+{
+ public static class ZipArchiveExtensions
+ {
+ // From https://stackoverflow.com/questions/14795197/forcefully-replacing-existing-files-during-extracting-file-using-system-io-compr/30425148
+ ///
+ /// Extracts a ZipArchive to a destination (with overwrite functionality)
+ ///
+ /// The archive to unpack
+ /// The destination directory
+ /// If true, it will overwrite the content inside the destination directory
+ public static bool ExtractToDirectory(this ZipArchive archive, string destinationDirectoryName, bool overwrite)
+ {
+ Uninstaller uninstaller = new Uninstaller(destinationDirectoryName);
+ bool extractionSuccessful = true;
+ if (!overwrite)
+ {
+ try
+ {
+ archive.ExtractToDirectory(destinationDirectoryName);
+ uninstaller.directories.Add(destinationDirectoryName);
+ if (Settings.Uninstall)
+ uninstaller.GenerateFile();
+ return true;
+ }
+ catch(Exception ex)
+ {
+ MessageBox.Show("Exception while extracting files to directory! => " + ex.Message, "Exception", MessageBoxButton.OK, MessageBoxImage.Error);
+ return false;
+ }
+ }
+
+ foreach (ZipArchiveEntry file in archive.Entries)
+ {
+ string completeFileName = Path.Combine(destinationDirectoryName, file.FullName);
+ string directory = Path.GetDirectoryName(completeFileName);
+
+ if (!Directory.Exists(directory))
+ Directory.CreateDirectory(directory);
+
+ if (!string.IsNullOrEmpty(file.Name) && file.Name != "zipsettings.json")
+ {
+ while (!Utils.CanBeWrittenTo(completeFileName))
+ {
+ if (MessageBoxResult.Cancel == MessageBox.Show($"The file '{completeFileName}' is locked or in use and can't be overwritten! Please close the process thats blocking it and press OK or press CANCEL to stop the installing process.", "Warning!", MessageBoxButton.OKCancel, MessageBoxImage.Warning))
+ {
+ MessageBox.Show("Can't progress with the installation!", "Exception", MessageBoxButton.OK, MessageBoxImage.Error);
+ extractionSuccessful = false;
+ break;
+ }
+ }
+ if (!extractionSuccessful)
+ break;
+ file.ExtractToFile(completeFileName, true);
+ uninstaller.files.Add(completeFileName);
+ }
+ }
+ if(Settings.Uninstall)
+ uninstaller.GenerateFile();
+
+ if (!extractionSuccessful)
+ return false;
+ return true;
+ }
+
+ //Added by daRedLoCo
+ ///
+ /// Extracts a ZipArchive to a destination (with overwrite functionality and ZipSettings inside the archive)
+ ///
+ /// The archive to unpack
+ /// The destination directory
+ /// If true, it will overwrite the content inside the destination directory
+ public static bool ExtractWithSettings(this ZipArchive archive, string destinationDirectoryName, bool overwrite)
+ {
+ ZipSettings settings = null;
+ bool extractionSuccessful = true;
+ if(archive.GetEntry("zipsettings.json") != null)
+ settings = ZipSettings.FromStream(archive.GetEntry("zipsettings.json").Open());
+ if(settings == null || settings.Subfolders.Count < 1)
+ {
+ return ExtractToDirectory(archive, destinationDirectoryName, overwrite);
+ }
+ Uninstaller uninstaller = new Uninstaller(destinationDirectoryName);
+ foreach(ZipArchiveEntry file in archive.Entries)
+ {
+ string completeFileName = Path.Combine(destinationDirectoryName, settings.GetSubfolder(file.FullName), file.FullName);
+ string directory = Path.GetDirectoryName(completeFileName);
+
+ if (!Directory.Exists(directory))
+ Directory.CreateDirectory(directory);
+
+ if (!string.IsNullOrEmpty(file.Name) && file.Name != "zipsettings.json")
+ {
+ while(!Utils.CanBeWrittenTo(completeFileName))
+ {
+ if(MessageBoxResult.Cancel == MessageBox.Show($"The file '{completeFileName}' is locked or in use and can't be overwritten! Please close the process thats blocking it and press OK or press CANCEL to stop the installing process.", "Warning!", MessageBoxButton.OKCancel, MessageBoxImage.Warning))
+ {
+ MessageBox.Show("Can't progress with the installation!", "Exception", MessageBoxButton.OK, MessageBoxImage.Error);
+ extractionSuccessful = false;
+ break;
+ }
+ }
+ if (!extractionSuccessful)
+ break;
+ file.ExtractToFile(completeFileName, overwrite);
+ uninstaller.files.Add(completeFileName);
+ }
+ }
+ if(Settings.Uninstall)
+ uninstaller.GenerateFile();
+
+
+ if (!extractionSuccessful)
+ return false;
+ return true;
+ }
+ }
+}
diff --git a/GitInstallerNET5/GitInstallerNET5/ZipSettings.cs b/GitInstallerNET5/GitInstallerNET5/ZipSettings.cs
new file mode 100644
index 0000000..3cf1b68
--- /dev/null
+++ b/GitInstallerNET5/GitInstallerNET5/ZipSettings.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace GitInstallerNET5
+{
+ public class ZipSettings
+ {
+ public List Subfolders = new List();
+
+ public ZipSettings() { }
+
+ ///
+ /// Gets the subfolder of a file
+ ///
+ /// The file to fetch the subfolder for
+ /// The subfolder for the file
+ public string GetSubfolder(string fname)
+ {
+ SubFolder sf = null;
+ string ffolder = fname.Replace(fname.Split('/')[fname.Split('/').Length - 1], "").Replace(fname.Split('\\')[fname.Split('\\').Length - 1],"");
+ sf = Subfolders.Find(x => x.Directories.Find(y => y == ffolder) != null);
+ sf = Subfolders.Find(x => x.Files.Find(y => y == fname) != null);
+ if (sf == null)
+ return "";
+
+ return sf.Name;
+ }
+
+ ///
+ /// Returns the ZipSettings from a File
+ ///
+ /// The file containing the ZipSettings
+ /// A ZipSettings object
+ public static ZipSettings FromFile(string fname)
+ {
+ if (File.Exists(fname))
+ {
+ using (FileStream fs = new FileStream(fname, FileMode.Open))
+ return FromStream(fs);
+ }
+ return null;
+ }
+
+ ///
+ /// Returns the ZipSettings from a Stream
+ ///
+ /// The stream with the ZipSettings
+ /// A ZipSettings object
+ public static ZipSettings FromStream(Stream stream)
+ {
+ using (StreamReader reader = new StreamReader(stream))
+ {
+ try
+ {
+ string jsonstr = reader.ReadToEnd();
+ ZipSettings zs = new ZipSettings();
+ JObject obj = JsonConvert.DeserializeObject(jsonstr);
+ JArray foldersarray = obj.Value("Subfolders");
+ foreach (JObject subdir in foldersarray.Children())
+ {
+ SubFolder sub = new SubFolder();
+ foreach (var dict in subdir)
+ {
+ sub.Name = dict.Key;
+ foreach (JToken token in dict.Value.Children().ToList())
+ {
+ Utils.ZipType ztype = Utils.FileOrDir(token.Value());
+ if (ztype == Utils.ZipType.File)
+ sub.Files.Add(token.Value());
+ else if (ztype == Utils.ZipType.Directory)
+ sub.Directories.Add(token.Value());
+ }
+ }
+ zs.Subfolders.Add(sub);
+ }
+ return zs;
+ }
+ catch (Exception ex)
+ {
+ MainWindow.Instance.WriteLog("There was an error while reading the ZipSettings! => " + ex.Message);
+ return null;
+ }
+ }
+ }
+
+ public class SubFolder
+ {
+ public string Name;
+ public List Files = new List();
+ public List Directories = new List();
+ }
+ }
+}
diff --git a/GitInstallerNET5/GitInstallerNET5/config.json b/GitInstallerNET5/GitInstallerNET5/config.json
new file mode 100644
index 0000000..6e1f1a6
--- /dev/null
+++ b/GitInstallerNET5/GitInstallerNET5/config.json
@@ -0,0 +1,11 @@
+{
+ "project": "GitInstaller",
+ "user": "daredloco",
+ "repo": "GitInstaller",
+ "unzip": true,
+ "preview": true,
+ "uninstall": true,
+ "showlicense": true,
+ "ignored-tags": [ "v1.0" ],
+ "ignored-files": [ "somefiletoignore.zip" ]
+}
\ No newline at end of file
diff --git a/GitInstallerNET5/GitInstallerNET5/icon.ico b/GitInstallerNET5/GitInstallerNET5/icon.ico
new file mode 100644
index 0000000..acfba32
Binary files /dev/null and b/GitInstallerNET5/GitInstallerNET5/icon.ico differ