Add CLI Tool
This commit is contained in:
parent
af4b9238be
commit
023f452b26
|
@ -0,0 +1,22 @@
|
|||
# CLI
|
||||
Updating the cache: uptool update
|
||||
|
||||
Installing a package: uptool install <package>
|
||||
|
||||
Upgrading a package: uptool upgrade <package>
|
||||
|
||||
Reinstalling a package: uptool reinstall <package>
|
||||
|
||||
Removing a package: uptool remove <package>
|
||||
|
||||
Removing a package and all its configuration and data files: uptool purge <package>
|
||||
|
||||
|
||||
|
||||
List installed packages: uptool list
|
||||
|
||||
Upgrade all packages: uptool dist-upgrade
|
||||
|
||||
Search for a package: uptool search <text>
|
||||
|
||||
Show package info: uptool show <package>
|
|
@ -16,7 +16,7 @@ Now you can add this\
|
|||
as a PostBuild event to automatically run pkgtool. Customize this if you need to.\
|
||||
For GitHub actions I wrote [this](https://github.com/JFronny/CC-Clicker/blob/master/.github/workflows/main.yml).\
|
||||
If you copy it, make sure to replace the descriptions and ID under the `Fenerate XML` step\
|
||||
You can also add something like this to your Readme: [![UpTool2](https://img.shields.io/badge/dynamic/xml?color=informational&label=UpTool2&query=%2F%2Fapp%2FVersion&url=https%3A%2F%2Fgithub.com%2FJFronny%2FCC-Clicker%2Freleases%2Fdownload%2F1.0.7380.28108%2Fapp.xml&style=flat)](https://jfronny.github.io/home/uptool)\
|
||||
You can also add something like this to your Readme: [![UpTool2](https://img.shields.io/github/v/tag/JFronny/CC-Clicker?color=informational&label=UpTool2)](https://jfronny.github.io/home/uptool)\
|
||||
(Look at the source for the MD Code)
|
||||
## Folder layout
|
||||
- %APPDATA%\UpTool2
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<ApplicationIcon>..\UpTool2.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CC-Functions.Misc" Version="1.1.7384.27745" />
|
||||
<PackageReference Include="System.CommandLine" Version="2.0.0-beta1.20104.2" />
|
||||
<PackageReference Include="CC-Functions.Misc" Version="1.1.7388.28729" />
|
||||
<PackageReference Include="System.CommandLine" Version="2.0.0-beta1.20158.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
13
UpTool2.sln
13
UpTool2.sln
|
@ -10,12 +10,17 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
|||
.gitignore = .gitignore
|
||||
.github\workflows\main.yml = .github\workflows\main.yml
|
||||
README.md = README.md
|
||||
CLI.md = CLI.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UpTool build tool", "UpTool build tool\UpTool build tool.csproj", "{AAB8D6BA-3A43-4DC4-95EE-6757482B77FD}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Installer", "Installer\Installer.csproj", "{1D273392-3796-4BE9-A67F-BB402315D52D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpToolLib", "UpToolLib\UpToolLib.csproj", "{FACD621F-6C6D-4D4B-B322-4364A0F9B4C2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpToolCLI", "UpToolCLI\UpToolCLI.csproj", "{3EC369B9-D927-4A53-BE1A-7E7006081BCE}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -34,6 +39,14 @@ Global
|
|||
{1D273392-3796-4BE9-A67F-BB402315D52D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1D273392-3796-4BE9-A67F-BB402315D52D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1D273392-3796-4BE9-A67F-BB402315D52D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{FACD621F-6C6D-4D4B-B322-4364A0F9B4C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{FACD621F-6C6D-4D4B-B322-4364A0F9B4C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FACD621F-6C6D-4D4B-B322-4364A0F9B4C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FACD621F-6C6D-4D4B-B322-4364A0F9B4C2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3EC369B9-D927-4A53-BE1A-7E7006081BCE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3EC369B9-D927-4A53-BE1A-7E7006081BCE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3EC369B9-D927-4A53-BE1A-7E7006081BCE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3EC369B9-D927-4A53-BE1A-7E7006081BCE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -29,7 +29,8 @@
|
|||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
|
||||
System.ComponentModel.ComponentResourceManager resources =
|
||||
new System.ComponentModel.ComponentResourceManager(typeof(UpTool2.MainForm));
|
||||
this.sidebarPanel = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.infoPanel = new System.Windows.Forms.Panel();
|
||||
this.action_run = new System.Windows.Forms.Button();
|
||||
|
@ -48,15 +49,12 @@
|
|||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.searchPackageDialog = new System.Windows.Forms.OpenFileDialog();
|
||||
this.infoPanel.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize) (this.splitContainer)).BeginInit();
|
||||
this.splitContainer.Panel1.SuspendLayout();
|
||||
this.splitContainer.Panel2.SuspendLayout();
|
||||
this.splitContainer.SuspendLayout();
|
||||
this.optionsPanel.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// sidebarPanel
|
||||
//
|
||||
this.sidebarPanel.AutoScroll = true;
|
||||
this.sidebarPanel.BackColor = System.Drawing.SystemColors.ControlLight;
|
||||
this.sidebarPanel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
|
@ -64,9 +62,6 @@
|
|||
this.sidebarPanel.Name = "sidebarPanel";
|
||||
this.sidebarPanel.Size = new System.Drawing.Size(312, 451);
|
||||
this.sidebarPanel.TabIndex = 0;
|
||||
//
|
||||
// infoPanel
|
||||
//
|
||||
this.infoPanel.Controls.Add(this.action_run);
|
||||
this.infoPanel.Controls.Add(this.action_remove);
|
||||
this.infoPanel.Controls.Add(this.action_update);
|
||||
|
@ -78,10 +73,9 @@
|
|||
this.infoPanel.Name = "infoPanel";
|
||||
this.infoPanel.Size = new System.Drawing.Size(616, 519);
|
||||
this.infoPanel.TabIndex = 1;
|
||||
//
|
||||
// action_run
|
||||
//
|
||||
this.action_run.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.action_run.Anchor =
|
||||
((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Top |
|
||||
System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.action_run.Location = new System.Drawing.Point(491, 6);
|
||||
this.action_run.Name = "action_run";
|
||||
this.action_run.Size = new System.Drawing.Size(27, 27);
|
||||
|
@ -89,10 +83,9 @@
|
|||
this.action_run.Text = "↗";
|
||||
this.action_run.UseVisualStyleBackColor = true;
|
||||
this.action_run.Click += new System.EventHandler(this.Action_run_Click);
|
||||
//
|
||||
// action_remove
|
||||
//
|
||||
this.action_remove.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.action_remove.Anchor =
|
||||
((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Top |
|
||||
System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.action_remove.Enabled = false;
|
||||
this.action_remove.Location = new System.Drawing.Point(523, 6);
|
||||
this.action_remove.Name = "action_remove";
|
||||
|
@ -101,10 +94,9 @@
|
|||
this.action_remove.Text = "🗑";
|
||||
this.action_remove.UseVisualStyleBackColor = true;
|
||||
this.action_remove.Click += new System.EventHandler(this.Action_remove_Click);
|
||||
//
|
||||
// action_update
|
||||
//
|
||||
this.action_update.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.action_update.Anchor =
|
||||
((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Top |
|
||||
System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.action_update.Enabled = false;
|
||||
this.action_update.Location = new System.Drawing.Point(554, 6);
|
||||
this.action_update.Name = "action_update";
|
||||
|
@ -113,10 +105,9 @@
|
|||
this.action_update.Text = "⭱";
|
||||
this.action_update.UseVisualStyleBackColor = true;
|
||||
this.action_update.Click += new System.EventHandler(this.Action_update_Click);
|
||||
//
|
||||
// action_install
|
||||
//
|
||||
this.action_install.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.action_install.Anchor =
|
||||
((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Top |
|
||||
System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.action_install.Enabled = false;
|
||||
this.action_install.Location = new System.Drawing.Point(586, 6);
|
||||
this.action_install.Name = "action_install";
|
||||
|
@ -125,37 +116,23 @@
|
|||
this.action_install.Text = "⭳";
|
||||
this.action_install.UseVisualStyleBackColor = true;
|
||||
this.action_install.Click += new System.EventHandler(this.Action_install_Click);
|
||||
//
|
||||
// infoPanel_Description
|
||||
//
|
||||
this.infoPanel_Description.Location = new System.Drawing.Point(3, 51);
|
||||
this.infoPanel_Description.Name = "infoPanel_Description";
|
||||
this.infoPanel_Description.Size = new System.Drawing.Size(611, 458);
|
||||
this.infoPanel_Description.TabIndex = 1;
|
||||
//
|
||||
// infoPanel_Title
|
||||
//
|
||||
this.infoPanel_Title.AutoSize = true;
|
||||
this.infoPanel_Title.Font = new System.Drawing.Font("Microsoft Sans Serif", 20.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
|
||||
this.infoPanel_Title.Font = new System.Drawing.Font("Microsoft Sans Serif", 20.25F,
|
||||
System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
|
||||
this.infoPanel_Title.Location = new System.Drawing.Point(2, 1);
|
||||
this.infoPanel_Title.Name = "infoPanel_Title";
|
||||
this.infoPanel_Title.Size = new System.Drawing.Size(0, 31);
|
||||
this.infoPanel_Title.TabIndex = 0;
|
||||
//
|
||||
// splitContainer
|
||||
//
|
||||
this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.splitContainer.Location = new System.Drawing.Point(0, 0);
|
||||
this.splitContainer.Name = "splitContainer";
|
||||
//
|
||||
// splitContainer.Panel1
|
||||
//
|
||||
this.splitContainer.Panel1.Controls.Add(this.sidebarPanel);
|
||||
this.splitContainer.Panel1.Controls.Add(this.optionsPanel);
|
||||
this.splitContainer.Panel1MinSize = 160;
|
||||
//
|
||||
// splitContainer.Panel2
|
||||
//
|
||||
this.splitContainer.Panel2.Controls.Add(this.infoPanel);
|
||||
this.splitContainer.Panel2MinSize = 160;
|
||||
this.splitContainer.Size = new System.Drawing.Size(933, 519);
|
||||
|
@ -163,9 +140,6 @@
|
|||
this.splitContainer.SplitterWidth = 5;
|
||||
this.splitContainer.TabIndex = 0;
|
||||
this.splitContainer.TabStop = false;
|
||||
//
|
||||
// optionsPanel
|
||||
//
|
||||
this.optionsPanel.Controls.Add(this.controls_upload);
|
||||
this.optionsPanel.Controls.Add(this.filterBox);
|
||||
this.optionsPanel.Controls.Add(this.searchBox);
|
||||
|
@ -176,10 +150,9 @@
|
|||
this.optionsPanel.Name = "optionsPanel";
|
||||
this.optionsPanel.Size = new System.Drawing.Size(312, 68);
|
||||
this.optionsPanel.TabIndex = 0;
|
||||
//
|
||||
// controls_upload
|
||||
//
|
||||
this.controls_upload.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.controls_upload.Anchor =
|
||||
((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Top |
|
||||
System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.controls_upload.Location = new System.Drawing.Point(284, 6);
|
||||
this.controls_upload.Name = "controls_upload";
|
||||
this.controls_upload.Size = new System.Drawing.Size(27, 27);
|
||||
|
@ -187,11 +160,10 @@
|
|||
this.controls_upload.Text = "↑";
|
||||
this.controls_upload.UseVisualStyleBackColor = true;
|
||||
this.controls_upload.Click += new System.EventHandler(this.controls_upload_Click);
|
||||
//
|
||||
// filterBox
|
||||
//
|
||||
this.filterBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.filterBox.Anchor =
|
||||
((System.Windows.Forms.AnchorStyles) (((System.Windows.Forms.AnchorStyles.Top |
|
||||
System.Windows.Forms.AnchorStyles.Left) |
|
||||
System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.filterBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.filterBox.FormattingEnabled = true;
|
||||
this.filterBox.Location = new System.Drawing.Point(68, 7);
|
||||
|
@ -199,19 +171,15 @@
|
|||
this.filterBox.Size = new System.Drawing.Size(209, 23);
|
||||
this.filterBox.TabIndex = 3;
|
||||
this.filterBox.SelectedIndexChanged += new System.EventHandler(this.UpdateSidebarV);
|
||||
//
|
||||
// searchBox
|
||||
//
|
||||
this.searchBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.searchBox.Anchor =
|
||||
((System.Windows.Forms.AnchorStyles) (((System.Windows.Forms.AnchorStyles.Bottom |
|
||||
System.Windows.Forms.AnchorStyles.Left) |
|
||||
System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.searchBox.Location = new System.Drawing.Point(3, 38);
|
||||
this.searchBox.Name = "searchBox";
|
||||
this.searchBox.Size = new System.Drawing.Size(307, 23);
|
||||
this.searchBox.TabIndex = 2;
|
||||
this.searchBox.TextChanged += new System.EventHandler(this.UpdateSidebarV);
|
||||
//
|
||||
// controls_settings
|
||||
//
|
||||
this.controls_settings.Location = new System.Drawing.Point(3, 6);
|
||||
this.controls_settings.Name = "controls_settings";
|
||||
this.controls_settings.Size = new System.Drawing.Size(27, 27);
|
||||
|
@ -219,9 +187,6 @@
|
|||
this.controls_settings.Text = "⚙";
|
||||
this.controls_settings.UseVisualStyleBackColor = true;
|
||||
this.controls_settings.Click += new System.EventHandler(this.Controls_settings_Click);
|
||||
//
|
||||
// controls_reload
|
||||
//
|
||||
this.controls_reload.Location = new System.Drawing.Point(34, 6);
|
||||
this.controls_reload.Name = "controls_reload";
|
||||
this.controls_reload.Size = new System.Drawing.Size(27, 27);
|
||||
|
@ -229,26 +194,17 @@
|
|||
this.controls_reload.Text = "↻";
|
||||
this.controls_reload.UseVisualStyleBackColor = true;
|
||||
this.controls_reload.Click += new System.EventHandler(this.Controls_reload_Click);
|
||||
//
|
||||
// toolTip
|
||||
//
|
||||
this.toolTip.AutoPopDelay = 5000;
|
||||
this.toolTip.InitialDelay = 300;
|
||||
this.toolTip.ReshowDelay = 100;
|
||||
this.toolTip.ShowAlways = true;
|
||||
//
|
||||
// searchPackageDialog
|
||||
//
|
||||
this.searchPackageDialog.Filter = "Packages (*.zip)|*.zip";
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(933, 519);
|
||||
this.Controls.Add(this.splitContainer);
|
||||
this.HelpButton = true;
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.Icon = ((System.Drawing.Icon) (resources.GetObject("$this.Icon")));
|
||||
this.MinimumSize = new System.Drawing.Size(631, 269);
|
||||
this.Name = "MainForm";
|
||||
this.ShowIcon = false;
|
||||
|
@ -258,12 +214,11 @@
|
|||
this.infoPanel.PerformLayout();
|
||||
this.splitContainer.Panel1.ResumeLayout(false);
|
||||
this.splitContainer.Panel2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize) (this.splitContainer)).EndInit();
|
||||
this.splitContainer.ResumeLayout(false);
|
||||
this.optionsPanel.ResumeLayout(false);
|
||||
this.optionsPanel.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -5,9 +5,12 @@ using System.IO;
|
|||
using System.IO.Compression;
|
||||
using System.Reflection;
|
||||
using System.Windows.Forms;
|
||||
using UpTool2.DataStructures;
|
||||
using UpTool2.Properties;
|
||||
using UpTool2.Tool;
|
||||
using UpToolLib;
|
||||
using UpToolLib.DataStructures;
|
||||
using UpToolLib.Tool;
|
||||
|
||||
#if DEBUG
|
||||
using System.Threading;
|
||||
using System.Linq;
|
||||
|
@ -17,13 +20,12 @@ namespace UpTool2
|
|||
{
|
||||
public sealed partial class MainForm : Form
|
||||
{
|
||||
HelpEventHandler help;
|
||||
private readonly HelpEventHandler _help;
|
||||
public MainForm()
|
||||
{
|
||||
GlobalVariables.ReloadElements = ReloadElements;
|
||||
InitializeComponent();
|
||||
help = MainForm_HelpRequested;
|
||||
HelpRequested += help;
|
||||
_help = MainForm_HelpRequested;
|
||||
HelpRequested += _help;
|
||||
filterBox.DataSource = Enum.GetValues(typeof(Status));
|
||||
if (Program.Online)
|
||||
{
|
||||
|
@ -52,13 +54,12 @@ namespace UpTool2
|
|||
{
|
||||
#endif
|
||||
AppInstall.Install((App) action_install.Tag);
|
||||
ReloadElements();
|
||||
trying = false;
|
||||
#if !DEBUG
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
if (!GlobalVariables.RelE)
|
||||
throw;
|
||||
trying = MessageBox.Show(e1.ToString(), "Install failed", MessageBoxButtons.RetryCancel) ==
|
||||
DialogResult.Retry;
|
||||
}
|
||||
|
@ -70,29 +71,11 @@ namespace UpTool2
|
|||
{
|
||||
try
|
||||
{
|
||||
string app = ((App) action_remove.Tag).appPath;
|
||||
string tmp = PathTool.tempPath;
|
||||
if (Directory.Exists(tmp))
|
||||
Directory.Delete(tmp, true);
|
||||
Directory.CreateDirectory(tmp);
|
||||
ZipFile.ExtractToDirectory(Path.Combine(app, "package.zip"), tmp);
|
||||
Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = "cmd.exe",
|
||||
Arguments = $"/C \"{Path.Combine(tmp, "Remove.bat")}\"",
|
||||
WorkingDirectory = Path.Combine(app, "app"),
|
||||
CreateNoWindow = true,
|
||||
WindowStyle = ProcessWindowStyle.Hidden
|
||||
}).WaitForExit();
|
||||
Directory.Delete(tmp, true);
|
||||
Directory.Delete(app, true);
|
||||
if (GlobalVariables.RelE)
|
||||
ReloadElements();
|
||||
AppExtras.Remove((App) action_remove.Tag, true);
|
||||
ReloadElements();
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
if (!GlobalVariables.RelE)
|
||||
throw;
|
||||
MessageBox.Show(e1.ToString(), "Removal failed");
|
||||
}
|
||||
}
|
||||
|
@ -115,8 +98,6 @@ namespace UpTool2
|
|||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
if (!GlobalVariables.RelE)
|
||||
throw;
|
||||
MessageBox.Show(e1.ToString(), "Install failed");
|
||||
}
|
||||
#endif
|
||||
|
@ -145,13 +126,15 @@ namespace UpTool2
|
|||
int availableUpdates = 0;
|
||||
foreach (App app in GlobalVariables.Apps.Values)
|
||||
{
|
||||
Panel sidebarIcon = new Panel();
|
||||
sidebarIcon.Tag = app;
|
||||
sidebarIcon.BackColor = app.Color;
|
||||
sidebarIcon.Size = new Size(70, 70);
|
||||
sidebarIcon.BackgroundImage = app.Icon;
|
||||
sidebarIcon.BackgroundImageLayout = ImageLayout.Stretch;
|
||||
bool updatable = !app.Local && (app.status & Status.Updatable) == Status.Updatable;
|
||||
Panel sidebarIcon = new Panel
|
||||
{
|
||||
Tag = app,
|
||||
BackColor = app.Color,
|
||||
Size = new Size(70, 70),
|
||||
BackgroundImage = (Bitmap) app.Icon,
|
||||
BackgroundImageLayout = ImageLayout.Stretch
|
||||
};
|
||||
bool updateable = !app.Local && (app.status & Status.Updatable) == Status.Updatable;
|
||||
sidebarIcon.Click += (sender, e) =>
|
||||
{
|
||||
infoPanel_Title.Text = app.Name;
|
||||
|
@ -162,39 +145,29 @@ namespace UpTool2
|
|||
action_remove.Tag = app;
|
||||
action_remove.Enabled = Directory.Exists(app.appPath);
|
||||
action_update.Tag = app;
|
||||
action_update.Enabled = updatable;
|
||||
action_update.Enabled = updateable;
|
||||
action_run.Tag = app;
|
||||
action_run.Enabled = (app.status & Status.Installed) == Status.Installed && !app.Local && app.Runnable && Directory.Exists(app.appPath);
|
||||
};
|
||||
if (updatable)
|
||||
if (updateable)
|
||||
availableUpdates++;
|
||||
toolTip.SetToolTip(sidebarIcon, app.Name);
|
||||
sidebarPanel.Controls.Add(sidebarIcon);
|
||||
}
|
||||
UpdateSidebarV(null, null);
|
||||
Text =
|
||||
$"UpTool2 {(availableUpdates == 0 ? "(All up-to-date)" : $"({availableUpdates.ToString()} Updates)")}";
|
||||
$"UpTool2 {(availableUpdates == 0 ? "(All up-to-date)" : $"({availableUpdates} Updates)")}";
|
||||
}
|
||||
|
||||
private void Action_run_Click(object sender, EventArgs e)
|
||||
{
|
||||
string path = Path.Combine(((App) action_run.Tag).dataPath, ((App) action_run.Tag).MainFile);
|
||||
try
|
||||
{
|
||||
Process.Start(
|
||||
new ProcessStartInfo
|
||||
{
|
||||
FileName = path,
|
||||
WorkingDirectory = ((App) action_run.Tag).dataPath
|
||||
});
|
||||
AppExtras.RunApp((App) action_run.Tag);
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
MessageBox.Show(e1
|
||||
#if DEBUG
|
||||
+ $"{Environment.NewLine}File was: {path}"
|
||||
#endif
|
||||
+ "Failed to start!");
|
||||
MessageBox.Show($"{e1}Failed to start!");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,16 +175,13 @@ namespace UpTool2
|
|||
{
|
||||
try
|
||||
{
|
||||
GlobalVariables.RelE = false;
|
||||
Action_remove_Click(sender, e);
|
||||
Action_install_Click(sender, e);
|
||||
AppExtras.Update((App) action_install.Tag);
|
||||
}
|
||||
catch (Exception e1)
|
||||
{
|
||||
MessageBox.Show(e1.ToString(), "Install failed");
|
||||
}
|
||||
ReloadElements();
|
||||
GlobalVariables.RelE = true;
|
||||
}
|
||||
|
||||
private void Controls_reload_Click(object sender, EventArgs e)
|
||||
|
@ -252,15 +222,15 @@ 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();
|
||||
App[] apps = AppExtras.FindApps(searchBox.Text);
|
||||
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 = apps.Contains(app) && ((int) app.status & (int) (Program.Online ? status : Status.Installed)) != 0;
|
||||
}
|
||||
ClearSelection();
|
||||
#if DEBUG
|
||||
}
|
||||
#endif
|
||||
|
@ -310,7 +280,7 @@ namespace UpTool2
|
|||
|
||||
private void MainForm_HelpRequested(object sender, HelpEventArgs hlpevent)
|
||||
{
|
||||
HelpRequested -= help;
|
||||
HelpRequested -= _help;
|
||||
try
|
||||
{
|
||||
DateTime buildTime = GetBuildDateTime(Assembly.GetExecutingAssembly());
|
||||
|
@ -320,7 +290,7 @@ Build Date: {buildTime:dd.MM.yyyy}", "UpTool2");
|
|||
}
|
||||
finally
|
||||
{
|
||||
HelpRequested += help;
|
||||
HelpRequested += _help;
|
||||
hlpevent.Handled = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@ using System.Diagnostics;
|
|||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
|
@ -13,6 +11,9 @@ using System.Windows.Forms;
|
|||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using UpTool2.Tool;
|
||||
using UpToolLib.Tool;
|
||||
using CC_Functions.Misc;
|
||||
using UpToolLib;
|
||||
|
||||
namespace UpTool2
|
||||
{
|
||||
|
@ -57,13 +58,14 @@ namespace UpTool2
|
|||
#endif
|
||||
hasHandle = true;
|
||||
}
|
||||
ExternalFunctionalityManager.Init(new UTLibFunctions());
|
||||
SetSplash(1, "Initializing paths");
|
||||
if (!Directory.Exists(PathTool.dir))
|
||||
Directory.CreateDirectory(PathTool.dir);
|
||||
FixXml();
|
||||
SetSplash(2, "Performing checks");
|
||||
string metaXml = XDocument.Load(PathTool.InfoXml).Element("meta").Element("UpdateSource").Value;
|
||||
Online = Ping(metaXml);
|
||||
Online = new Uri(metaXml).Ping();
|
||||
if (Application.ExecutablePath != PathTool.GetRelative("Install", "UpTool2.dll"))
|
||||
Splash.Invoke((Action)(() => MessageBox.Show(Splash, $"WARNING!{Environment.NewLine}Running from outside the install directory is not recommended!")));
|
||||
if (!Directory.Exists(PathTool.GetRelative("Apps")))
|
||||
|
@ -177,40 +179,7 @@ namespace UpTool2
|
|||
{
|
||||
try
|
||||
{
|
||||
if (!File.Exists(PathTool.InfoXml) || XDocument.Load(PathTool.InfoXml).Element("meta") == null)
|
||||
new XElement("meta").Save(PathTool.InfoXml);
|
||||
XDocument x = XDocument.Load(PathTool.InfoXml);
|
||||
XElement meta = x.Element("meta");
|
||||
if (meta.Element("UpdateSource") == null)
|
||||
meta.Add(new XElement("UpdateSource"));
|
||||
if (new[]
|
||||
{
|
||||
"",
|
||||
"https://raw.githubusercontent.com/CreepyCrafter24/UpTool2/master/Meta.xml",
|
||||
"https://raw.githubusercontent.com/JFronny/UpTool2/master/Meta.xml",
|
||||
"https://gist.githubusercontent.com/JFronny/f1ccbba3d8a2f5862592bb29fdb612c4/raw/Meta.xml"
|
||||
}
|
||||
.Contains(meta.Element("UpdateSource").Value))
|
||||
meta.Element("UpdateSource").Value =
|
||||
"https://github.com/JFronny/UpTool2/releases/latest/download/meta.xml";
|
||||
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://gist.githubusercontent.com/JFronny/f1ccbba3d8a2f5862592bb29fdb612c4/raw/Repo.xml")));
|
||||
meta.Element("Repos").Elements("Repo").Select(s => s.Element("Link"))
|
||||
.Where(s => new[]
|
||||
{
|
||||
null, "https://github.com/JFronny/UpTool2/releases/download/Repo/Repo.xml",
|
||||
"https://raw.githubusercontent.com/JFronny/UpTool2/master/Repo.xml"
|
||||
}.Contains(s.Value))
|
||||
.ToList().ForEach(s =>
|
||||
s.Value =
|
||||
"https://gist.githubusercontent.com/JFronny/f1ccbba3d8a2f5862592bb29fdb612c4/raw/Repo.xml");
|
||||
if (meta.Element("LocalRepo") == null)
|
||||
meta.Add(new XElement("LocalRepo"));
|
||||
x.Save(PathTool.InfoXml);
|
||||
XmlTool.FixXml();
|
||||
}
|
||||
catch (XmlException)
|
||||
{
|
||||
|
@ -263,21 +232,5 @@ namespace UpTool2
|
|||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool Ping(string url)
|
||||
{
|
||||
try
|
||||
{
|
||||
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
|
||||
request.Timeout = 3000;
|
||||
request.AllowAutoRedirect = true;
|
||||
using WebResponse response = request.GetResponse();
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
using System.Windows.Forms;
|
||||
using System.Xml.Linq;
|
||||
using UpTool2.Tool;
|
||||
using UpToolLib.Tool;
|
||||
|
||||
namespace UpTool2
|
||||
{
|
||||
|
|
|
@ -1,177 +0,0 @@
|
|||
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 CC_Functions.Misc;
|
||||
using UpTool2.DataStructures;
|
||||
using UpTool2.Properties;
|
||||
|
||||
namespace UpTool2.Tool
|
||||
{
|
||||
internal static class RepoManagement
|
||||
{
|
||||
public static void FetchRepos()
|
||||
{
|
||||
Program.FixXml();
|
||||
XElement meta = XDocument.Load(PathTool.InfoXml).Element("meta");
|
||||
List<XElement> tmpAppsList = new List<XElement>();
|
||||
List<string> repArr = meta.Element("Repos").Elements("Repo").Select(s => s.Element("Link").Value).Distinct()
|
||||
.ToList();
|
||||
using (WebClient client = new WebClient())
|
||||
{
|
||||
int i = 0;
|
||||
while (i < repArr.Count)
|
||||
{
|
||||
#if !DEBUG
|
||||
try
|
||||
{
|
||||
#endif
|
||||
XDocument repo = XDocument.Load(new Uri(repArr[i]).Unshorten().AbsoluteUri);
|
||||
repArr.AddRange(repo.Element("repo").Elements("repolink").Select(s => s.Value)
|
||||
.Where(s => !repArr.Contains(s)));
|
||||
XElement[] tmp_apparray = repo.Element("repo").Elements("app").Where(app =>
|
||||
!tmpAppsList.Any(a => a.Element("ID").Value == app.Element("ID").Value) ||
|
||||
!tmpAppsList
|
||||
.Where(a => a.Element("ID").Value == app.Element("ID").Value).Any(a =>
|
||||
GetVer(a.Element("Version")) >= app.Element("Version").GetVer())).ToArray()
|
||||
.Concat(repo.Element("repo").Elements("applink")
|
||||
.Select(s => XDocument.Load(new Uri(s.Value).Unshorten().AbsoluteUri).Element("app")))
|
||||
.ToArray();
|
||||
for (int i1 = 0; i1 < tmp_apparray.Length; i1++)
|
||||
{
|
||||
XElement app = tmp_apparray[i1];
|
||||
//"Sanity check"
|
||||
Version.Parse(app.Element("Version").Value);
|
||||
Guid.Parse(app.Element("ID").Value);
|
||||
//Create XElement
|
||||
tmpAppsList.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)
|
||||
tmpAppsList.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(new Uri(app.Element("Icon").Value).Unshorten()));
|
||||
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 ImageAttributes 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 MemoryStream ms = new MemoryStream();
|
||||
dest.Save(ms, ImageFormat.Png);
|
||||
tmpAppsList.Last()
|
||||
.Add(new XElement("Icon", Convert.ToBase64String(ms.ToArray())));
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
if (tmpAppsList.Count(a => a.Element("ID").Value == app.Element("ID").Value) > 1)
|
||||
tmpAppsList.Where(a => a.Element("ID").Value == app.Element("ID").Value).Reverse()
|
||||
.Skip(1)
|
||||
.ToList().ForEach(a => tmpAppsList.Remove(a));
|
||||
}
|
||||
#if !DEBUG
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
MessageBox.Show(e.ToString(), "Failed to load repo: " + repArr[i]);
|
||||
}
|
||||
#endif
|
||||
i++;
|
||||
}
|
||||
}
|
||||
tmpAppsList.Sort((x, y) =>
|
||||
string.Compare(x.Element("Name").Value, y.Element("Name").Value, StringComparison.Ordinal));
|
||||
if (meta.Element("LocalRepo") == null)
|
||||
meta.Add(new XElement("LocalRepo"));
|
||||
XElement repos = meta.Element("LocalRepo");
|
||||
repos.RemoveNodes();
|
||||
tmpAppsList.ForEach(app => repos.Add(app));
|
||||
meta.Save(PathTool.InfoXml);
|
||||
}
|
||||
|
||||
private static Version GetVer(this XElement el) =>
|
||||
int.TryParse(el.Value, out int i) ? new Version(0, 0, 0, i) : Version.Parse(el.Value);
|
||||
|
||||
public static void GetReposFromDisk()
|
||||
{
|
||||
GlobalVariables.Apps.Clear();
|
||||
string xml = PathTool.InfoXml;
|
||||
XDocument.Load(xml).Element("meta").Element("LocalRepo").Elements().ToList().ForEach(app =>
|
||||
{
|
||||
Guid id = Guid.Parse(app.Element("ID").Value);
|
||||
string locInPath = PathTool.GetInfoPath(id);
|
||||
XElement locIn = File.Exists(locInPath) ? XDocument.Load(locInPath).Element("app") : app;
|
||||
if (int.TryParse(app.Element("Version").Value, out _))
|
||||
app.Element("Version").Value = GlobalVariables.minimumVer.ToString();
|
||||
GlobalVariables.Apps.Add(id, new App(
|
||||
locIn.Element("Name").Value,
|
||||
locIn.Element("Description").Value,
|
||||
Version.Parse(app.Element("Version").Value),
|
||||
app.Element("File").Value,
|
||||
false,
|
||||
app.Element("Hash").Value,
|
||||
id,
|
||||
Color.White,
|
||||
app.Element("Icon") == null
|
||||
? Resources.C_64.ToBitmap()
|
||||
: (Bitmap) new ImageConverter().ConvertFrom(
|
||||
Convert.FromBase64String(app.Element("Icon").Value)),
|
||||
locIn.Element("MainFile") != null || app.Element("MainFile") != null,
|
||||
locIn.Element("MainFile") == null
|
||||
? app.Element("MainFile") == null ? "" : app.Element("MainFile").Value
|
||||
: locIn.Element("MainFile").Value
|
||||
));
|
||||
});
|
||||
Directory.GetDirectories(PathTool.appsPath)
|
||||
.Where(s => Guid.TryParse(Path.GetFileName(s), out Guid guid) &&
|
||||
!GlobalVariables.Apps.ContainsKey(guid)).ToList().ForEach(s =>
|
||||
{
|
||||
Guid tmp = Guid.Parse(Path.GetFileName(s));
|
||||
try
|
||||
{
|
||||
XElement data = XDocument.Load(PathTool.GetInfoPath(tmp)).Element("app");
|
||||
GlobalVariables.Apps.Add(tmp,
|
||||
new App("(local) " + data.Element("Name").Value, data.Element("Description").Value,
|
||||
GlobalVariables.minimumVer, "", 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:
|
||||
{e.Message}
|
||||
Do you want to exit? Otherwise the folder will be deleted, possibly causeing problems later.", "",
|
||||
MessageBoxButtons.YesNo) == DialogResult.No)
|
||||
Directory.Delete(PathTool.GetAppPath(tmp), true);
|
||||
else
|
||||
Environment.Exit(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Windows.Forms;
|
||||
using UpTool2.Properties;
|
||||
using UpTool2.Tool;
|
||||
using UpToolLib;
|
||||
using UpToolLib.DataStructures;
|
||||
|
||||
namespace UpTool2
|
||||
{
|
||||
class UTLibFunctions : IExternalFunctionality
|
||||
{
|
||||
public Tuple<bool, byte[]> Download(Uri link)
|
||||
{
|
||||
using DownloadDialog dialog = new DownloadDialog(link.AbsoluteUri);
|
||||
bool success = dialog.ShowDialog() == DialogResult.OK;
|
||||
return new Tuple<bool, byte[]>(success, success ? dialog.Result : null);
|
||||
}
|
||||
|
||||
public string FetchImageB64(Uri link)
|
||||
{
|
||||
using WebClient client = new WebClient();
|
||||
Image src = Image.FromStream(
|
||||
client.OpenRead(link));
|
||||
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 ImageAttributes 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 MemoryStream ms = new MemoryStream();
|
||||
dest.Save(ms, ImageFormat.Png);
|
||||
return Convert.ToBase64String(ms.ToArray());
|
||||
}
|
||||
|
||||
public bool YesNoDialog(string text, bool _) => MessageBox.Show(text, "", MessageBoxButtons.YesNo) == DialogResult.Yes;
|
||||
public void OKDialog(string text) => MessageBox.Show(text);
|
||||
public object GetDefaultIcon() => Resources.C_64.ToBitmap();
|
||||
public object ImageFromB64(string b64) => (Bitmap) new ImageConverter().ConvertFrom(Convert.FromBase64String(b64));
|
||||
|
||||
public void Log(string text) { }
|
||||
}
|
||||
}
|
|
@ -19,6 +19,9 @@
|
|||
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CC-Functions.Misc" Version="1.1.7384.27745" />
|
||||
<PackageReference Include="CC-Functions.Misc" Version="1.1.7388.28729" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\UpToolLib\UpToolLib.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,225 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.CommandLine;
|
||||
using System.CommandLine.Invocation;
|
||||
using System.Linq;
|
||||
using UpToolLib;
|
||||
using UpToolLib.DataStructures;
|
||||
using UpToolLib.Tool;
|
||||
|
||||
namespace UpToolCLI
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static int Main(string[] args)
|
||||
{
|
||||
ExternalFunctionalityManager.Init(new UTLibFunctions());
|
||||
RootCommand rootCommand = new RootCommand();
|
||||
rootCommand.AddCommand(new Command("update", "Updates the cache")
|
||||
{
|
||||
Handler = CommandHandler.Create(Update)
|
||||
});
|
||||
|
||||
Command install = new Command("install", "Install a package")
|
||||
{
|
||||
Handler = CommandHandler.Create<string>(Install)
|
||||
};
|
||||
install.AddOption(new Option<string>(new[] { "--identifier", "-i" }, "Something to identify the app"));
|
||||
rootCommand.AddCommand(install);
|
||||
|
||||
Command upgrade = new Command("upgrade", "Upgrade a package")
|
||||
{
|
||||
Handler = CommandHandler.Create<string>(Upgrade)
|
||||
};
|
||||
upgrade.AddOption(new Option<string>(new[] { "--identifier", "-i" }, "Something to identify the app"));
|
||||
rootCommand.AddCommand(upgrade);
|
||||
|
||||
Command reinstall = new Command("reinstall", "Reinstall a package")
|
||||
{
|
||||
Handler = CommandHandler.Create<string>(Reinstall)
|
||||
};
|
||||
reinstall.AddOption(new Option<string>(new[] { "--identifier", "-i" }, "Something to identify the app"));
|
||||
rootCommand.AddCommand(reinstall);
|
||||
|
||||
Command remove = new Command("remove", "Remove a package")
|
||||
{
|
||||
Handler = CommandHandler.Create<string>(Remove)
|
||||
};
|
||||
remove.AddOption(new Option<string>(new[] { "--identifier", "-i" }, "Something to identify the app"));
|
||||
rootCommand.AddCommand(remove);
|
||||
|
||||
Command purge = new Command("purge", "Completely remove a package")
|
||||
{
|
||||
Handler = CommandHandler.Create<string>(Purge)
|
||||
};
|
||||
purge.AddOption(new Option<string>(new[] { "--identifier", "-i" }, "Something to identify the app"));
|
||||
rootCommand.AddCommand(purge);
|
||||
|
||||
|
||||
|
||||
rootCommand.AddCommand(new Command("list", "Lists installed packages")
|
||||
{
|
||||
Handler = CommandHandler.Create(List)
|
||||
});
|
||||
|
||||
rootCommand.AddCommand(new Command("dist-upgrade", "Upgrades all packages")
|
||||
{
|
||||
Handler = CommandHandler.Create(DistUpgrade)
|
||||
});
|
||||
|
||||
Command search = new Command("search", "Search for packages")
|
||||
{
|
||||
Handler = CommandHandler.Create<string>(Search)
|
||||
};
|
||||
search.AddOption(new Option<string>(new[] { "--identifier", "-i" }, "Something to identify the app"));
|
||||
rootCommand.AddCommand(search);
|
||||
|
||||
Command show = new Command("show", "Shows package info")
|
||||
{
|
||||
Handler = CommandHandler.Create<string>(Show)
|
||||
};
|
||||
show.AddOption(new Option<string>(new[] { "--identifier", "-i" }, "Something to identify the app"));
|
||||
rootCommand.AddCommand(show);
|
||||
|
||||
return rootCommand.InvokeAsync(args).Result;
|
||||
}
|
||||
|
||||
private static void Update()
|
||||
{
|
||||
Console.WriteLine("Fetching Repos...");
|
||||
RepoManagement.FetchRepos();
|
||||
Console.WriteLine("Done!");
|
||||
}
|
||||
|
||||
private static void List()
|
||||
{
|
||||
RepoManagement.GetReposFromDisk();
|
||||
foreach (KeyValuePair<Guid, App> app in GlobalVariables.Apps.Where(s => (s.Value.status & Status.Installed) == Status.Installed))
|
||||
{
|
||||
Console.BackgroundColor = (app.Value.status & Status.Local) == Status.Local ? ConsoleColor.DarkRed : ((app.Value.status & Status.Updatable) == Status.Updatable ? ConsoleColor.DarkGreen : ConsoleColor.Black);
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
Console.WriteLine($"{app.Value.Name} ({app.Key}");
|
||||
}
|
||||
Console.ResetColor();
|
||||
}
|
||||
|
||||
private static void DistUpgrade()
|
||||
{
|
||||
RepoManagement.GetReposFromDisk();
|
||||
foreach (KeyValuePair<Guid, App> app in GlobalVariables.Apps.Where(s => (s.Value.status & Status.Updatable) == Status.Updatable))
|
||||
{
|
||||
Console.WriteLine($"Updating {app.Value.Name}");
|
||||
AppExtras.Update(app.Value);
|
||||
}
|
||||
}
|
||||
|
||||
private static void Show(string identifier)
|
||||
{
|
||||
RepoManagement.GetReposFromDisk();
|
||||
App[] apps = AppExtras.FindApps(identifier);
|
||||
if (apps.Length == 0)
|
||||
Console.WriteLine("Package not found.");
|
||||
else
|
||||
Console.WriteLine(apps.First());
|
||||
}
|
||||
|
||||
private static void Search(string identifier)
|
||||
{
|
||||
RepoManagement.GetReposFromDisk();
|
||||
App[] apps = AppExtras.FindApps(identifier);
|
||||
Console.WriteLine($"Found {apps.Length} app(s)");
|
||||
for (int i = 0; i < apps.Length; i++)
|
||||
Console.WriteLine($"{apps[i].Name} ({apps[i].Id}");
|
||||
}
|
||||
|
||||
private static void Upgrade(string identifier)
|
||||
{
|
||||
RepoManagement.GetReposFromDisk();
|
||||
App[] apps = AppExtras.FindApps(identifier);
|
||||
if (apps.Length == 0)
|
||||
Console.WriteLine("Package not found.");
|
||||
else
|
||||
{
|
||||
App tmp = apps.First();
|
||||
if ((tmp.status & Status.Updatable) == Status.Updatable)
|
||||
{
|
||||
Console.WriteLine($"Upgrading {tmp.Name}");
|
||||
AppExtras.Update(tmp);
|
||||
}
|
||||
else
|
||||
Console.WriteLine("Package is up-to-date");
|
||||
}
|
||||
}
|
||||
|
||||
private static void Reinstall(string identifier)
|
||||
{
|
||||
RepoManagement.GetReposFromDisk();
|
||||
App[] apps = AppExtras.FindApps(identifier);
|
||||
if (apps.Length == 0)
|
||||
Console.WriteLine("Package not found.");
|
||||
else
|
||||
{
|
||||
App tmp = apps.First();
|
||||
Console.WriteLine($"Reinstalling {tmp.Name}");
|
||||
AppExtras.Update(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
private static void Remove(string identifier)
|
||||
{
|
||||
RepoManagement.GetReposFromDisk();
|
||||
App[] apps = AppExtras.FindApps(identifier);
|
||||
if (apps.Length == 0)
|
||||
Console.WriteLine("Package not found.");
|
||||
else
|
||||
{
|
||||
App tmp = apps.First();
|
||||
if ((tmp.status & Status.Installed) == Status.Installed)
|
||||
{
|
||||
Console.WriteLine($"Removing {tmp.Name}");
|
||||
AppExtras.Remove(tmp, false);
|
||||
}
|
||||
else
|
||||
Console.WriteLine("Package is not installed");
|
||||
}
|
||||
}
|
||||
|
||||
private static void Purge(string identifier)
|
||||
{
|
||||
RepoManagement.GetReposFromDisk();
|
||||
App[] apps = AppExtras.FindApps(identifier);
|
||||
if (apps.Length == 0)
|
||||
Console.WriteLine("Package not found.");
|
||||
else
|
||||
{
|
||||
App tmp = apps.First();
|
||||
if ((tmp.status & Status.Installed) == Status.Installed)
|
||||
{
|
||||
Console.WriteLine($"Purgeing {tmp.Name}");
|
||||
AppExtras.Remove(tmp, true);
|
||||
}
|
||||
else
|
||||
Console.WriteLine("Package is not installed");
|
||||
}
|
||||
}
|
||||
|
||||
private static void Install(string identifier)
|
||||
{
|
||||
RepoManagement.GetReposFromDisk();
|
||||
App[] apps = AppExtras.FindApps(identifier);
|
||||
if (apps.Length == 0)
|
||||
Console.WriteLine("Package not found.");
|
||||
else
|
||||
{
|
||||
App tmp = apps.First();
|
||||
if ((tmp.status & Status.Installed) == Status.Installed)
|
||||
Console.WriteLine("Package is already installed");
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"Installing {tmp.Name}");
|
||||
AppInstall.Install(tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using UpToolLib.DataStructures;
|
||||
|
||||
namespace UpToolCLI
|
||||
{
|
||||
public class UTLibFunctions : IExternalFunctionality
|
||||
{
|
||||
public Tuple<bool, byte[]> Download(Uri link)
|
||||
{
|
||||
using WebClient client = new WebClient();
|
||||
byte[] result = new byte[0];
|
||||
bool finished = false;
|
||||
bool success = true;
|
||||
client.DownloadDataCompleted += (sender, e) =>
|
||||
{
|
||||
success = !e.Cancelled;
|
||||
if (success)
|
||||
result = e.Result;
|
||||
finished = true;
|
||||
};
|
||||
client.DownloadProgressChanged += (sender, e) =>
|
||||
{
|
||||
Console.Write($"{new string('=', e.ProgressPercentage / 10)}[{e.ProgressPercentage}]{new string('-', 10 - e.ProgressPercentage / 10)}");
|
||||
Console.CursorLeft = 0;
|
||||
};
|
||||
client.DownloadDataAsync(link);
|
||||
while (!finished)
|
||||
Thread.Sleep(100);
|
||||
return new Tuple<bool, byte[]>(success, result);
|
||||
}
|
||||
|
||||
public string FetchImageB64(Uri link)
|
||||
{
|
||||
using WebClient client = new WebClient();
|
||||
using Image image = Image.Load(client.OpenRead(link));
|
||||
image.Mutate(x => x.Resize(70, 70));
|
||||
using MemoryStream ms = new MemoryStream();
|
||||
image.SaveAsPng(ms);
|
||||
return Convert.ToBase64String(ms.ToArray());
|
||||
}
|
||||
|
||||
public bool YesNoDialog(string text, bool defaultVal)
|
||||
{
|
||||
bool choosing = true;
|
||||
bool current = defaultVal;
|
||||
Console.WriteLine(text);
|
||||
while (choosing)
|
||||
{
|
||||
Console.CursorLeft = 0;
|
||||
Console.BackgroundColor = current ? ConsoleColor.White : ConsoleColor.Black;
|
||||
Console.ForegroundColor = current ? ConsoleColor.Black : ConsoleColor.White;
|
||||
Console.Write("Yes");
|
||||
Console.ResetColor();
|
||||
Console.Write(" ");
|
||||
Console.BackgroundColor = current ? ConsoleColor.Black : ConsoleColor.White;
|
||||
Console.ForegroundColor = current ? ConsoleColor.White : ConsoleColor.Black;
|
||||
Console.Write("No");
|
||||
Console.ResetColor();
|
||||
switch (Console.ReadKey().Key)
|
||||
{
|
||||
case ConsoleKey.LeftArrow:
|
||||
case ConsoleKey.RightArrow:
|
||||
current = !current;
|
||||
break;
|
||||
case ConsoleKey.Enter:
|
||||
choosing = false;
|
||||
break;
|
||||
case ConsoleKey.Escape:
|
||||
current = defaultVal;
|
||||
choosing = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
Console.ResetColor();
|
||||
Console.WriteLine($" Selecting: {current}");
|
||||
return current;
|
||||
}
|
||||
|
||||
public void OKDialog(string text)
|
||||
{
|
||||
Console.WriteLine(text);
|
||||
Console.BackgroundColor = ConsoleColor.White;
|
||||
Console.Write("OK");
|
||||
Console.ResetColor();
|
||||
Console.ReadKey();
|
||||
}
|
||||
|
||||
public object GetDefaultIcon() => 0;
|
||||
|
||||
public object ImageFromB64(string b64) => 0;
|
||||
public void Log(string text) => Console.WriteLine(text);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<AssemblyName>uptool</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.0-beta0007" />
|
||||
<PackageReference Include="System.CommandLine" Version="2.0.0-beta1.20158.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\UpToolLib\UpToolLib.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -3,10 +3,10 @@ using System.Collections.Generic;
|
|||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using UpTool2.Tool;
|
||||
using UpToolLib.Tool;
|
||||
using static System.Environment;
|
||||
|
||||
namespace UpTool2.DataStructures
|
||||
namespace UpToolLib.DataStructures
|
||||
{
|
||||
public struct App : IEquatable<App>
|
||||
{
|
||||
|
@ -16,14 +16,14 @@ namespace UpTool2.DataStructures
|
|||
public readonly string File;
|
||||
public readonly bool Local;
|
||||
public readonly string Hash;
|
||||
private Guid _id;
|
||||
public readonly Guid Id;
|
||||
public Color Color;
|
||||
public readonly Image Icon;
|
||||
public readonly object Icon;
|
||||
public readonly bool Runnable;
|
||||
public readonly string MainFile;
|
||||
|
||||
public App(string name, string description, Version version, string file, bool local, string hash, Guid iD,
|
||||
Color color, Image icon, bool runnable, string mainFile)
|
||||
Color color, object icon, bool runnable, string mainFile)
|
||||
{
|
||||
Name = name ?? throw new ArgumentNullException(nameof(name));
|
||||
Description = description ?? throw new ArgumentNullException(nameof(description));
|
||||
|
@ -31,7 +31,7 @@ namespace UpTool2.DataStructures
|
|||
File = file ?? throw new ArgumentNullException(nameof(file));
|
||||
Local = local;
|
||||
Hash = hash ?? throw new ArgumentNullException(nameof(hash));
|
||||
_id = iD;
|
||||
Id = iD;
|
||||
Color = color;
|
||||
Icon = icon ?? throw new ArgumentNullException(nameof(icon));
|
||||
Runnable = runnable;
|
||||
|
@ -53,30 +53,30 @@ namespace UpTool2.DataStructures
|
|||
|
||||
public override bool Equals(object obj) => obj is App app && Equals(app);
|
||||
|
||||
public bool Equals(App other) => _id.Equals(other._id);
|
||||
public bool Equals(App other) => Id.Equals(other.Id);
|
||||
|
||||
public override int GetHashCode() => 1213502048 + EqualityComparer<Guid>.Default.GetHashCode(_id);
|
||||
public override int GetHashCode() => 1213502048 + EqualityComparer<Guid>.Default.GetHashCode(Id);
|
||||
|
||||
public override string ToString() => $@"Name: {Name}
|
||||
Description:
|
||||
{string.Join(NewLine, Description.Split('\n').Select(s => { if (s.EndsWith("\r")) s.Remove(s.Length - 1, 1); return "> " + s; }))}
|
||||
Version: {Version}
|
||||
File: {File}
|
||||
Local: {Local.ToString()}
|
||||
Local: {Local}
|
||||
Hash: {Hash}
|
||||
ID: {_id.ToString()}
|
||||
Color: {Color.ToKnownColor().ToString()}
|
||||
ID: {Id}
|
||||
Color: {Color.ToKnownColor()}
|
||||
Runnable: {Runnable}
|
||||
MainFile: {MainFile}
|
||||
Status: {status.ToString()}
|
||||
Status: {status}
|
||||
Object Hash Code: {GetHashCode()}";
|
||||
|
||||
public static bool operator ==(App left, App right) => left.Equals(right);
|
||||
|
||||
public static bool operator !=(App left, App right) => !(left == right);
|
||||
|
||||
public string appPath => PathTool.GetAppPath(_id);
|
||||
public string dataPath => PathTool.GetDataPath(_id);
|
||||
public string infoPath => PathTool.GetInfoPath(_id);
|
||||
public string appPath => PathTool.GetAppPath(Id);
|
||||
public string dataPath => PathTool.GetDataPath(Id);
|
||||
public string infoPath => PathTool.GetInfoPath(Id);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
|
||||
namespace UpToolLib.DataStructures
|
||||
{
|
||||
public interface IExternalFunctionality
|
||||
{
|
||||
public Tuple<bool, byte[]> Download(Uri link);
|
||||
public string FetchImageB64(Uri link);
|
||||
public bool YesNoDialog(string text, bool defaultVal);
|
||||
public void OKDialog(string text);
|
||||
public object GetDefaultIcon();
|
||||
public object ImageFromB64(string b64);
|
||||
public void Log(string text);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
|
||||
namespace UpTool2.DataStructures
|
||||
namespace UpToolLib.DataStructures
|
||||
{
|
||||
[Flags]
|
||||
public enum Status
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UpToolLib.DataStructures;
|
||||
|
||||
namespace UpToolLib
|
||||
{
|
||||
public static class ExternalFunctionalityManager
|
||||
{
|
||||
internal static IExternalFunctionality instance;
|
||||
|
||||
public static void Init(IExternalFunctionality externalFunctionality) =>
|
||||
instance = externalFunctionality;
|
||||
}
|
||||
}
|
|
@ -1,14 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UpTool2.DataStructures;
|
||||
using UpToolLib.DataStructures;
|
||||
|
||||
namespace UpTool2
|
||||
namespace UpToolLib
|
||||
{
|
||||
internal static class GlobalVariables
|
||||
public static class GlobalVariables
|
||||
{
|
||||
public static readonly Dictionary<Guid, App> Apps = new Dictionary<Guid, App>();
|
||||
public static bool RelE = true;
|
||||
public static Action ReloadElements;
|
||||
public static Version minimumVer => Version.Parse("0.0.0.0");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace UpToolLib.Properties {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("UpToolLib.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
|
@ -0,0 +1,70 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using UpToolLib.DataStructures;
|
||||
|
||||
namespace UpToolLib.Tool
|
||||
{
|
||||
public static class AppExtras
|
||||
{
|
||||
public static Process RunApp(App app) =>
|
||||
Process.Start(
|
||||
new ProcessStartInfo
|
||||
{
|
||||
FileName = Path.Combine(app.dataPath, app.MainFile),
|
||||
WorkingDirectory = app.dataPath
|
||||
});
|
||||
|
||||
public static void Update(App app)
|
||||
{
|
||||
Remove(app, false);
|
||||
AppInstall.Install(app);
|
||||
}
|
||||
|
||||
public static void Remove(App app, bool deleteAll)
|
||||
{
|
||||
string tmp = PathTool.tempPath;
|
||||
if (Directory.Exists(tmp))
|
||||
Directory.Delete(tmp, true);
|
||||
Directory.CreateDirectory(tmp);
|
||||
ZipFile.ExtractToDirectory(Path.Combine(app.appPath, "package.zip"), tmp);
|
||||
Process.Start(new ProcessStartInfo
|
||||
{
|
||||
FileName = "cmd.exe",
|
||||
Arguments = $"/C \"{Path.Combine(tmp, "Remove.bat")}\"",
|
||||
WorkingDirectory = Path.Combine(app.appPath, "app"),
|
||||
CreateNoWindow = true,
|
||||
WindowStyle = ProcessWindowStyle.Hidden
|
||||
}).WaitForExit();
|
||||
if (!deleteAll) CheckDirecory(Path.Combine(tmp, "Data"), app.dataPath);
|
||||
Directory.Delete(tmp, true);
|
||||
if (File.Exists(app.infoPath))
|
||||
File.Delete(app.infoPath);
|
||||
if (File.Exists(Path.Combine(app.appPath, "package.zip")))
|
||||
File.Delete(Path.Combine(app.appPath, "package.zip"));
|
||||
if (deleteAll || Directory.GetFiles(app.dataPath).Length + Directory.GetDirectories(app.dataPath).Length == 0)
|
||||
Directory.Delete(app.appPath, true);
|
||||
}
|
||||
|
||||
private static void CheckDirecory(string tmp, string app)
|
||||
{
|
||||
foreach (string file in Directory.GetFiles(tmp)) File.Delete(Path.Combine(app, Path.GetFileName(file)));
|
||||
foreach (string directory in Directory.GetDirectories(tmp))
|
||||
CheckDirecory(directory, Path.Combine(app, Path.GetFileName(directory)));
|
||||
if (Directory.GetFiles(app).Length + Directory.GetDirectories(app).Length == 0)
|
||||
Directory.Delete(app);
|
||||
}
|
||||
|
||||
public static App[] FindApps(string identifier)
|
||||
{
|
||||
Dictionary<Guid, App> tmp = GlobalVariables.Apps;
|
||||
IEnumerable<KeyValuePair<Guid, App>> tmp1 = tmp.Where(s => s.Key.ToString().StartsWith(identifier));
|
||||
tmp1 = tmp1.Concat(tmp.Where(s => s.Value.Name.Contains(identifier)));
|
||||
tmp1 = tmp1.Concat(tmp.Where(s => s.Value.Description.Contains(identifier)));
|
||||
return tmp1.Select(s => s.Value).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,14 +3,18 @@ using System.Diagnostics;
|
|||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Security.Cryptography;
|
||||
using System.Windows.Forms;
|
||||
using System.Xml.Linq;
|
||||
using UpTool2.DataStructures;
|
||||
using UpToolLib.DataStructures;
|
||||
|
||||
namespace UpTool2.Tool
|
||||
namespace UpToolLib.Tool
|
||||
{
|
||||
internal static class AppInstall
|
||||
public static class AppInstall
|
||||
{
|
||||
/// <summary>
|
||||
/// Install an application
|
||||
/// </summary>
|
||||
/// <param name="appI">The app to install</param>
|
||||
/// <param name="download">A method to download files. Input: app file, Outputs: whether the download was successful and the data</param>
|
||||
public static void Install(App appI)
|
||||
{
|
||||
string app = "";
|
||||
|
@ -27,19 +31,19 @@ namespace UpTool2.Tool
|
|||
if (Directory.Exists(app))
|
||||
Directory.Delete(app, true);
|
||||
Directory.CreateDirectory(app);
|
||||
using DownloadDialog dlg = new DownloadDialog(appI.File);
|
||||
if (dlg.ShowDialog() != DialogResult.OK)
|
||||
(bool dlSuccess, byte[] dlData) = ExternalFunctionalityManager.instance.Download(new Uri(appI.File));
|
||||
if (!dlSuccess)
|
||||
throw new Exception("Download failed");
|
||||
using (SHA256CryptoServiceProvider sha256 = new SHA256CryptoServiceProvider())
|
||||
{
|
||||
string pkgHash = BitConverter.ToString(sha256.ComputeHash(dlg.Result)).Replace("-", string.Empty)
|
||||
string pkgHash = BitConverter.ToString(sha256.ComputeHash(dlData)).Replace("-", string.Empty)
|
||||
.ToUpper();
|
||||
if (pkgHash != appI.Hash.ToUpper())
|
||||
throw new Exception($@"The hash is not equal to the one stored in the repo:
|
||||
Package: {pkgHash}
|
||||
Online: {appI.Hash.ToUpper()}");
|
||||
}
|
||||
File.WriteAllBytes(Path.Combine(app, "package.zip"), dlg.Result);
|
||||
File.WriteAllBytes(Path.Combine(app, "package.zip"), dlData);
|
||||
CompleteInstall(appI);
|
||||
#if !DEBUG
|
||||
}
|
||||
|
@ -110,8 +114,6 @@ Online: {appI.Hash.ToUpper()}");
|
|||
CreateNoWindow = true,
|
||||
WindowStyle = ProcessWindowStyle.Hidden
|
||||
}).WaitForExit();
|
||||
if (GlobalVariables.RelE)
|
||||
GlobalVariables.ReloadElements.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,9 +2,9 @@
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace UpTool2.Tool
|
||||
namespace UpToolLib.Tool
|
||||
{
|
||||
internal static class PathTool
|
||||
public static class PathTool
|
||||
{
|
||||
public static string dir =>
|
||||
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "UpTool2");
|
|
@ -0,0 +1,158 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Xml.Linq;
|
||||
using CC_Functions.Misc;
|
||||
using UpToolLib.DataStructures;
|
||||
|
||||
namespace UpToolLib.Tool
|
||||
{
|
||||
public static class RepoManagement
|
||||
{
|
||||
public static void FetchRepos()
|
||||
{
|
||||
XmlTool.FixXml();
|
||||
XElement meta = XDocument.Load(PathTool.InfoXml).Element("meta");
|
||||
List<XElement> tmpAppsList = new List<XElement>();
|
||||
List<string> repArr = meta.Element("Repos").Elements("Repo").Select(s => s.Element("Link").Value).Distinct()
|
||||
.ToList();
|
||||
int i = 0;
|
||||
while (i < repArr.Count)
|
||||
{
|
||||
#if !DEBUG
|
||||
try
|
||||
{
|
||||
#endif
|
||||
ExternalFunctionalityManager.instance.Log($"[{i + 1}] Loading {repArr[i]}");
|
||||
XDocument repo = XDocument.Load(new Uri(repArr[i]).Unshorten().AbsoluteUri);
|
||||
repArr.AddRange(repo.Element("repo").Elements("repolink").Select(s => s.Value)
|
||||
.Where(s => !repArr.Contains(s)));
|
||||
XElement[] tmp_apparray = repo.Element("repo").Elements("app").Where(app =>
|
||||
!tmpAppsList.Any(a => a.Element("ID").Value == app.Element("ID").Value) ||
|
||||
!tmpAppsList
|
||||
.Where(a => a.Element("ID").Value == app.Element("ID").Value).Any(a =>
|
||||
GetVer(a.Element("Version")) >= app.Element("Version").GetVer())).ToArray()
|
||||
.Concat(repo.Element("repo").Elements("applink")
|
||||
.Select(s =>
|
||||
{
|
||||
ExternalFunctionalityManager.instance.Log($"- Loading {s.Value}");
|
||||
return XDocument.Load(new Uri(s.Value).Unshorten().AbsoluteUri).Element("app");
|
||||
}))
|
||||
.ToArray();
|
||||
for (int i1 = 0; i1 < tmp_apparray.Length; i1++)
|
||||
{
|
||||
XElement app = tmp_apparray[i1];
|
||||
//"Sanity check"
|
||||
Version.Parse(app.Element("Version").Value);
|
||||
Guid.Parse(app.Element("ID").Value);
|
||||
//Create XElement
|
||||
tmpAppsList.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)
|
||||
tmpAppsList.Last().Add(new XElement("MainFile", app.Element("MainFile").Value));
|
||||
if (app.Element("Icon") != null)
|
||||
try
|
||||
{
|
||||
tmpAppsList.Last()
|
||||
.Add(new XElement("Icon", ExternalFunctionalityManager.instance.FetchImageB64(new Uri(app.Element("Icon").Value).Unshorten())));
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
if (tmpAppsList.Count(a => a.Element("ID").Value == app.Element("ID").Value) > 1)
|
||||
tmpAppsList.Where(a => a.Element("ID").Value == app.Element("ID").Value).Reverse()
|
||||
.Skip(1)
|
||||
.ToList().ForEach(a => tmpAppsList.Remove(a));
|
||||
}
|
||||
#if !DEBUG
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ExternalFunctionalityManager.instance.OKDialog($"Failed to load repo: {repArr[i]}{Environment.NewLine}{e}");
|
||||
}
|
||||
#endif
|
||||
i++;
|
||||
}
|
||||
tmpAppsList.Sort((x, y) =>
|
||||
string.Compare(x.Element("Name").Value, y.Element("Name").Value, StringComparison.Ordinal));
|
||||
if (meta.Element("LocalRepo") == null)
|
||||
meta.Add(new XElement("LocalRepo"));
|
||||
XElement repos = meta.Element("LocalRepo");
|
||||
repos.RemoveNodes();
|
||||
tmpAppsList.ForEach(app => repos.Add(app));
|
||||
meta.Save(PathTool.InfoXml);
|
||||
}
|
||||
|
||||
private static Version GetVer(this XElement el) =>
|
||||
int.TryParse(el.Value, out int i) ? new Version(0, 0, 0, i) : Version.Parse(el.Value);
|
||||
|
||||
/// <summary>
|
||||
/// Load the repository cache
|
||||
/// </summary>
|
||||
/// <param name="errorHandler">Function to call on an exception, will ask the user whether he wants to quit</param>
|
||||
public static void GetReposFromDisk()
|
||||
{
|
||||
GlobalVariables.Apps.Clear();
|
||||
string xml = PathTool.InfoXml;
|
||||
XDocument.Load(xml).Element("meta").Element("LocalRepo").Elements().ToList().ForEach(app =>
|
||||
{
|
||||
Guid id = Guid.Parse(app.Element("ID").Value);
|
||||
string locInPath = PathTool.GetInfoPath(id);
|
||||
XElement locIn = File.Exists(locInPath) ? XDocument.Load(locInPath).Element("app") : app;
|
||||
if (int.TryParse(app.Element("Version").Value, out _))
|
||||
app.Element("Version").Value = GlobalVariables.minimumVer.ToString();
|
||||
GlobalVariables.Apps.Add(id, new App(
|
||||
locIn.Element("Name").Value,
|
||||
locIn.Element("Description").Value,
|
||||
Version.Parse(app.Element("Version").Value),
|
||||
app.Element("File").Value,
|
||||
false,
|
||||
app.Element("Hash").Value,
|
||||
id,
|
||||
Color.White,
|
||||
app.Element("Icon") == null
|
||||
? ExternalFunctionalityManager.instance.GetDefaultIcon()
|
||||
: ExternalFunctionalityManager.instance.ImageFromB64(app.Element("Icon").Value),
|
||||
locIn.Element("MainFile") != null || app.Element("MainFile") != null,
|
||||
locIn.Element("MainFile") == null
|
||||
? app.Element("MainFile") == null ? "" : app.Element("MainFile").Value
|
||||
: locIn.Element("MainFile").Value
|
||||
));
|
||||
});
|
||||
Directory.GetDirectories(PathTool.appsPath)
|
||||
.Where(s => Guid.TryParse(Path.GetFileName(s), out Guid guid) &&
|
||||
!GlobalVariables.Apps.ContainsKey(guid)).ToList().ForEach(s =>
|
||||
{
|
||||
Guid tmp = Guid.Parse(Path.GetFileName(s));
|
||||
try
|
||||
{
|
||||
XElement data = XDocument.Load(PathTool.GetInfoPath(tmp)).Element("app");
|
||||
GlobalVariables.Apps.Add(tmp,
|
||||
new App("(local) " + data.Element("Name").Value, data.Element("Description").Value,
|
||||
GlobalVariables.minimumVer, "", true, "", tmp, Color.Red, ExternalFunctionalityManager.instance.GetDefaultIcon(),
|
||||
data.Element("MainFile") != null,
|
||||
data.Element("MainFile") == null ? "" : data.Element("MainFile").Value));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (ExternalFunctionalityManager.instance.YesNoDialog($@"An error occured while loading this local repo:
|
||||
{e.Message}
|
||||
Do you want to exit? Otherwise the folder will be deleted, possibly causeing problems later.", false))
|
||||
Environment.Exit(0);
|
||||
else
|
||||
Directory.Delete(PathTool.GetAppPath(tmp), true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace UpToolLib.Tool
|
||||
{
|
||||
public static class XmlTool
|
||||
{
|
||||
public static void FixXml()
|
||||
{
|
||||
if (!File.Exists(PathTool.InfoXml) || XDocument.Load(PathTool.InfoXml).Element("meta") == null)
|
||||
new XElement("meta").Save(PathTool.InfoXml);
|
||||
XDocument x = XDocument.Load(PathTool.InfoXml);
|
||||
XElement meta = x.Element("meta");
|
||||
if (meta.Element("UpdateSource") == null)
|
||||
meta.Add(new XElement("UpdateSource"));
|
||||
if (new[]
|
||||
{
|
||||
"",
|
||||
"https://raw.githubusercontent.com/CreepyCrafter24/UpTool2/master/Meta.xml",
|
||||
"https://raw.githubusercontent.com/JFronny/UpTool2/master/Meta.xml",
|
||||
"https://gist.githubusercontent.com/JFronny/f1ccbba3d8a2f5862592bb29fdb612c4/raw/Meta.xml"
|
||||
}
|
||||
.Contains(meta.Element("UpdateSource").Value))
|
||||
meta.Element("UpdateSource").Value =
|
||||
"https://github.com/JFronny/UpTool2/releases/latest/download/meta.xml";
|
||||
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://gist.githubusercontent.com/JFronny/f1ccbba3d8a2f5862592bb29fdb612c4/raw/Repo.xml")));
|
||||
meta.Element("Repos").Elements("Repo").Select(s => s.Element("Link"))
|
||||
.Where(s => new[]
|
||||
{
|
||||
null, "https://github.com/JFronny/UpTool2/releases/download/Repo/Repo.xml",
|
||||
"https://raw.githubusercontent.com/JFronny/UpTool2/master/Repo.xml"
|
||||
}.Contains(s.Value))
|
||||
.ToList().ForEach(s =>
|
||||
s.Value =
|
||||
"https://gist.githubusercontent.com/JFronny/f1ccbba3d8a2f5862592bb29fdb612c4/raw/Repo.xml");
|
||||
if (meta.Element("LocalRepo") == null)
|
||||
meta.Add(new XElement("LocalRepo"));
|
||||
x.Save(PathTool.InfoXml);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CC-Functions.Misc" Version="1.1.7388.28729" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
Reference in New Issue