Improved Updates
This commit is contained in:
parent
ec18671b4f
commit
128434f1f7
3
ToDo.txt
3
ToDo.txt
@ -3,7 +3,6 @@ More apps: Laptop Sim (when done)
|
||||
Split up main File (MainForm.cs) to (more or less) independent modules
|
||||
Allow Repos to contain "Links" to seperate Repos/App files (Repo with only one app & without a repo tag)
|
||||
Automatically push Meta.xml changes after building
|
||||
Allow Zips for updates
|
||||
Allow 3rd party update source in main.xml
|
||||
Show number of available updates
|
||||
|
||||
NOTE: All command prompts will be removed soon (tm) Update your scripts to reflect this change (there may be some things provided for dialogs)
|
16
UpTool2/MainForm.Designer.cs
generated
16
UpTool2/MainForm.Designer.cs
generated
@ -46,6 +46,7 @@
|
||||
this.controls_reload = new System.Windows.Forms.Button();
|
||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.searchPackageDialog = new System.Windows.Forms.OpenFileDialog();
|
||||
this.controls_local = new System.Windows.Forms.Button();
|
||||
this.infoPanel.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
|
||||
this.splitContainer.Panel1.SuspendLayout();
|
||||
@ -169,6 +170,7 @@
|
||||
this.optionsPanel.Controls.Add(this.searchBox);
|
||||
this.optionsPanel.Controls.Add(this.controls_settings);
|
||||
this.optionsPanel.Controls.Add(this.controls_reload);
|
||||
this.optionsPanel.Controls.Add(this.controls_local);
|
||||
this.optionsPanel.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.optionsPanel.Location = new System.Drawing.Point(0, 0);
|
||||
this.optionsPanel.Name = "optionsPanel";
|
||||
@ -204,7 +206,7 @@
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.searchBox.Location = new System.Drawing.Point(3, 33);
|
||||
this.searchBox.Name = "searchBox";
|
||||
this.searchBox.Size = new System.Drawing.Size(262, 20);
|
||||
this.searchBox.Size = new System.Drawing.Size(233, 20);
|
||||
this.searchBox.TabIndex = 2;
|
||||
this.searchBox.TextChanged += new System.EventHandler(this.updateSidebarV);
|
||||
//
|
||||
@ -239,6 +241,17 @@
|
||||
//
|
||||
this.searchPackageDialog.Filter = "Packages (*.zip)|*.zip";
|
||||
//
|
||||
// controls_local
|
||||
//
|
||||
this.controls_local.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.controls_local.Location = new System.Drawing.Point(242, 31);
|
||||
this.controls_local.Name = "controls_local";
|
||||
this.controls_local.Size = new System.Drawing.Size(23, 23);
|
||||
this.controls_local.TabIndex = 6;
|
||||
this.controls_local.Text = "⇓";
|
||||
this.controls_local.UseVisualStyleBackColor = true;
|
||||
this.controls_local.Click += new System.EventHandler(this.controls_local_Click);
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
@ -281,6 +294,7 @@
|
||||
private System.Windows.Forms.Button action_run;
|
||||
private System.Windows.Forms.Button controls_upload;
|
||||
private System.Windows.Forms.OpenFileDialog searchPackageDialog;
|
||||
private System.Windows.Forms.Button controls_local;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,6 +14,7 @@ using Microsoft.VisualBasic;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Threading;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace UpTool2
|
||||
{
|
||||
@ -162,6 +163,9 @@ namespace UpTool2
|
||||
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);
|
||||
toolTip.SetToolTip(filterBox, "Filter");
|
||||
toolTip.SetToolTip(action_install, "Install");
|
||||
toolTip.SetToolTip(action_remove, "Remove");
|
||||
@ -283,10 +287,8 @@ namespace UpTool2
|
||||
tmp_apps_list.Last().Add(new XElement("MainFile", app.Element("MainFile").Value));
|
||||
if (app.Element("Icon") != null)
|
||||
{
|
||||
#if !DEBUG
|
||||
try
|
||||
{
|
||||
#endif
|
||||
//Scale Image and save as Base64
|
||||
Image src = Image.FromStream(client.OpenRead(app.Element("Icon").Value));
|
||||
Bitmap dest = new Bitmap(70, 70);
|
||||
@ -309,10 +311,8 @@ namespace UpTool2
|
||||
dest.Save(ms, ImageFormat.Png);
|
||||
tmp_apps_list.Last().Add(new XElement("Icon", Convert.ToBase64String(ms.ToArray())));
|
||||
}
|
||||
#if !DEBUG
|
||||
}
|
||||
catch { }
|
||||
#endif
|
||||
}
|
||||
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));
|
||||
@ -335,8 +335,8 @@ namespace UpTool2
|
||||
tmp_apps_list.ForEach(app => repos.Add(app));
|
||||
meta.Save(xml);
|
||||
}
|
||||
#endregion
|
||||
#region Run/Update/Reload/Settings (Small links to other stuff)
|
||||
#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));
|
||||
@ -345,7 +345,8 @@ namespace UpTool2
|
||||
Console.WriteLine(((App)action_run.Tag).mainFile);
|
||||
Console.WriteLine(getDataPath((App)action_run.Tag));
|
||||
_ = Process.Start(
|
||||
new ProcessStartInfo {
|
||||
new ProcessStartInfo
|
||||
{
|
||||
FileName = getDataPath((App)action_run.Tag) + "\\" +
|
||||
((App)action_run.Tag).mainFile,
|
||||
WorkingDirectory = getDataPath((App)action_run.Tag)
|
||||
@ -374,8 +375,8 @@ namespace UpTool2
|
||||
}
|
||||
|
||||
private void Controls_settings_Click(object sender, EventArgs e) => new SettingsForms().ShowDialog();
|
||||
#endregion
|
||||
#region GUI (stuff only present for GUI)
|
||||
#endregion
|
||||
#region GUI (stuff only present for GUI)
|
||||
void clearSelection()
|
||||
{
|
||||
action_install.Enabled = false;
|
||||
@ -401,14 +402,14 @@ namespace UpTool2
|
||||
else
|
||||
{
|
||||
#endif
|
||||
Enum.TryParse(filterBox.SelectedValue.ToString(), out Status status);
|
||||
for (int i = 0; i < sidebarPanel.Controls.Count; i++)
|
||||
{
|
||||
Panel sidebarIcon = (Panel)sidebarPanel.Controls[i];
|
||||
App app = (App)sidebarIcon.Tag;
|
||||
sidebarIcon.Visible = app.name.Contains(searchBox.Text) && ((int)app.status & (int)(Program.online ? status : Status.Installed)) != 0;
|
||||
}
|
||||
clearSelection();
|
||||
Enum.TryParse(filterBox.SelectedValue.ToString(), out Status status);
|
||||
for (int i = 0; i < sidebarPanel.Controls.Count; i++)
|
||||
{
|
||||
Panel sidebarIcon = (Panel)sidebarPanel.Controls[i];
|
||||
App app = (App)sidebarIcon.Tag;
|
||||
sidebarIcon.Visible = app.name.Contains(searchBox.Text) && ((int)app.status & (int)(Program.online ? status : Status.Installed)) != 0;
|
||||
}
|
||||
clearSelection();
|
||||
#if DEBUG
|
||||
}
|
||||
#endif
|
||||
@ -435,8 +436,64 @@ namespace UpTool2
|
||||
Program.splash.Hide();
|
||||
BringToFront();
|
||||
}
|
||||
#endregion
|
||||
#region Definitions
|
||||
|
||||
private void controls_local_Click(object sender, EventArgs e)
|
||||
{
|
||||
File.Copy(dir + @"\update.exe", dir + @"\UpTool2.exe", true);
|
||||
Shortcut.Create(Path.GetDirectoryName(Application.ExecutablePath) + "\\UpTool2.lnk", dir + @"\UpTool2.exe", null, null, null, null, null);
|
||||
Shortcut.Create(Environment.GetFolderPath(Environment.SpecialFolder.Programs) + "\\UpTool2.lnk", dir + @"\UpTool2.exe", null, null, null, null, null);
|
||||
Close();
|
||||
}
|
||||
|
||||
public class Shortcut
|
||||
{
|
||||
|
||||
private static Type m_type = Type.GetTypeFromProgID("WScript.Shell");
|
||||
private static object m_shell = Activator.CreateInstance(m_type);
|
||||
|
||||
[ComImport, TypeLibType((short)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();
|
||||
}
|
||||
|
||||
public static void Create(string fileName, string targetPath, string arguments, string workingDirectory, string description, string hotkey, string iconPath)
|
||||
{
|
||||
IWshShortcut shortcut = (IWshShortcut)m_type.InvokeMember("CreateShortcut", System.Reflection.BindingFlags.InvokeMethod, null, m_shell, new object[] { fileName });
|
||||
shortcut.Description = description;
|
||||
shortcut.TargetPath = targetPath;
|
||||
shortcut.WorkingDirectory = workingDirectory;
|
||||
shortcut.Arguments = arguments;
|
||||
if (!string.IsNullOrEmpty(hotkey))
|
||||
shortcut.Hotkey = hotkey;
|
||||
if (!string.IsNullOrEmpty(iconPath))
|
||||
shortcut.IconLocation = iconPath;
|
||||
shortcut.Save();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#region Definitions
|
||||
private struct App : IEquatable<App>
|
||||
{
|
||||
public string name;
|
||||
@ -504,6 +561,6 @@ namespace UpTool2
|
||||
string getAppPath(Guid app) => appsPath + @"\" + app.ToString();
|
||||
string getDataPath(Guid app) => getAppPath(app) + @"\app";
|
||||
bool relE = true;
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
using System.IO.Compression;
|
||||
|
||||
namespace UpTool2
|
||||
{
|
||||
@ -26,14 +27,13 @@ namespace UpTool2
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
showSplash();
|
||||
ShowSplash();
|
||||
string appGuid = ((GuidAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(GuidAttribute), false).GetValue(0)).Value.ToString();
|
||||
string mutexId = string.Format("Global\\{{{0}}}", appGuid);
|
||||
bool createdNew;
|
||||
var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
|
||||
var securitySettings = new MutexSecurity();
|
||||
securitySettings.AddAccessRule(allowEveryoneRule);
|
||||
using (var mutex = new Mutex(false, mutexId, out createdNew, securitySettings))
|
||||
using (var mutex = new Mutex(false, mutexId, out bool createdNew, securitySettings))
|
||||
{
|
||||
var hasHandle = false;
|
||||
#if !DEBUG
|
||||
@ -57,10 +57,10 @@ namespace UpTool2
|
||||
if (!Directory.Exists(dir + @"\Apps"))
|
||||
Directory.CreateDirectory(dir + @"\Apps");
|
||||
string xml = dir + @"\info.xml";
|
||||
fixXML(xml);
|
||||
string metaXml = "https://raw.githubusercontent.com/CreepyCrafter24/UpTool2/master/Meta.xml";
|
||||
online = Ping(metaXml);
|
||||
if (!online || updateCheck(dir, xml, metaXml))
|
||||
FixXML(xml);
|
||||
string metaXML = XDocument.Load(xml).Element("meta").Element("UpdateSource").Value;
|
||||
online = Ping(metaXML);
|
||||
if (!online || UpdateCheck(dir, xml, metaXML))
|
||||
Application.Run(new MainForm());
|
||||
#if !DEBUG
|
||||
}
|
||||
@ -77,7 +77,7 @@ namespace UpTool2
|
||||
}
|
||||
}
|
||||
|
||||
static void showSplash()
|
||||
static void ShowSplash()
|
||||
{
|
||||
splash = new Form
|
||||
{
|
||||
@ -107,27 +107,30 @@ namespace UpTool2
|
||||
splash.BringToFront();
|
||||
}
|
||||
|
||||
static void fixXML(string xml)
|
||||
static void FixXML(string xml)
|
||||
{
|
||||
try
|
||||
{
|
||||
if ((!File.Exists(xml)) || XDocument.Load(xml).Element("meta") == null)
|
||||
new XElement("meta", new XElement("Version", 0), new XElement("Repos", new XElement("Repo", new XElement("Name", "UpTool2 official Repo"), new XElement("Link", "https://raw.githubusercontent.com/CreepyCrafter24/UpTool2/master/Repo.xml"))), new XElement("LocalRepo")).Save(xml);
|
||||
new XElement("meta", new XElement("Version", 0), new XElement("UpdateSource", "https://raw.githubusercontent.com/CreepyCrafter24/UpTool2/master/Meta.xml"), new XElement("Repos", new XElement("Repo", new XElement("Name", "UpTool2 official Repo"), new XElement("Link", "https://raw.githubusercontent.com/CreepyCrafter24/UpTool2/master/Repo.xml"))), new XElement("LocalRepo")).Save(xml);
|
||||
else
|
||||
{
|
||||
XDocument x = XDocument.Load(xml);
|
||||
XElement meta = x.Element("meta");
|
||||
if (XDocument.Load(xml).Element("meta").Element("Repos") == null || XDocument.Load(xml).Element("meta").Element("Repos").Elements("Repo").Count() == 0)
|
||||
{
|
||||
if (XDocument.Load(xml).Element("meta").Element("Version") == null)
|
||||
meta.Add(new XElement("Version", 0));
|
||||
if (XDocument.Load(xml).Element("meta").Element("UpdateSource") == null)
|
||||
meta.Add(new XElement("UpdateSource", "https://raw.githubusercontent.com/CreepyCrafter24/UpTool2/master/Meta.xml"));
|
||||
if (XDocument.Load(xml).Element("meta").Element("Repos") == null)
|
||||
meta.Add(new XElement("Repos", new XElement("Repo", new XElement("Name", "UpTool2 official Repo"), new XElement("Link", "https://raw.githubusercontent.com/CreepyCrafter24/UpTool2/master/Repo.xml"))));
|
||||
meta.Add(new XElement("LocalRepo"));
|
||||
}
|
||||
else if (XDocument.Load(xml).Element("meta").Element("Repos").Elements("Repo").Count() == 0)
|
||||
meta.Element("Repos").Add(new XElement("Repo", new XElement("Name", "UpTool2 official Repo"), new XElement("Link", "https://raw.githubusercontent.com/CreepyCrafter24/UpTool2/master/Repo.xml")));
|
||||
else
|
||||
{
|
||||
XElement repos = meta.Element("Repos");
|
||||
IEnumerable<XElement> reposa = repos.Elements("Repo");
|
||||
reposa.Select(s => s.Element("Link")).Where(s => s.Value == "https://github.com/CreepyCrafter24/UpTool2/releases/download/Repo/Repo.xml").ToList().ForEach(s => s.Value = "https://raw.githubusercontent.com/CreepyCrafter24/UpTool2/master/Repo.xml");
|
||||
}
|
||||
meta.Element("Repos").Elements("Repo").Select(s => s.Element("Link"))
|
||||
.Where(s => s.Value == "https://github.com/CreepyCrafter24/UpTool2/releases/download/Repo/Repo.xml")
|
||||
.ToList().ForEach(s => s.Value = "https://raw.githubusercontent.com/CreepyCrafter24/UpTool2/master/Repo.xml");
|
||||
if (XDocument.Load(xml).Element("meta").Element("LocalRepo") == null)
|
||||
meta.Add(new XElement("LocalRepo"));
|
||||
x.Save(xml);
|
||||
}
|
||||
}
|
||||
@ -137,20 +140,38 @@ namespace UpTool2
|
||||
}
|
||||
}
|
||||
|
||||
static bool updateCheck(string dir, string xml, string metaXml)
|
||||
static bool UpdateCheck(string dir, string xml, string metaXML)
|
||||
{
|
||||
XElement meta = XDocument.Load(metaXml).Element("meta");
|
||||
XElement meta = XDocument.Load(metaXML).Element("meta");
|
||||
int version = int.Parse(meta.Element("Version").Value);
|
||||
if (int.Parse(XDocument.Load(xml).Element("meta").Element("Version").Value) < version)
|
||||
{
|
||||
if (new DownloadDialog(meta.Element("File").Value, dir + @"\update.exe").ShowDialog() != DialogResult.OK)
|
||||
throw new Exception("Failed to update");
|
||||
using (DownloadDialog dlg = new DownloadDialog(meta.Element("File").Value, dir + @"\update.tmp"))
|
||||
{
|
||||
if (dlg.ShowDialog() != DialogResult.OK)
|
||||
throw new Exception("Failed to update");
|
||||
}
|
||||
using (SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider())
|
||||
{
|
||||
string pkghash = BitConverter.ToString(sha256.ComputeHash(File.ReadAllBytes(dir + @"\update.exe"))).Replace("-", string.Empty).ToUpper();
|
||||
string pkghash = BitConverter.ToString(sha256.ComputeHash(File.ReadAllBytes(dir + @"\update.tmp"))).Replace("-", string.Empty).ToUpper();
|
||||
if (pkghash != meta.Element("Hash").Value.ToUpper())
|
||||
throw new Exception("The hash is not equal to the one stored in the repo:\r\nPackage: " + pkghash + "\r\nOnline: " + meta.Element("Hash").Value.ToUpper());
|
||||
}
|
||||
try
|
||||
{
|
||||
//Try extracting. This is done to support automatically built updates
|
||||
if (Directory.Exists(dir + @"\update"))
|
||||
Directory.Delete(dir + @"\update", true);
|
||||
ZipFile.ExtractToDirectory(dir + @"\update.tmp", dir + @"\update");
|
||||
File.Delete(dir + @"\update.tmp");
|
||||
File.Copy(dir + @"\update", dir + @"\update.exe", true);
|
||||
}
|
||||
catch (InvalidDataException)
|
||||
{
|
||||
//If it can not be extracted as a .zip we try reading to see if it is a binary by trying to read it's name
|
||||
AssemblyName.GetAssemblyName(dir + @"\update.tmp");
|
||||
File.Move(dir + @"\update.tmp", dir + @"\update.exe");
|
||||
}
|
||||
new XElement("meta", new XElement("Version", version)).Save(xml);
|
||||
splash.Hide();
|
||||
Process.Start(new ProcessStartInfo { FileName = "cmd.exe", Arguments = "/C timeout /t 2 & copy /b/v/y \"" + dir + @"\update.exe" + "\" \"" + Application.ExecutablePath + "\" & \"" + Application.ExecutablePath + "\"", CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden });
|
||||
|
@ -40,6 +40,7 @@
|
||||
<Reference Include="Microsoft.VisualBasic" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.IO.Compression" />
|
||||
<Reference Include="System.IO.Compression.FileSystem" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
|
Reference in New Issue
Block a user