diff --git a/UpTool2/App.cs b/UpTool2/App.cs new file mode 100644 index 0000000..2f4a6d5 --- /dev/null +++ b/UpTool2/App.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Xml.Linq; + +namespace UpTool2 +{ + public struct App : IEquatable + { + public string name; + public string description; + public int version; + public string file; + public bool local; + public string hash; + public Guid ID; + public Color color; + public Image icon; + public bool runnable; + public string mainFile; + + public App(string name, string description, int version, string file, bool local, string hash, Guid iD, Color color, Image icon, bool runnable, string mainFile) + { + this.name = name ?? throw new ArgumentNullException(nameof(name)); + this.description = description ?? throw new ArgumentNullException(nameof(description)); + this.version = version; + this.file = file ?? throw new ArgumentNullException(nameof(file)); + this.local = local; + this.hash = hash ?? throw new ArgumentNullException(nameof(hash)); + ID = iD; + this.color = color; + this.icon = icon ?? throw new ArgumentNullException(nameof(icon)); + this.runnable = runnable; + this.mainFile = mainFile ?? throw new ArgumentNullException(nameof(mainFile)); +#if DEBUG + Console.WriteLine(";" + mainFile + ";" + this.mainFile); +#endif + } + + public Status status + { + get { + string dir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\UpTool2"; + string xml = dir + @"\Apps\" + ID.ToString() + @"\info.xml"; + if (File.Exists(xml)) + { + if (int.Parse(XDocument.Load(xml).Element("app").Element("Version").Value) < version) + return Status.Updatable; + else + { + return local ? Status.Installed | Status.Local : Status.Installed; + } + } + else + return Status.Not_Installed; + } + } + + public override bool Equals(object obj) => obj is App app && Equals(app); + public bool Equals(App other) => ID.Equals(other.ID); + public override int GetHashCode() => 1213502048 + EqualityComparer.Default.GetHashCode(ID); + public override string ToString() => "Name: " + name + "\r\nDescription:\r\n" + string.Join("\r\n", description.Split('\n').Select(s => { if (s.EndsWith("\r")) s.Remove(s.Length - 1, 1); return "> " + s; })) + "\r\nVersion: " + version + "\r\nFile: " + file + "\r\nLocal: " + local.ToString() + "\r\nHash: " + hash + "\r\nID: " + ID.ToString() + "\r\nColor: " + color.ToKnownColor().ToString() + "\r\nRunnable: " + runnable + "\r\nMainFile: " + mainFile + "\r\nStatus: " + status.ToString() + "\r\nObject Hash Code: " + GetHashCode(); + public static bool operator ==(App left, App right) => left.Equals(right); + public static bool operator !=(App left, App right) => !(left == right); + } +} diff --git a/UpTool2/GlobalVariables.cs b/UpTool2/GlobalVariables.cs new file mode 100644 index 0000000..e7410ab --- /dev/null +++ b/UpTool2/GlobalVariables.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; + +namespace UpTool2 +{ + static partial class GlobalVariables + { + public static Dictionary apps = new Dictionary(); + public static string dir => Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\UpTool2"; + public static string appsPath => dir + @"\Apps"; + public static string getAppPath(App app) => getAppPath(app.ID); + public static string getDataPath(App app) => getDataPath(app.ID); + public static string getInfoPath(App app) => getInfoPath(app.ID); + public static string getAppPath(Guid app) => appsPath + @"\" + app.ToString(); + public static string getDataPath(Guid app) => getAppPath(app) + @"\app"; + public static string getInfoPath(Guid app) => getAppPath(app) + "\\info.xml"; + public static bool relE = true; + } +} diff --git a/UpTool2/MainForm.cs b/UpTool2/MainForm.cs index 4b0b42b..84ef841 100644 --- a/UpTool2/MainForm.cs +++ b/UpTool2/MainForm.cs @@ -1,7 +1,5 @@ using System; -using System.Collections.Generic; using System.Drawing; -using System.Net; using System.Windows.Forms; using UpTool2.Properties; using System.Xml.Linq; @@ -9,18 +7,12 @@ using System.IO; using System.Diagnostics; using System.IO.Compression; using System.Security.Cryptography; -using System.Linq; using Microsoft.VisualBasic; -using System.Drawing.Drawing2D; -using System.Drawing.Imaging; -using System.Threading; -using System.Runtime.InteropServices; namespace UpTool2 { public partial class MainForm : Form { - #region Install/Remove/Upload (Main local app management) private void Action_install_Click(object sender, EventArgs e) { string app = ""; @@ -30,8 +22,8 @@ namespace UpTool2 { #endif App appI = (App)action_install.Tag; - app = dir + @"\Apps\" + appI.ID.ToString(); - tmp = dir + @"\tmp"; + app = GlobalVariables.dir + @"\Apps\" + appI.ID.ToString(); + tmp = GlobalVariables.dir + @"\tmp"; if (Directory.Exists(tmp)) Directory.Delete(tmp, true); Directory.CreateDirectory(tmp); @@ -51,7 +43,7 @@ namespace UpTool2 } catch (Exception e1) { - if (!relE) + if (!GlobalVariables.relE) throw; if (Directory.Exists(app)) Directory.Delete(app, true); @@ -64,8 +56,8 @@ namespace UpTool2 { try { - string app = dir + @"\Apps\" + ((App)action_remove.Tag).ID.ToString(); - string tmp = dir + @"\tmp"; + string app = GlobalVariables.dir + @"\Apps\" + ((App)action_remove.Tag).ID.ToString(); + string tmp = GlobalVariables.dir + @"\tmp"; if (Directory.Exists(tmp)) Directory.Delete(tmp, true); Directory.CreateDirectory(tmp); @@ -73,12 +65,12 @@ namespace UpTool2 Process.Start(new ProcessStartInfo { FileName = "cmd.exe", Arguments = "/C \"" + tmp + "\\Remove.bat\"", WorkingDirectory = app + @"\app" }).WaitForExit(); Directory.Delete(tmp, true); Directory.Delete(app, true); - if (relE) + if (GlobalVariables.relE) reloadElements(); } catch (Exception e1) { - if (!relE) + if (!GlobalVariables.relE) throw; MessageBox.Show(e1.ToString(), "Removal failed"); } @@ -94,15 +86,15 @@ namespace UpTool2 if (searchPackageDialog.ShowDialog() == DialogResult.OK) { Guid ID = Guid.NewGuid(); - app = dir + @"\Apps\" + ID.ToString(); + app = GlobalVariables.dir + @"\Apps\" + ID.ToString(); while (Directory.Exists(app)) { ID = Guid.NewGuid(); - app = dir + @"\Apps\" + ID.ToString(); + app = GlobalVariables.dir + @"\Apps\" + ID.ToString(); } App appI = new App(Interaction.InputBox("Name:"), "Locally installed package, removal only", -1, "", true, "", ID, Color.Red, Resources.C_64.ToBitmap(), false, ""); Directory.CreateDirectory(app); - tmp = dir + @"\tmp"; + tmp = GlobalVariables.dir + @"\tmp"; if (Directory.Exists(tmp)) Directory.Delete(tmp, true); Directory.CreateDirectory(tmp); @@ -113,7 +105,7 @@ namespace UpTool2 } catch (Exception e1) { - if (!relE) + if (!GlobalVariables.relE) throw; if (Directory.Exists(app)) Directory.Delete(app, true); @@ -129,7 +121,7 @@ namespace UpTool2 try { #endif - string tmp = dir + @"\tmp"; + string tmp = GlobalVariables.dir + @"\tmp"; ZipFile.ExtractToDirectory(app + @"\package.zip", tmp); Directory.Move(tmp + @"\Data", app + @"\app"); if (appI.runnable) @@ -137,15 +129,13 @@ namespace UpTool2 else new XElement("app", new XElement("Name", appI.name), new XElement("Description", appI.description), new XElement("Version", appI.version)).Save(app + @"\info.xml"); Process.Start(new ProcessStartInfo { FileName = "cmd.exe", Arguments = "/C \"" + tmp + "\\Install.bat\"", WorkingDirectory = app + @"\app", CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden }).WaitForExit(); - if (relE) + if (GlobalVariables.relE) reloadElements(); #if !DEBUG } catch { throw; } #endif } - #endregion - #region Repo management void reloadElements() { //remove @@ -158,22 +148,22 @@ namespace UpTool2 { sidebarPanel.Controls[0].Dispose(); } - apps.Clear(); + GlobalVariables.apps.Clear(); //add toolTip.SetToolTip(controls_settings, "Settings"); toolTip.SetToolTip(controls_reload, "Refresh repositories"); toolTip.SetToolTip(controls_upload, "Install package from disk"); toolTip.SetToolTip(controls_local, "Install UpTool2 locally"); - controls_local.Visible = Application.ExecutablePath != dir + @"\UpTool2.exe"; - searchBox.Size = (Application.ExecutablePath != dir + @"\UpTool2.exe") ? new Size(233, 20) : new Size(262, 20); + controls_local.Visible = Application.ExecutablePath != GlobalVariables.dir + @"\UpTool2.exe"; + searchBox.Size = (Application.ExecutablePath != GlobalVariables.dir + @"\UpTool2.exe") ? new Size(233, 20) : new Size(262, 20); toolTip.SetToolTip(filterBox, "Filter"); toolTip.SetToolTip(action_install, "Install"); toolTip.SetToolTip(action_remove, "Remove"); toolTip.SetToolTip(action_update, "Update"); toolTip.SetToolTip(action_run, "Run"); - getReposFromDisk(); + RepoManagement.getReposFromDisk(); int availableUpdates = 0; - foreach (App app in apps.Values) + foreach (App app in GlobalVariables.apps.Values) { Panel sidebarIcon = new Panel(); sidebarIcon.Tag = app; @@ -187,16 +177,15 @@ namespace UpTool2 infoPanel_Title.ForeColor = app.local ? Color.Red : Color.Black; infoPanel_Description.Text = app.description; action_install.Tag = app; - action_install.Enabled = !(app.local || Directory.Exists(dir + @"\Apps\" + app.ID.ToString())); + action_install.Enabled = !(app.local || Directory.Exists(GlobalVariables.getAppPath(app))); action_remove.Tag = app; - action_remove.Enabled = Directory.Exists(dir + @"\Apps\" + app.ID.ToString()); + action_remove.Enabled = Directory.Exists(GlobalVariables.getAppPath(app)); action_update.Tag = app; - string xml = dir + @"\Apps\" + app.ID.ToString() + @"\info.xml"; - action_update.Enabled = (!app.local) && File.Exists(getInfoPath(app)) && int.Parse(XDocument.Load(getInfoPath(app)).Element("app").Element("Version").Value) < app.version; + action_update.Enabled = (!app.local) && File.Exists(GlobalVariables.getInfoPath(app)) && int.Parse(XDocument.Load(GlobalVariables.getInfoPath(app)).Element("app").Element("Version").Value) < app.version; action_run.Tag = app; - action_run.Enabled = (!app.local) && app.runnable && Directory.Exists(dir + @"\Apps\" + app.ID.ToString()); + action_run.Enabled = (!app.local) && app.runnable && Directory.Exists(GlobalVariables.getAppPath(app)); }; - if ((!app.local) && File.Exists(getInfoPath(app)) && int.Parse(XDocument.Load(getInfoPath(app)).Element("app").Element("Version").Value) < app.version) + if ((!app.local) && File.Exists(GlobalVariables.getInfoPath(app)) && int.Parse(XDocument.Load(GlobalVariables.getInfoPath(app)).Element("app").Element("Version").Value) < app.version) availableUpdates++; toolTip.SetToolTip(sidebarIcon, app.name); sidebarPanel.Controls.Add(sidebarIcon); @@ -204,168 +193,25 @@ namespace UpTool2 updateSidebarV(null, null); Text = "UpTool2 " + ((availableUpdates == 0) ? "(All up-to-date)" : "(" + availableUpdates.ToString() + " Updates)"); } - - void getReposFromDisk() - { - apps.Clear(); - string xml = dir + @"\info.xml"; - XDocument.Load(xml).Element("meta").Element("LocalRepo").Elements().ToList().ForEach(app => - { - Guid id = Guid.Parse(app.Element("ID").Value); - string locInPath = getInfoPath(id); - XElement locIn = File.Exists(locInPath) ? XDocument.Load(locInPath).Element("app") : app; - apps.Add(id, new App( - name: locIn.Element("Name").Value, - description: locIn.Element("Description").Value, - version: int.Parse(app.Element("Version").Value), - file: app.Element("File").Value, - local: false, - hash: app.Element("Hash").Value, - iD: id, - color: Color.White, - icon: app.Element("Icon") == null ? Resources.C_64.ToBitmap() : (Bitmap)new ImageConverter().ConvertFrom(Convert.FromBase64String(app.Element("Icon").Value)), - runnable: locIn.Element("MainFile") != null || app.Element("MainFile") != null, - mainFile: locIn.Element("MainFile") == null ? (app.Element("MainFile") == null ? "" : app.Element("MainFile").Value) : locIn.Element("MainFile").Value - )); -#if DEBUG - Console.WriteLine(locIn.Element("MainFile") == null ? "NULL" : locIn.Element("MainFile").Value); - Console.WriteLine(apps[id].mainFile); -#endif - }); - Directory.GetDirectories(dir + @"\Apps\").Where(s => !apps.ContainsKey(Guid.Parse(Path.GetFileName(s)))).ToList().ForEach(s => - { - Guid tmp = Guid.Parse(Path.GetFileName(s)); - try - { - XElement data = XDocument.Load(getInfoPath(tmp)).Element("app"); - apps.Add(tmp, new App("(local) " + data.Element("Name").Value, data.Element("Description").Value, -1, "", true, "", tmp, Color.Red, Resources.C_64.ToBitmap(), data.Element("MainFile") != null, data.Element("MainFile") == null ? "" : data.Element("MainFile").Value)); - } - catch (Exception e) - { - if (MessageBox.Show("An error occured while loading this local repo:\r\n" + e.Message + "\r\nDo you want to exit? Otherwise the folder will be deleted, possibly causeing problems later.", "", MessageBoxButtons.YesNo) == DialogResult.No) - Directory.Delete(getAppPath(tmp), true); - else - Environment.Exit(0); - } - }); - } - - void fetchRepos() - { - string xml = dir + @"\info.xml"; - XElement meta = XDocument.Load(xml).Element("meta"); - List tmp_apps_list = new List(); - if (meta.Element("Repos") == null) - meta.Add(new XElement("Repos")); - if (meta.Element("Repos").Elements("Repo").Count() == 0) - meta.Element("Repos").Add(new XElement("Repo", new XElement("Name", "UpTool2 official Repo"), new XElement("Link", "https://github.com/CreepyCrafter24/UpTool2/releases/download/Repo/Repo.xml"))); - List repArr = meta.Element("Repos").Elements("Repo").Select(s => s.Element("Link").Value).ToList(); - using (WebClient client = new WebClient()) - { - int i = 0; - while (i < repArr.Count) - { -#if !DEBUG - try - { -#endif - XDocument repo = XDocument.Load(repArr[i]); - repArr.AddRange(repo.Element("repo").Elements("repolink").Select(s => s.Value)); - XElement[] tmp_apparray = repo.Element("repo").Elements("app").Where(app => tmp_apps_list.Where(a => a.Element("ID").Value == app.Element("ID").Value).Count() == 0 || - tmp_apps_list.Where(a => a.Element("ID").Value == app.Element("ID").Value) - .Where(a => int.Parse(a.Element("Version").Value) >= int.Parse(app.Element("Version").Value)).Count() == 0).ToArray() - .Concat(repo.Element("repo").Elements("applink").Select(s => XDocument.Load(s.Value).Element("app"))).ToArray(); - for (int i1 = 0; i1 < tmp_apparray.Length; i1++) - { - XElement app = tmp_apparray[i1]; - //"Sanity check" - int.Parse(app.Element("Version").Value); - Guid.Parse(app.Element("ID").Value); - //Create XElement - tmp_apps_list.Add(new XElement("App", - new XElement("Name", app.Element("Name").Value), - new XElement("Description", app.Element("Description").Value), - new XElement("Version", app.Element("Version").Value), - new XElement("ID", app.Element("ID").Value), - new XElement("File", app.Element("File").Value), - new XElement("Hash", app.Element("Hash").Value) - )); - if (app.Element("MainFile") != null) - tmp_apps_list.Last().Add(new XElement("MainFile", app.Element("MainFile").Value)); - if (app.Element("Icon") != null) - { - try - { - //Scale Image and save as Base64 - Image src = Image.FromStream(client.OpenRead(app.Element("Icon").Value)); - Bitmap dest = new Bitmap(70, 70); - dest.SetResolution(src.HorizontalResolution, src.VerticalResolution); - using (Graphics g = Graphics.FromImage(dest)) - { - g.CompositingMode = CompositingMode.SourceCopy; - g.CompositingQuality = CompositingQuality.HighQuality; - g.InterpolationMode = InterpolationMode.HighQualityBicubic; - g.SmoothingMode = SmoothingMode.HighQuality; - g.PixelOffsetMode = PixelOffsetMode.HighQuality; - using (var wrapMode = new ImageAttributes()) - { - wrapMode.SetWrapMode(WrapMode.TileFlipXY); - g.DrawImage(src, new Rectangle(0, 0, 70, 70), 0, 0, src.Width, src.Height, GraphicsUnit.Pixel, wrapMode); - } - } - using (var ms = new MemoryStream()) - { - dest.Save(ms, ImageFormat.Png); - tmp_apps_list.Last().Add(new XElement("Icon", Convert.ToBase64String(ms.ToArray()))); - } - } - catch { } - } - - if (tmp_apps_list.Where(a => a.Element("ID").Value == app.Element("ID").Value).Count() > 1) - tmp_apps_list.Where(a => a.Element("ID").Value == app.Element("ID").Value).Reverse().Skip(1).ToList().ForEach(a => tmp_apps_list.Remove(a)); - } -#if !DEBUG - } - catch (Exception e) - { - MessageBox.Show(e.ToString(), "Failed to load repo: " + repArr[i]); - } -#endif - i++; - } - } - tmp_apps_list.Sort((x, y) => x.Element("Name").Value.CompareTo(y.Element("Name").Value)); - if (meta.Element("LocalRepo") == null) - meta.Add(new XElement("LocalRepo")); - XElement repos = meta.Element("LocalRepo"); - repos.RemoveNodes(); - tmp_apps_list.ForEach(app => repos.Add(app)); - meta.Save(xml); - } - #endregion - #region Run/Update/Reload/Settings (Small links to other stuff) private void Action_run_Click(object sender, EventArgs e) { Console.WriteLine(new string('-', 10)); - Console.WriteLine(getDataPath((App)action_run.Tag)); + Console.WriteLine(GlobalVariables.getDataPath((App)action_run.Tag)); Console.WriteLine("\\"); Console.WriteLine(((App)action_run.Tag).mainFile); - Console.WriteLine(getDataPath((App)action_run.Tag)); + Console.WriteLine(GlobalVariables.getDataPath((App)action_run.Tag)); _ = Process.Start( new ProcessStartInfo { - FileName = getDataPath((App)action_run.Tag) + "\\" + - ((App)action_run.Tag).mainFile, - WorkingDirectory = getDataPath((App)action_run.Tag) + FileName = GlobalVariables.getDataPath((App)action_run.Tag) + "\\" + ((App)action_run.Tag).mainFile, + WorkingDirectory = GlobalVariables.getDataPath((App)action_run.Tag) }); } - private void Action_update_Click(object sender, EventArgs e) { try { - relE = false; + GlobalVariables.relE = false; Action_remove_Click(sender, e); Action_install_Click(sender, e); } @@ -374,17 +220,14 @@ namespace UpTool2 MessageBox.Show(e1.ToString(), "Install failed"); } reloadElements(); - relE = true; + GlobalVariables.relE = true; } private void Controls_reload_Click(object sender, EventArgs e) { - fetchRepos(); + RepoManagement.fetchRepos(); reloadElements(); } - private void Controls_settings_Click(object sender, EventArgs e) => new SettingsForms().ShowDialog(); - #endregion - #region GUI (stuff only present for GUI) void clearSelection() { action_install.Enabled = false; @@ -427,7 +270,7 @@ namespace UpTool2 InitializeComponent(); filterBox.DataSource = Enum.GetValues(typeof(Status)); if (Program.online) - fetchRepos(); + RepoManagement.fetchRepos(); else { MessageBox.Show("Starting in offline mode!"); @@ -436,126 +279,20 @@ namespace UpTool2 filterBox.SelectedIndex = 2; } reloadElements(); - if (!Directory.Exists(appsPath)) - Directory.CreateDirectory(appsPath); + if (!Directory.Exists(GlobalVariables.appsPath)) + Directory.CreateDirectory(GlobalVariables.appsPath); } private void MainForm_Load(object sender, EventArgs e) { Program.splash.Hide(); BringToFront(); } - private void controls_local_Click(object sender, EventArgs e) { - File.Copy(dir + @"\update.exe", dir + @"\UpTool2.exe", true); - Type m_type = Type.GetTypeFromProgID("WScript.Shell"); - object m_shell = Activator.CreateInstance(m_type); - IWshShortcut shortcut = (IWshShortcut)m_type.InvokeMember("CreateShortcut", System.Reflection.BindingFlags.InvokeMethod, null, m_shell, new object[] { Path.GetDirectoryName(Application.ExecutablePath) + "\\UpTool2.lnk" }); - shortcut.TargetPath = dir + @"\UpTool2.exe"; - shortcut.Save(); - shortcut = (IWshShortcut)m_type.InvokeMember("CreateShortcut", System.Reflection.BindingFlags.InvokeMethod, null, m_shell, new object[] { Environment.GetFolderPath(Environment.SpecialFolder.Programs) + "\\UpTool2.lnk" }); - shortcut.TargetPath = dir + @"\UpTool2.exe"; - shortcut.Save(); + File.Copy(GlobalVariables.dir + @"\update.exe", GlobalVariables.dir + @"\UpTool2.exe", true); + Shortcut.Make(GlobalVariables.dir + @"\UpTool2.exe", Path.GetDirectoryName(Application.ExecutablePath) + "\\UpTool2.lnk"); + Shortcut.Make(GlobalVariables.dir + @"\UpTool2.exe", Environment.GetFolderPath(Environment.SpecialFolder.Programs) + "\\UpTool2.lnk"); Close(); } - - [ComImport, TypeLibType(0x1040), Guid("F935DC23-1CF0-11D0-ADB9-00C04FD58A0B")] - private interface IWshShortcut - { - [DispId(0)] - string FullName { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0)] get; } - [DispId(0x3e8)] - string Arguments { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3e8)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3e8)] set; } - [DispId(0x3e9)] - string Description { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3e9)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3e9)] set; } - [DispId(0x3ea)] - string Hotkey { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3ea)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ea)] set; } - [DispId(0x3eb)] - string IconLocation { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3eb)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3eb)] set; } - [DispId(0x3ec)] - string RelativePath { [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ec)] set; } - [DispId(0x3ed)] - string TargetPath { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3ed)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ed)] set; } - [DispId(0x3ee)] - int WindowStyle { [DispId(0x3ee)] get; [param: In] [DispId(0x3ee)] set; } - [DispId(0x3ef)] - string WorkingDirectory { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3ef)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ef)] set; } - [TypeLibFunc((short)0x40), DispId(0x7d0)] - void Load([In, MarshalAs(UnmanagedType.BStr)] string PathLink); - [DispId(0x7d1)] - void Save(); - } - #endregion - #region Definitions - private struct App : IEquatable - { - public string name; - public string description; - public int version; - public string file; - public bool local; - public string hash; - public Guid ID; - public Color color; - public Image icon; - public bool runnable; - public string mainFile; - - public App(string name, string description, int version, string file, bool local, string hash, Guid iD, Color color, Image icon, bool runnable, string mainFile) - { - this.name = name ?? throw new ArgumentNullException(nameof(name)); - this.description = description ?? throw new ArgumentNullException(nameof(description)); - this.version = version; - this.file = file ?? throw new ArgumentNullException(nameof(file)); - this.local = local; - this.hash = hash ?? throw new ArgumentNullException(nameof(hash)); - ID = iD; - this.color = color; - this.icon = icon ?? throw new ArgumentNullException(nameof(icon)); - this.runnable = runnable; - this.mainFile = mainFile ?? throw new ArgumentNullException(nameof(mainFile)); -#if DEBUG - Console.WriteLine(";" + mainFile + ";" + this.mainFile); -#endif - } - - public Status status - { - get { - string dir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\UpTool2"; - string xml = dir + @"\Apps\" + ID.ToString() + @"\info.xml"; - if (File.Exists(xml)) - { - if (int.Parse(XDocument.Load(xml).Element("app").Element("Version").Value) < version) - return Status.Updatable; - else - { - return local ? Status.Installed | Status.Local : Status.Installed; - } - } - else - return Status.Not_Installed; - } - } - - public override bool Equals(object obj) => obj is App app && Equals(app); - public bool Equals(App other) => ID.Equals(other.ID); - public override int GetHashCode() => 1213502048 + EqualityComparer.Default.GetHashCode(ID); - public override string ToString() => "Name: " + name + "\r\nDescription:\r\n" + string.Join("\r\n", description.Split('\n').Select(s => { if (s.EndsWith("\r")) s.Remove(s.Length - 1, 1); return "> " + s; })) + "\r\nVersion: " + version + "\r\nFile: " + file + "\r\nLocal: " + local.ToString() + "\r\nHash: " + hash + "\r\nID: " + ID.ToString() + "\r\nColor: " + color.ToKnownColor().ToString() + "\r\nRunnable: " + runnable + "\r\nMainFile: " + mainFile + "\r\nStatus: " + status.ToString() + "\r\nObject Hash Code: " + GetHashCode(); - public static bool operator ==(App left, App right) => left.Equals(right); - public static bool operator !=(App left, App right) => !(left == right); - } - Dictionary apps = new Dictionary(); - enum Status { Not_Installed = 1, Updatable = 2, Installed = 4, Local = 8, All = 15 } - string dir => Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\UpTool2"; - string appsPath => dir + @"\Apps"; - string getAppPath(App app) => getAppPath(app.ID); - string getDataPath(App app) => getDataPath(app.ID); - string getInfoPath(App app) => getInfoPath(app.ID); - string getAppPath(Guid app) => appsPath + @"\" + app.ToString(); - string getDataPath(Guid app) => getAppPath(app) + @"\app"; - string getInfoPath(Guid app) => getAppPath(app) + "\\info.xml"; - bool relE = true; - #endregion } } diff --git a/UpTool2/Program.cs b/UpTool2/Program.cs index 4e01cd8..3fbc37c 100644 --- a/UpTool2/Program.cs +++ b/UpTool2/Program.cs @@ -12,7 +12,6 @@ using System.Windows.Forms; using System.Xml.Linq; using System.Drawing; using System.Linq; -using System.Collections.Generic; using System.Xml; using System.IO.Compression; @@ -53,14 +52,13 @@ namespace UpTool2 #endif hasHandle = true; } - string dir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\UpTool2"; - if (!Directory.Exists(dir + @"\Apps")) - Directory.CreateDirectory(dir + @"\Apps"); - string xml = dir + @"\info.xml"; + if (!Directory.Exists(GlobalVariables.dir + @"\Apps")) + Directory.CreateDirectory(GlobalVariables.dir + @"\Apps"); + string xml = GlobalVariables.dir + @"\info.xml"; FixXML(xml); string metaXML = XDocument.Load(xml).Element("meta").Element("UpdateSource").Value; online = Ping(metaXML); - if (!online || UpdateCheck(dir, xml, metaXML)) + if (!online || UpdateCheck(GlobalVariables.dir, xml, metaXML)) Application.Run(new MainForm()); #if !DEBUG } diff --git a/UpTool2/RepoManagement.cs b/UpTool2/RepoManagement.cs new file mode 100644 index 0000000..e2ff53a --- /dev/null +++ b/UpTool2/RepoManagement.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.IO; +using System.Linq; +using System.Net; +using System.Windows.Forms; +using System.Xml.Linq; +using UpTool2.Properties; + +namespace UpTool2 +{ + static class RepoManagement + { + public static void fetchRepos() + { + string xml = GlobalVariables.dir + @"\info.xml"; + XElement meta = XDocument.Load(xml).Element("meta"); + List tmp_apps_list = new List(); + if (meta.Element("Repos") == null) + meta.Add(new XElement("Repos")); + if (meta.Element("Repos").Elements("Repo").Count() == 0) + meta.Element("Repos").Add(new XElement("Repo", new XElement("Name", "UpTool2 official Repo"), new XElement("Link", "https://github.com/CreepyCrafter24/UpTool2/releases/download/Repo/Repo.xml"))); + List repArr = meta.Element("Repos").Elements("Repo").Select(s => s.Element("Link").Value).ToList(); + using (WebClient client = new WebClient()) + { + int i = 0; + while (i < repArr.Count) + { +#if !DEBUG + try + { +#endif + XDocument repo = XDocument.Load(repArr[i]); + repArr.AddRange(repo.Element("repo").Elements("repolink").Select(s => s.Value)); + XElement[] tmp_apparray = repo.Element("repo").Elements("app").Where(app => tmp_apps_list.Where(a => a.Element("ID").Value == app.Element("ID").Value).Count() == 0 || + tmp_apps_list.Where(a => a.Element("ID").Value == app.Element("ID").Value) + .Where(a => int.Parse(a.Element("Version").Value) >= int.Parse(app.Element("Version").Value)).Count() == 0).ToArray() + .Concat(repo.Element("repo").Elements("applink").Select(s => XDocument.Load(s.Value).Element("app"))).ToArray(); + for (int i1 = 0; i1 < tmp_apparray.Length; i1++) + { + XElement app = tmp_apparray[i1]; + //"Sanity check" + int.Parse(app.Element("Version").Value); + Guid.Parse(app.Element("ID").Value); + //Create XElement + tmp_apps_list.Add(new XElement("App", + new XElement("Name", app.Element("Name").Value), + new XElement("Description", app.Element("Description").Value), + new XElement("Version", app.Element("Version").Value), + new XElement("ID", app.Element("ID").Value), + new XElement("File", app.Element("File").Value), + new XElement("Hash", app.Element("Hash").Value) + )); + if (app.Element("MainFile") != null) + tmp_apps_list.Last().Add(new XElement("MainFile", app.Element("MainFile").Value)); + if (app.Element("Icon") != null) + { + try + { + //Scale Image and save as Base64 + Image src = Image.FromStream(client.OpenRead(app.Element("Icon").Value)); + Bitmap dest = new Bitmap(70, 70); + dest.SetResolution(src.HorizontalResolution, src.VerticalResolution); + using (Graphics g = Graphics.FromImage(dest)) + { + g.CompositingMode = CompositingMode.SourceCopy; + g.CompositingQuality = CompositingQuality.HighQuality; + g.InterpolationMode = InterpolationMode.HighQualityBicubic; + g.SmoothingMode = SmoothingMode.HighQuality; + g.PixelOffsetMode = PixelOffsetMode.HighQuality; + using (var wrapMode = new ImageAttributes()) + { + wrapMode.SetWrapMode(WrapMode.TileFlipXY); + g.DrawImage(src, new Rectangle(0, 0, 70, 70), 0, 0, src.Width, src.Height, GraphicsUnit.Pixel, wrapMode); + } + } + using (var ms = new MemoryStream()) + { + dest.Save(ms, ImageFormat.Png); + tmp_apps_list.Last().Add(new XElement("Icon", Convert.ToBase64String(ms.ToArray()))); + } + } + catch { } + } + + if (tmp_apps_list.Where(a => a.Element("ID").Value == app.Element("ID").Value).Count() > 1) + tmp_apps_list.Where(a => a.Element("ID").Value == app.Element("ID").Value).Reverse().Skip(1).ToList().ForEach(a => tmp_apps_list.Remove(a)); + } +#if !DEBUG + } + catch (Exception e) + { + MessageBox.Show(e.ToString(), "Failed to load repo: " + repArr[i]); + } +#endif + i++; + } + } + tmp_apps_list.Sort((x, y) => x.Element("Name").Value.CompareTo(y.Element("Name").Value)); + if (meta.Element("LocalRepo") == null) + meta.Add(new XElement("LocalRepo")); + XElement repos = meta.Element("LocalRepo"); + repos.RemoveNodes(); + tmp_apps_list.ForEach(app => repos.Add(app)); + meta.Save(xml); + } + + public static void getReposFromDisk() + { + GlobalVariables.apps.Clear(); + string xml = GlobalVariables.dir + @"\info.xml"; + XDocument.Load(xml).Element("meta").Element("LocalRepo").Elements().ToList().ForEach(app => + { + Guid id = Guid.Parse(app.Element("ID").Value); + string locInPath = GlobalVariables.getInfoPath(id); + XElement locIn = File.Exists(locInPath) ? XDocument.Load(locInPath).Element("app") : app; + GlobalVariables.apps.Add(id, new App( + name: locIn.Element("Name").Value, + description: locIn.Element("Description").Value, + version: int.Parse(app.Element("Version").Value), + file: app.Element("File").Value, + local: false, + hash: app.Element("Hash").Value, + iD: id, + color: Color.White, + icon: app.Element("Icon") == null ? Resources.C_64.ToBitmap() : (Bitmap)new ImageConverter().ConvertFrom(Convert.FromBase64String(app.Element("Icon").Value)), + runnable: locIn.Element("MainFile") != null || app.Element("MainFile") != null, + mainFile: locIn.Element("MainFile") == null ? (app.Element("MainFile") == null ? "" : app.Element("MainFile").Value) : locIn.Element("MainFile").Value + )); +#if DEBUG + Console.WriteLine(locIn.Element("MainFile") == null ? "NULL" : locIn.Element("MainFile").Value); + Console.WriteLine(apps[id].mainFile); +#endif + }); + Directory.GetDirectories(GlobalVariables.dir + @"\Apps\").Where(s => !GlobalVariables.apps.ContainsKey(Guid.Parse(Path.GetFileName(s)))).ToList().ForEach(s => + { + Guid tmp = Guid.Parse(Path.GetFileName(s)); + try + { + XElement data = XDocument.Load(GlobalVariables.getInfoPath(tmp)).Element("app"); + GlobalVariables.apps.Add(tmp, new App("(local) " + data.Element("Name").Value, data.Element("Description").Value, -1, "", true, "", tmp, Color.Red, Resources.C_64.ToBitmap(), data.Element("MainFile") != null, data.Element("MainFile") == null ? "" : data.Element("MainFile").Value)); + } + catch (Exception e) + { + if (MessageBox.Show("An error occured while loading this local repo:\r\n" + e.Message + "\r\nDo you want to exit? Otherwise the folder will be deleted, possibly causeing problems later.", "", MessageBoxButtons.YesNo) == DialogResult.No) + Directory.Delete(GlobalVariables.getAppPath(tmp), true); + else + Environment.Exit(0); + } + }); + } + } +} diff --git a/UpTool2/Shortcut.cs b/UpTool2/Shortcut.cs new file mode 100644 index 0000000..4026e99 --- /dev/null +++ b/UpTool2/Shortcut.cs @@ -0,0 +1,45 @@ +using System; +using System.Runtime.InteropServices; +using System.Reflection; + +namespace UpTool2 +{ + static class Shortcut + { + static Type m_type = Type.GetTypeFromProgID("WScript.Shell"); + static object m_shell = Activator.CreateInstance(m_type); + public static void Make(string target, string fileName) + { + IWshShortcut shortcut = (IWshShortcut)m_type.InvokeMember("CreateShortcut", BindingFlags.InvokeMethod, null, m_shell, new object[] { fileName }); + shortcut.TargetPath = target; + shortcut.Save(); + } + + [ComImport, TypeLibType(0x1040), Guid("F935DC23-1CF0-11D0-ADB9-00C04FD58A0B")] + private interface IWshShortcut + { + [DispId(0)] + string FullName { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0)] get; } + [DispId(0x3e8)] + string Arguments { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3e8)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3e8)] set; } + [DispId(0x3e9)] + string Description { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3e9)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3e9)] set; } + [DispId(0x3ea)] + string Hotkey { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3ea)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ea)] set; } + [DispId(0x3eb)] + string IconLocation { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3eb)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3eb)] set; } + [DispId(0x3ec)] + string RelativePath { [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ec)] set; } + [DispId(0x3ed)] + string TargetPath { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3ed)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ed)] set; } + [DispId(0x3ee)] + int WindowStyle { [DispId(0x3ee)] get; [param: In] [DispId(0x3ee)] set; } + [DispId(0x3ef)] + string WorkingDirectory { [return: MarshalAs(UnmanagedType.BStr)] [DispId(0x3ef)] get; [param: In, MarshalAs(UnmanagedType.BStr)] [DispId(0x3ef)] set; } + [TypeLibFunc((short)0x40), DispId(0x7d0)] + void Load([In, MarshalAs(UnmanagedType.BStr)] string PathLink); + [DispId(0x7d1)] + void Save(); + } + } +} diff --git a/UpTool2/Status.cs b/UpTool2/Status.cs new file mode 100644 index 0000000..a979630 --- /dev/null +++ b/UpTool2/Status.cs @@ -0,0 +1,11 @@ +namespace UpTool2 +{ + public enum Status + { + Not_Installed = 1, + Updatable = 2, + Installed = 4, + Local = 8, + All = 15 + } +} diff --git a/UpTool2/UpTool2.csproj b/UpTool2/UpTool2.csproj index 85843e1..a88047f 100644 --- a/UpTool2/UpTool2.csproj +++ b/UpTool2/UpTool2.csproj @@ -53,12 +53,14 @@ + Form DownloadDialog.cs + Form @@ -67,12 +69,15 @@ + + Form SourcesForm.cs + DownloadDialog.cs