mirror of
https://github.com/WinDurango/WinDurango.UI.git
synced 2026-01-31 00:55:24 +01:00
patching, also rewrite incoming (probably)
This commit is contained in:
@@ -4,6 +4,7 @@ using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Markup.Localizer;
|
||||
using Windows.Storage;
|
||||
using WinDurango.UI.Settings;
|
||||
using WinDurango.UI.Utils;
|
||||
@@ -14,7 +15,7 @@ namespace WinDurango.UI
|
||||
public partial class App : Application
|
||||
{
|
||||
// constants
|
||||
public static readonly string DataDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "WinDurango");
|
||||
public static readonly string DataDir = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "WinDurango"), "UI");
|
||||
public static readonly string AppDir = AppContext.BaseDirectory;
|
||||
private static readonly FileVersionInfo Fvi = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);
|
||||
// versioning
|
||||
@@ -39,9 +40,10 @@ namespace WinDurango.UI
|
||||
return (major, minor, patch);
|
||||
}
|
||||
|
||||
private async Task InitializeLocalizer()
|
||||
private static async Task InitializeLocalizer()
|
||||
{
|
||||
string StringsFolderPath = Path.Combine(AppContext.BaseDirectory, "Strings");
|
||||
Logger.WriteDebug(AppContext.BaseDirectory);
|
||||
StorageFolder stringsFolder = await StorageFolder.GetFolderFromPathAsync(StringsFolderPath);
|
||||
|
||||
ILocalizer localizer = await new LocalizerBuilder()
|
||||
@@ -51,6 +53,8 @@ namespace WinDurango.UI
|
||||
options.DefaultLanguage = "en-US";
|
||||
})
|
||||
.Build();
|
||||
// await localizer.SetLanguage(Settings.Settings.Language);
|
||||
Logger.WriteDebug($"Using language {localizer.GetCurrentLanguage()}");
|
||||
}
|
||||
|
||||
private void App_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.UI.Xaml;
|
||||
using CommunityToolkit.WinUI;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Media.Imaging;
|
||||
using System;
|
||||
@@ -6,6 +7,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel;
|
||||
using Windows.ApplicationModel.Core;
|
||||
using Windows.Foundation;
|
||||
@@ -24,12 +26,16 @@ namespace WinDurango.UI.Controls
|
||||
private string _Publisher;
|
||||
private string _Version;
|
||||
private Uri _Logo;
|
||||
private ProgressDialog currentDialog = null;
|
||||
// "Just Works"
|
||||
// this needs to be fixed.
|
||||
private bool shouldShowDone = true;
|
||||
|
||||
private async void HandleUnregister(object sender, SplitButtonClickEventArgs e)
|
||||
{
|
||||
if ((bool)unregisterCheckbox.IsChecked)
|
||||
{
|
||||
var confirmation = new Confirmation($"Are you sure you want to uninstall {_Name}?", "Uninstall?");
|
||||
var confirmation = new Confirmation(Localization.Locale.GetLocalizedText("Packages.UninstallConfirmation", _Name), "Uninstall?");
|
||||
Dialog.BtnClicked answer = await confirmation.Show();
|
||||
if (answer == Dialog.BtnClicked.Yes)
|
||||
{
|
||||
@@ -51,6 +57,58 @@ namespace WinDurango.UI.Controls
|
||||
_ = Process.Start(new ProcessStartInfo(_package.InstalledPath) { UseShellExecute = true });
|
||||
}
|
||||
|
||||
private async Task StatusUpdateAsync(string status, int progress)
|
||||
{
|
||||
if (currentDialog == null)
|
||||
{
|
||||
currentDialog = new ProgressDialog("Working", "Patcher", false);
|
||||
// shitty way of doing it
|
||||
if (new ProgressDialog("Working", "Patcher", false) != null)
|
||||
{
|
||||
await App.MainWindow.DispatcherQueue.EnqueueAsync(async () =>
|
||||
{
|
||||
await currentDialog.ShowAsync();
|
||||
});
|
||||
} else
|
||||
{
|
||||
Logger.WriteDebug("???");
|
||||
}
|
||||
} else
|
||||
{
|
||||
currentDialog.Text = status;
|
||||
currentDialog.Progress = progress;
|
||||
if (progress == 100)
|
||||
{
|
||||
Logger.WriteDebug("100");
|
||||
currentDialog.Hide();
|
||||
currentDialog = null;
|
||||
if (shouldShowDone)
|
||||
await new NoticeDialog("Done!", "Patcher").Show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async void RepatchPackage(object sender, RoutedEventArgs args)
|
||||
{
|
||||
shouldShowDone = false;
|
||||
await WinDurangoPatcher.UnpatchPackage(_package, StatusUpdateAsync);
|
||||
shouldShowDone = true;
|
||||
await WinDurangoPatcher.PatchPackage(_package, true, StatusUpdateAsync);
|
||||
App.MainWindow.ReloadAppList();
|
||||
}
|
||||
|
||||
private async void UnpatchPackage(object sender, RoutedEventArgs args)
|
||||
{
|
||||
await WinDurangoPatcher.UnpatchPackage(_package, StatusUpdateAsync);
|
||||
App.MainWindow.ReloadAppList();
|
||||
}
|
||||
|
||||
private async void PatchPackage(object sender, RoutedEventArgs args)
|
||||
{
|
||||
await WinDurangoPatcher.PatchPackage(_package, false, StatusUpdateAsync);
|
||||
App.MainWindow.ReloadAppList();
|
||||
}
|
||||
|
||||
public AppTile(string familyName)
|
||||
{
|
||||
_familyName = familyName;
|
||||
@@ -68,6 +126,7 @@ namespace WinDurango.UI.Controls
|
||||
_Publisher = _package.PublisherDisplayName ?? _package.Id.PublisherId;
|
||||
_Version = $"{_package.Id.Version.Major.ToString() ?? "U"}.{_package.Id.Version.Minor.ToString() ?? "U"}.{_package.Id.Version.Build.ToString() ?? "U"}.{_package.Id.Version.Revision.ToString() ?? "U"}";
|
||||
_Logo = _package.Logo;
|
||||
|
||||
string ss = Packages.GetSplashScreenPath(_package);
|
||||
IReadOnlyList<AppListEntry> appListEntries = null;
|
||||
try
|
||||
@@ -112,7 +171,32 @@ namespace WinDurango.UI.Controls
|
||||
}
|
||||
infoExpander.Header = _Name;
|
||||
|
||||
Flyout rcFlyout = new();
|
||||
MenuFlyout rcFlyout = new();
|
||||
|
||||
bool isPatched = InstalledPackages.GetInstalledPackage(_package.Id.FamilyName).Value.installedPackage.IsPatched;
|
||||
|
||||
MenuFlyoutItem patchButton = new MenuFlyoutItem
|
||||
{
|
||||
Text = isPatched ? "Repatch" : "Patch",
|
||||
Name = "patchButton"
|
||||
};
|
||||
|
||||
if (isPatched)
|
||||
{
|
||||
patchButton.Click += RepatchPackage;
|
||||
MenuFlyoutItem unpatchButton = new MenuFlyoutItem
|
||||
{
|
||||
Text = "Unpatch",
|
||||
Name = "unpatchButton"
|
||||
};
|
||||
unpatchButton.Click += UnpatchPackage;
|
||||
rcFlyout.Items.Add(unpatchButton);
|
||||
} else
|
||||
{
|
||||
patchButton.Click += PatchPackage;
|
||||
}
|
||||
|
||||
rcFlyout.Items.Add(patchButton);
|
||||
|
||||
expanderVersion.Text = $"Publisher: {_Publisher}\nVersion {_Version}";
|
||||
|
||||
|
||||
@@ -10,7 +10,10 @@ namespace WinDurango.UI.Localization
|
||||
{
|
||||
public static string GetLocalizedText(string name, params object[] args)
|
||||
{
|
||||
return string.Format(name.GetLocalizedString(), args);
|
||||
String translated = Localizer.Get().GetLocalizedString(name);
|
||||
if (translated == "")
|
||||
Logger.Write(LogLevel.Warning, $"String {name} not found in string resources.");
|
||||
return string.Format(translated == "" ? $"LOCALIZATION ERROR: String {name} not found in string resources." : translated, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,13 +132,13 @@ namespace WinDurango.UI.Pages
|
||||
{
|
||||
// there is no AppxManifest inside.
|
||||
Logger.WriteError($"Could not find AppxManifest.xml in {folder.Path} and {mountFolder}");
|
||||
await new NoticeDialog(GetLocalizedText("ManifestNotFoundMulti", folder.Path, mountFolder), "Error").Show();
|
||||
await new NoticeDialog(GetLocalizedText("Packages.Error.ManifestNotFoundMulti", folder.Path, mountFolder), "Error").Show();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.WriteError($"Could not find AppxManifest.xml in {folder.Path} and no Mount folder exists");
|
||||
await new NoticeDialog(GetLocalizedText("ManifestNotFoundNoMount", folder.Path), "Error").Show();
|
||||
await new NoticeDialog(GetLocalizedText("Packages.Error.ManifestNotFoundNoMount", folder.Path), "Error").Show();
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
@@ -3,14 +3,16 @@
|
||||
[](https://github.com/WinDurango-project/WinDurango.UI/stargazers)
|
||||
GUI for WinDurango, which is planned to allow for easy installing/patching among other random stuff I decide lmfao
|
||||
|
||||
### NOTICE: A large amount of the codebase has to be rewritten as I was not a good C# dev when this was originally made (statics everywhere, messy fields, etc)
|
||||
#### Additonally, the translation shit does NOT work at this moment, I cannot figure out why.
|
||||
|
||||
> [!NOTE]
|
||||
> This does nothing more than provide a GUI for easily registering and patching packages with WinDurango.
|
||||
> Additionally, I don't know much about C#... so the code is probably very messy.
|
||||
|
||||
# Roadmap
|
||||
|
||||
## Features
|
||||
- [ ] Compiling the DLLs and patching automatically
|
||||
- [X] Patching
|
||||
- [X] Allow for package removal from UI instead of just completely uninstalling.
|
||||
- [X] Installation options
|
||||
- [X] Scan for already installed EraOS/XUWP stuff
|
||||
|
||||
@@ -12,14 +12,17 @@ namespace WinDurango.UI.Settings
|
||||
{
|
||||
public string FullName { get; set; }
|
||||
public List<string> SymlinkedDLLs { get; set; }
|
||||
public List<string> OriginalDLLs { get; set; }
|
||||
public bool IsPatched { get; set; }
|
||||
}
|
||||
|
||||
// TODO: make this not static
|
||||
public abstract class InstalledPackages
|
||||
{
|
||||
|
||||
public static void RemoveInstalledPackage(Package pkg)
|
||||
{
|
||||
string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "WinDurango");
|
||||
string path = App.DataDir;
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
_ = Directory.CreateDirectory(path);
|
||||
@@ -127,7 +130,7 @@ namespace WinDurango.UI.Settings
|
||||
|
||||
public static void AddInstalledPackage(Package package)
|
||||
{
|
||||
string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "WinDurango");
|
||||
string path = App.DataDir;
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
_ = Directory.CreateDirectory(path);
|
||||
@@ -154,7 +157,9 @@ namespace WinDurango.UI.Settings
|
||||
installedPkgs[package.Id.FamilyName] = new InstalledPackage
|
||||
{
|
||||
FullName = package.Id.FullName,
|
||||
SymlinkedDLLs = []
|
||||
SymlinkedDLLs = [],
|
||||
OriginalDLLs = [],
|
||||
IsPatched = false
|
||||
};
|
||||
|
||||
string updated = JsonSerializer.Serialize(installedPkgs, new JsonSerializerOptions { WriteIndented = true });
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
@@ -22,6 +23,10 @@ public class WdSettingsData
|
||||
public uint SaveVersion { get; set; } = App.VerPacked;
|
||||
public ThemeSetting Theme { get; set; } = ThemeSetting.Fluent;
|
||||
public bool DebugLoggingEnabled { get; set; } = false;
|
||||
|
||||
public string Language { get; set; } = "en-US";
|
||||
|
||||
public string DownloadedWDVer { get; set; }
|
||||
}
|
||||
|
||||
public class WdSettings
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
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">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<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" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</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>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="EDbgLog" xml:space="preserve">
|
||||
<value>Enable debug logging</value>
|
||||
</data>
|
||||
<data name="DDbgLog" xml:space="preserve">
|
||||
<value>Disable debug logging</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1,143 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
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">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</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.Runtime.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:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<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" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</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>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ManifestNotFoundNoMount" xml:space="preserve">
|
||||
<value>AppxManifest does not exist in {0} and there is no "Mount" folder.</value>
|
||||
<comment>for when AppxManifest.xml is not found and there is no Mount folder to look in</comment>
|
||||
</data>
|
||||
<data name="MountNotFound" xml:space="preserve">
|
||||
<value>{0} was not found.</value>
|
||||
</data>
|
||||
<data name="ManifestNotFoundMulti" xml:space="preserve">
|
||||
<value>AppxManifest does not exist in {0} and {1}</value>
|
||||
<comment>for when it's not found in either the Mount folder or current chosen folder</comment>
|
||||
</data>
|
||||
<data name="NotFound" xml:space="preserve">
|
||||
<value>{0} was not found.</value>
|
||||
</data>
|
||||
<data name="AlreadyInstalled" xml:space="preserve">
|
||||
<value>{0} is already installed.</value>
|
||||
</data>
|
||||
<data name="PackageInstallFailedEx" xml:space="preserve">
|
||||
<value>{0} failed to install: {1}</value>
|
||||
</data>
|
||||
<data name="PackageUninstallFailedEx" xml:space="preserve">
|
||||
<value>Failed to uninstall {0}: {1}</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -117,28 +117,60 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="ReadingManifest" xml:space="preserve">
|
||||
<data name="Packages.ReadingManifest" xml:space="preserve">
|
||||
<value>Reading manifest...</value>
|
||||
</data>
|
||||
<data name="CheckingInstallStatus" xml:space="preserve">
|
||||
<data name="Packages.CheckingInstallStatus" xml:space="preserve">
|
||||
<value>Checking if {0} is already installed...</value>
|
||||
</data>
|
||||
<data name="InstallingPackage" xml:space="preserve">
|
||||
<data name="Packages.InstallingPackage" xml:space="preserve">
|
||||
<value>Installing {0}...</value>
|
||||
</data>
|
||||
<data name="GettingAppInfo" xml:space="preserve">
|
||||
<data name="Packages.GettingAppInfo" xml:space="preserve">
|
||||
<value>Getting app info...</value>
|
||||
</data>
|
||||
<data name="UpdatingAppList" xml:space="preserve">
|
||||
<data name="Ui.UpdatingAppList" xml:space="preserve">
|
||||
<value>Updating app list...</value>
|
||||
</data>
|
||||
<data name="PackageInstalled" xml:space="preserve">
|
||||
<data name="Packages.PackageInstalled" xml:space="preserve">
|
||||
<value>{0} was installed! :)</value>
|
||||
</data>
|
||||
<data name="UninstallingPackage" xml:space="preserve">
|
||||
<data name="Packages.UninstallingPackage" xml:space="preserve">
|
||||
<value>Uninstalling {0}...</value>
|
||||
</data>
|
||||
<data name="PackageUninstalled" xml:space="preserve">
|
||||
<data name="Packages.PackageUninstalled" xml:space="preserve">
|
||||
<value>{0} was uninstalled.</value>
|
||||
</data>
|
||||
<data name="Packages.Error.AlreadyInstalled" xml:space="preserve">
|
||||
<value>{0} is already installed.</value>
|
||||
</data>
|
||||
<data name="Packages.Error.PackageUninstallFailedEx" xml:space="preserve">
|
||||
<value>Failed to uninstall {0}: {1}</value>
|
||||
</data>
|
||||
<data name="Error.NotFound" xml:space="preserve">
|
||||
<value>{0} was not found.</value>
|
||||
</data>
|
||||
<data name="Packages.Error.PackageInstallFailedEx" xml:space="preserve">
|
||||
<value>{0} failed to install: {1}</value>
|
||||
</data>
|
||||
<data name="Packages.Error.ManifestNotFoundNoMount" xml:space="preserve">
|
||||
<value>AppxManifest does not exist in {0} and there is no "Mount" folder.</value>
|
||||
<comment>for when AppxManifest.xml is not found and there is no Mount folder to look in</comment>
|
||||
</data>
|
||||
<data name="Packages.Error.ManifestNotFoundMulti" xml:space="preserve">
|
||||
<value>AppxManifest does not exist in {0} and {1}</value>
|
||||
<comment>for when it's not found in either the Mount folder or current chosen folder</comment>
|
||||
</data>
|
||||
<data name="Error.MountNotFound" xml:space="preserve">
|
||||
<value>{0} was not found.</value>
|
||||
</data>
|
||||
<data name="Ui.Controls.EDbgLog" xml:space="preserve">
|
||||
<value>Enable debug logging</value>
|
||||
</data>
|
||||
<data name="Ui.Controls.DDbgLog" xml:space="preserve">
|
||||
<value>Disable debug logging</value>
|
||||
</data>
|
||||
<data name="Packages.UninstallConfirmation" xml:space="preserve">
|
||||
<value>Are you sure you want to uninstall {0}?</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -12,7 +12,7 @@ namespace WinDurango.UI.Utils
|
||||
public class Logger
|
||||
{
|
||||
public static readonly Logger Instance = new();
|
||||
private static readonly string logDir = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "WinDurango"), "logs");
|
||||
private static readonly string logDir = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "WinDurango\\UI"), "logs");
|
||||
private static readonly string logFile = Path.Combine(logDir, $"WinDurangoUI_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.log");
|
||||
private static readonly object @lock = new();
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace WinDurango.UI.Utils
|
||||
Directory.CreateDirectory(logDir);
|
||||
}
|
||||
|
||||
public static void WriteLine(string str) => Instance.WriteLog(LogLevel.Info, str);
|
||||
public static void WriteDebug(string str) => Instance.WriteLog(LogLevel.Debug, str);
|
||||
public static void WriteError(string str) => Instance.WriteLog(LogLevel.Error, str);
|
||||
public static void WriteWarning(string str) => Instance.WriteLog(LogLevel.Warning, str);
|
||||
@@ -52,7 +53,6 @@ namespace WinDurango.UI.Utils
|
||||
|
||||
string logEntry = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] [{level.ToString().ToUpper()}] {message}";
|
||||
Debug.WriteLine(logEntry);
|
||||
|
||||
lock (@lock)
|
||||
{
|
||||
using StreamWriter writer = new(logFile, true);
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace WinDurango.UI.Utils
|
||||
|
||||
if (!Directory.Exists(mountDir))
|
||||
{
|
||||
await new NoticeDialog(GetLocalizedText($"mountNotFound", mountDir), "Error").Show();
|
||||
await new NoticeDialog(GetLocalizedText($"Error.mountNotFound", mountDir), "Error").Show();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -77,20 +77,21 @@ namespace WinDurango.UI.Utils
|
||||
|
||||
var (familyName, installedPackage) = InstalledPackages.GetInstalledPackage(package).Value;
|
||||
|
||||
if (hasExvd)
|
||||
{
|
||||
foreach (string filePath in Directory.GetFiles(Path.Combine(exvdDir + "\\Windows\\System32")))
|
||||
{
|
||||
string fileName = Path.GetFileName(filePath);
|
||||
// DO NOT COPY THE DLLS FROM THIS
|
||||
//if (hasExvd)
|
||||
//{
|
||||
// foreach (string filePath in Directory.GetFiles(Path.Combine(exvdDir + "\\Windows\\System32")))
|
||||
// {
|
||||
// string fileName = Path.GetFileName(filePath);
|
||||
|
||||
if (File.Exists(Path.Combine(mountDir, fileName)))
|
||||
continue;
|
||||
// if (File.Exists(Path.Combine(mountDir, fileName)))
|
||||
// continue;
|
||||
|
||||
FileSystemInfo symlink = File.CreateSymbolicLink(Path.Combine(mountDir, fileName), filePath);
|
||||
installedPackage.SymlinkedDLLs.Add(symlink.Name);
|
||||
InstalledPackages.UpdateInstalledPackage(familyName, installedPackage);
|
||||
}
|
||||
}
|
||||
// FileSystemInfo symlink = File.CreateSymbolicLink(Path.Combine(mountDir, fileName), filePath);
|
||||
// installedPackage.SymlinkedDLLs.Add(symlink.Name);
|
||||
// InstalledPackages.UpdateInstalledPackage(familyName, installedPackage);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
public static string GetSplashScreenPath(Package pkg)
|
||||
@@ -145,19 +146,19 @@ namespace WinDurango.UI.Utils
|
||||
// TODO: strip UI
|
||||
if (!File.Exists(manifestPath))
|
||||
{
|
||||
await new NoticeDialog(GetLocalizedText("NotFound", manifestPath), "Error").Show();
|
||||
await new NoticeDialog(GetLocalizedText("Error.NotFound", manifestPath), "Error").Show();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Logger.WriteInformation($"Installing package \"{manifestPath}\"...");
|
||||
var status = new ProgressDialog($"Installing package...", "Installing", false);
|
||||
var status = new ProgressDialog(GetLocalizedText("Packages.InstallingPackage", "Package..."), "Installing", false);
|
||||
_ = App.MainWindow.DispatcherQueue.TryEnqueue(async () => await status.ShowAsync());
|
||||
PackageManager pm = new();
|
||||
try
|
||||
{
|
||||
Logger.WriteInformation($"Reading manifest...");
|
||||
status.Text = "ReadingManifest".GetLocalizedString();
|
||||
status.Text = "Packages.ReadingManifest".GetLocalizedString();
|
||||
string manifest;
|
||||
await using (var stream = File.OpenRead(manifestPath))
|
||||
{
|
||||
@@ -181,24 +182,24 @@ namespace WinDurango.UI.Utils
|
||||
{
|
||||
status.Hide();
|
||||
Logger.WriteError($"{pkgName} is already installed.");
|
||||
await new NoticeDialog(GetLocalizedText("AlreadyInstalled", pkgName), "Error").Show();
|
||||
await new NoticeDialog(GetLocalizedText("Error.AlreadyInstalled", pkgName), "Error").Show();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
status.Progress = 40.0;
|
||||
status.Text = GetLocalizedText("InstallingPackage", pkgName);
|
||||
status.Text = GetLocalizedText("Packages.InstallingPackage", pkgName);
|
||||
Logger.WriteInformation($"Registering...");
|
||||
var deployment = await pm.RegisterPackageAsync(appxManifestUri, null, DeploymentOptions.DevelopmentMode);
|
||||
|
||||
status.Progress = 60.0;
|
||||
|
||||
status.Text = "GettingAppInfo".GetLocalizedString();
|
||||
status.Text = "Packages.GettingAppInfo".GetLocalizedString();
|
||||
var recentPkg = GetMostRecentlyInstalledPackage();
|
||||
|
||||
if (addInstalledPackage)
|
||||
{
|
||||
status.Text = $"UpdatingAppList".GetLocalizedString();
|
||||
status.Text = $"Ui.UpdatingAppList".GetLocalizedString();
|
||||
status.Progress = 80.0;
|
||||
InstalledPackages.AddInstalledPackage(recentPkg);
|
||||
status.Progress = 90.0;
|
||||
@@ -212,7 +213,7 @@ namespace WinDurango.UI.Utils
|
||||
|
||||
status.Hide();
|
||||
Logger.WriteInformation($"{recentPkg.Id.Name} was installed.");
|
||||
await new NoticeDialog(GetLocalizedText("PackageInstalled", recentPkg.Id.Name)).Show();
|
||||
await new NoticeDialog(GetLocalizedText("Packages.PackageInstalled", recentPkg.Id.Name)).Show();
|
||||
return recentPkg.Id.FamilyName;
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -221,7 +222,7 @@ namespace WinDurango.UI.Utils
|
||||
status.Hide();
|
||||
Logger.WriteError($"{appxManifestUri} failed to install");
|
||||
Logger.WriteException(e);
|
||||
await new NoticeDialog(GetLocalizedText("PackageInstallFailedEx", appxManifestUri, e.Message), "Error").Show();
|
||||
await new NoticeDialog(GetLocalizedText("Packages.Error.PackageInstallFailedEx", appxManifestUri, e.Message), "Error").Show();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -229,7 +230,7 @@ namespace WinDurango.UI.Utils
|
||||
public static async Task RemovePackage(Package package)
|
||||
{
|
||||
Logger.WriteError($"Uninstalling {package.DisplayName}...");
|
||||
var status = new ProgressDialog(GetLocalizedText("UninstallingPackage", package.DisplayName), "Uninstalling", false);
|
||||
var status = new ProgressDialog(GetLocalizedText("Packages.UninstallingPackage", package.DisplayName), "Uninstalling", false);
|
||||
_ = App.MainWindow.DispatcherQueue.TryEnqueue(async () => await status.ShowAsync());
|
||||
PackageManager pm = new();
|
||||
try
|
||||
@@ -241,7 +242,7 @@ namespace WinDurango.UI.Utils
|
||||
status.Progress = 100.0;
|
||||
status.Hide();
|
||||
Logger.WriteInformation($"{package.DisplayName} was uninstalled.");
|
||||
await new NoticeDialog(GetLocalizedText("PackageUninstalled", package.DisplayName)).Show();
|
||||
await new NoticeDialog(GetLocalizedText("Packages.PackageUninstalled", package.DisplayName)).Show();
|
||||
App.MainWindow.ReloadAppList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -249,7 +250,7 @@ namespace WinDurango.UI.Utils
|
||||
status.Hide();
|
||||
Logger.WriteError($"{package.DisplayName} failed to uninstall");
|
||||
Logger.WriteException(ex);
|
||||
await new NoticeDialog(GetLocalizedText("PackageUninstallFailedEx", package.DisplayName, ex.Message), "Error!").Show();
|
||||
await new NoticeDialog(GetLocalizedText("Packages.Error.PackageUninstallFailedEx", package.DisplayName, ex.Message), "Error!").Show();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
233
Utils/WinDurangoPatcher.cs
Normal file
233
Utils/WinDurangoPatcher.cs
Normal file
@@ -0,0 +1,233 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.IO.Packaging;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Policy;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel;
|
||||
using WinDurango.UI.Settings;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
|
||||
namespace WinDurango.UI.Utils
|
||||
{
|
||||
public class GitHubRelease
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string DownloadLink { get; set; }
|
||||
}
|
||||
|
||||
public class WinDurangoPatcher
|
||||
{
|
||||
private static GitHubRelease wdRelease;
|
||||
private static string patchDir = Path.Combine(App.DataDir, "WinDurangoCore");
|
||||
|
||||
public static async Task<bool> PatchPackage(Windows.ApplicationModel.Package package, bool forceRedownload, Func<string, int, Task> statusCallback)
|
||||
{
|
||||
Logger.WriteInformation($"Patching package {package.Id.FamilyName}");
|
||||
statusCallback($"Patching {package.Id.FamilyName}", 0);
|
||||
string curDate = DateTime.UtcNow.ToString("yyyy-MM-dd_HH-mm-ss");
|
||||
var instPkg = InstalledPackages.GetInstalledPackage(package.Id.FamilyName);
|
||||
|
||||
string installPath = package.InstalledPath;
|
||||
|
||||
statusCallback($"Getting release", 10);
|
||||
await GetOrReuseRelease(); // don't use the return value since wdRelease is set regardless
|
||||
|
||||
|
||||
if (!Path.Exists(patchDir) || forceRedownload)
|
||||
{
|
||||
if (forceRedownload && Path.Exists(patchDir))
|
||||
Directory.Delete(patchDir, true);
|
||||
|
||||
string zip = Path.Combine(App.DataDir, "WinDurangoCore.zip");
|
||||
|
||||
try
|
||||
{
|
||||
using (HttpClient client = new HttpClient(new HttpClientHandler { AllowAutoRedirect = true }))
|
||||
{
|
||||
statusCallback($"Downloading WinDurango release \"{wdRelease.Name}\"", 20);
|
||||
Logger.WriteInformation($"Downloading WinDurango release \"{wdRelease.Name}\"");
|
||||
using (HttpResponseMessage res = await client.GetAsync(wdRelease.DownloadLink, HttpCompletionOption.ResponseHeadersRead))
|
||||
{
|
||||
res.EnsureSuccessStatusCode();
|
||||
|
||||
using (FileStream stream = new FileStream(zip, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||
{
|
||||
statusCallback($"Writing release zip", 30);
|
||||
await res.Content.CopyToAsync(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteException(ex);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(patchDir);
|
||||
Logger.WriteInformation($"Unzipping");
|
||||
statusCallback($"Unzipping", 40);
|
||||
ZipFile.ExtractToDirectory(zip, patchDir);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.WriteException(ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
statusCallback($"Patching", 50);
|
||||
if (Path.Exists(patchDir))
|
||||
{
|
||||
DirectoryInfo unzipped = new DirectoryInfo(patchDir);
|
||||
|
||||
var unzippedFiles = unzipped.GetFiles("*.dll");
|
||||
float prog = (90 - 50) / (float)unzippedFiles.Length;
|
||||
DirectoryInfo pkg = new DirectoryInfo(installPath);
|
||||
|
||||
foreach (var file in unzippedFiles)
|
||||
{
|
||||
int progress = (int)Math.Round(50 + prog * Array.IndexOf(unzippedFiles, file));
|
||||
statusCallback($"Copying {file.Name}", progress);
|
||||
var pkgFName = pkg.GetFiles("*.dll").FirstOrDefault(pkgFName => pkgFName.Name == file.Name);
|
||||
if (pkgFName != null)
|
||||
{
|
||||
Logger.WriteInformation($"Backing up old {pkgFName.Name}");
|
||||
string DllBackup = Path.Combine(installPath, "WDDllBackup", curDate);
|
||||
if (!Path.Exists(DllBackup))
|
||||
Directory.CreateDirectory(DllBackup);
|
||||
|
||||
File.Move(pkgFName.FullName, Path.Combine(DllBackup, pkgFName.Name));
|
||||
if (!instPkg.Value.installedPackage.OriginalDLLs.Contains(Path.Combine(DllBackup, pkgFName.Name)))
|
||||
instPkg.Value.installedPackage.OriginalDLLs.Add(Path.Combine(DllBackup, pkgFName.Name));
|
||||
}
|
||||
|
||||
string symPath = Path.Combine(installPath, file.Name);
|
||||
Logger.WriteInformation($"Added {file.Name}");
|
||||
File.Copy(file.FullName, Path.Combine(installPath, file.Name));
|
||||
if (!instPkg.Value.installedPackage.SymlinkedDLLs.Contains(symPath))
|
||||
instPkg.Value.installedPackage.SymlinkedDLLs.Add(symPath);
|
||||
}
|
||||
} else
|
||||
{
|
||||
Logger.WriteError("How did this happen???? patchDir should exist.");
|
||||
return false;
|
||||
}
|
||||
|
||||
statusCallback($"Updating package list", 95);
|
||||
instPkg.Value.installedPackage.IsPatched = true;
|
||||
InstalledPackages.UpdateInstalledPackage(instPkg.Value.familyName, instPkg.Value.installedPackage);
|
||||
statusCallback($"Done!", 100);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static async Task<bool> UnpatchPackage(Windows.ApplicationModel.Package package, Func<string, int, Task> statusCallback)
|
||||
{
|
||||
Logger.WriteInformation($"Unpatching package {package.Id.FamilyName}");
|
||||
statusCallback($"Unpatching {package.Id.FamilyName}", 0);
|
||||
var instPkg = InstalledPackages.GetInstalledPackage(package.Id.FamilyName);
|
||||
var dlls = instPkg.Value.installedPackage.SymlinkedDLLs.ToArray();
|
||||
var origDlls = instPkg.Value.installedPackage.OriginalDLLs.ToArray();
|
||||
|
||||
string installPath = package.InstalledPath;
|
||||
|
||||
float delProg = (0 - 50) / (float)instPkg.Value.installedPackage.SymlinkedDLLs.Count;
|
||||
foreach (var dll in dlls)
|
||||
{
|
||||
int progress = (int)Math.Round(50 + delProg * Array.IndexOf(instPkg.Value.installedPackage.SymlinkedDLLs.ToArray(), dll));
|
||||
statusCallback($"Removing {dll}", progress);
|
||||
try
|
||||
{
|
||||
File.Delete(dll);
|
||||
} catch
|
||||
{
|
||||
Logger.WriteError($"Failed to delete {dll}.");
|
||||
}
|
||||
if (instPkg.Value.installedPackage.SymlinkedDLLs.Contains(dll))
|
||||
instPkg.Value.installedPackage.SymlinkedDLLs.Remove(dll);
|
||||
};
|
||||
|
||||
float repProg = (99 - 50) / (float)instPkg.Value.installedPackage.OriginalDLLs.Count;
|
||||
foreach (var dll in origDlls)
|
||||
{
|
||||
int progress = (int)Math.Round(50 + delProg * Array.IndexOf(origDlls, dll));
|
||||
statusCallback($"Placing back original DLL \"{dll}\"", progress);
|
||||
try
|
||||
{
|
||||
File.Copy(dll, Path.Combine(installPath, dll));
|
||||
}
|
||||
catch
|
||||
{
|
||||
Logger.WriteError($"Failed to copy {dll}.");
|
||||
}
|
||||
if (instPkg.Value.installedPackage.OriginalDLLs.Contains(dll))
|
||||
instPkg.Value.installedPackage.OriginalDLLs.Remove(dll);
|
||||
};
|
||||
|
||||
instPkg.Value.installedPackage.IsPatched = false;
|
||||
|
||||
statusCallback($"Updating package list", 99);
|
||||
InstalledPackages.UpdateInstalledPackage(instPkg.Value.familyName, instPkg.Value.installedPackage);
|
||||
statusCallback($"Done!", 100);
|
||||
return true;
|
||||
}
|
||||
|
||||
// don't wanna use all the api shits lol
|
||||
public static async Task<GitHubRelease> GetOrReuseRelease()
|
||||
{
|
||||
if (wdRelease.GetType() != typeof(GitHubRelease))
|
||||
await GetLatestRelease();
|
||||
|
||||
return wdRelease;
|
||||
}
|
||||
|
||||
public static async Task<GitHubRelease> GetLatestRelease()
|
||||
{
|
||||
GitHubRelease release = new GitHubRelease();
|
||||
|
||||
string url = $"https://api.github.com/repos/WinDurango/WinDurango/releases";
|
||||
|
||||
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
|
||||
client.DefaultRequestHeaders.UserAgent.ParseAdd("Mozilla/5.0 (compatible; GitHubAPI/1.0)");
|
||||
var response = await client.GetAsync(url);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
|
||||
JsonDocument document = JsonDocument.Parse(json);
|
||||
var releases = document.RootElement.EnumerateArray();
|
||||
|
||||
if (!releases.MoveNext())
|
||||
throw new Exception("Couldn't find any releases?????");
|
||||
|
||||
JsonElement newestRelease = releases.Current;
|
||||
|
||||
string name = newestRelease.GetProperty("name").GetString();
|
||||
|
||||
release.Name = name;
|
||||
|
||||
var assets = newestRelease.GetProperty("assets").EnumerateArray();
|
||||
|
||||
if (!assets.MoveNext())
|
||||
throw new Exception("Couldn't find any assets?????");
|
||||
|
||||
string download = assets.Current.GetProperty("browser_download_url").GetString();
|
||||
|
||||
release.DownloadLink = download;
|
||||
|
||||
wdRelease = release;
|
||||
return release;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,6 @@
|
||||
<ItemGroup>
|
||||
<None Remove="Controls\AppTile.xaml" />
|
||||
<None Remove="Controls\ContributorInfo.xaml" />
|
||||
<None Remove="Controls\NewFile1.txt" />
|
||||
<None Remove="Dialogs\AppListDialog.xaml" />
|
||||
<None Remove="Dialogs\InstallConfirmationDialog.xaml" />
|
||||
<None Remove="Pages\AboutPage.xaml" />
|
||||
@@ -42,6 +41,31 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<WindowsSdkPackageVersion>10.0.26100.38</WindowsSdkPackageVersion>
|
||||
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||
<DebugType>embedded</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -100,12 +124,6 @@
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Remove="Strings\en-US\Controls.resw" />
|
||||
<Content Remove="Strings\en-US\Errors.resw" />
|
||||
<Content Remove="Strings\en-US\Resources.resw" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="D:\Projects\Dev\C#\WinDurango.UI\.editorconfig" />
|
||||
</ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user