From be187e851fef70f2755e22704d89aa4da0d910bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Fri, 30 Aug 2024 23:44:12 +0200 Subject: [PATCH 01/13] Move folders one level up --- .../Dialogs/AboutUniGetUI.xaml | 0 .../Dialogs/AboutUniGetUI.xaml.cs | 0 .../Dialogs/IgnoredUpdates.xaml | 0 .../Dialogs/IgnoredUpdates.xaml.cs | 0 .../Dialogs/InstallOptions.xaml | 0 .../Dialogs/InstallOptions.xaml.cs | 0 .../{Interface => }/Dialogs/ReleaseNotes.xaml | 0 .../Dialogs/ReleaseNotes.xaml.cs | 0 src/UniGetUI/{Interface => }/MainView.xaml | 0 src/UniGetUI/{Interface => }/MainView.xaml.cs | 0 src/UniGetUI/{Interface => }/MainWindow.xaml | 0 .../{Interface => }/MainWindow.xaml.cs | 0 .../OperationControl.xaml | 0 .../OperationControl.xaml.cs | 0 .../PackageOperations.cs | 0 .../SourceOperations.cs | 0 .../Pages/AboutPages/AboutUniGetUI.xaml | 0 .../Pages/AboutPages/AboutUniGetUI.xaml.cs | 0 .../Pages/AboutPages/Contributors.xaml | 0 .../Pages/AboutPages/Contributors.xaml.cs | 0 .../Pages/AboutPages/SupportMe.xaml | 0 .../Pages/AboutPages/SupportMe.xaml.cs | 0 .../Pages/AboutPages/ThirdPartyLicenses.xaml | 0 .../AboutPages/ThirdPartyLicenses.xaml.cs | 0 .../Pages/AboutPages/Translators.xaml | 0 .../Pages/AboutPages/Translators.xaml.cs | 0 .../{Interface => }/Pages/HelpPage.xaml | 0 .../{Interface => }/Pages/HelpPage.xaml.cs | 0 .../Pages/IPageWithKeyboardShortcuts.cs | 0 .../Pages/LogPage/AppLogPage.cs | 0 .../Pages/LogPage/LogPage.xaml | 0 .../Pages/LogPage/LogPage.xaml.cs | 0 .../Pages/LogPage/ManagerLogsPage.cs | 0 .../Pages/LogPage/OperationHistoryPage.cs | 0 .../Pages/PackageDetailsPage.xaml | 0 .../Pages/PackageDetailsPage.xaml.cs | 0 .../{Interface => }/Pages/SettingsPage.xaml | 0 .../Pages/SettingsPage.xaml.cs | 0 .../SoftwarePages/AbstractPackagesPage.xaml | 0 .../AbstractPackagesPage.xaml.cs | 0 .../SoftwarePages/DiscoverSoftwarePage.cs | 0 .../SoftwarePages/InstalledPackagesPage.cs | 0 .../SoftwarePages/PackageBundlesPage.cs | 0 .../SoftwarePages/SoftwareUpdatesPage.cs | 0 src/UniGetUI/UniGetUI.csproj | 34 ++----------------- src/UniGetUI/UniGetUI.csproj.user | 33 ------------------ .../{Interface => }/Widgets/Announcer.xaml | 0 .../{Interface => }/Widgets/Announcer.xaml.cs | 0 .../{Interface => }/Widgets/ButtonCard.cs | 0 .../{Interface => }/Widgets/CheckboxCard.cs | 0 .../{Interface => }/Widgets/ComboboxCard.cs | 0 .../Widgets/DialogCloseButton.xaml | 0 .../Widgets/DialogCloseButton.xaml.cs | 0 .../{Interface => }/Widgets/LocalIcon.cs | 0 .../{Interface => }/Widgets/MenuForPackage.cs | 0 .../{Interface => }/Widgets/NavButton.xaml | 0 .../{Interface => }/Widgets/NavButton.xaml.cs | 0 .../Widgets/PackageItemContainer.cs | 0 .../{Interface => }/Widgets/SettingsEntry.cs | 0 .../Widgets/SourceManager.xaml | 0 .../Widgets/SourceManager.xaml.cs | 0 .../{Interface => }/Widgets/TextboxCard.cs | 0 .../Widgets/TranslatedTextBlock.xaml | 0 .../Widgets/TranslatedTextBlock.xaml.cs | 0 64 files changed, 3 insertions(+), 64 deletions(-) rename src/UniGetUI/{Interface => }/Dialogs/AboutUniGetUI.xaml (100%) rename src/UniGetUI/{Interface => }/Dialogs/AboutUniGetUI.xaml.cs (100%) rename src/UniGetUI/{Interface => }/Dialogs/IgnoredUpdates.xaml (100%) rename src/UniGetUI/{Interface => }/Dialogs/IgnoredUpdates.xaml.cs (100%) rename src/UniGetUI/{Interface => }/Dialogs/InstallOptions.xaml (100%) rename src/UniGetUI/{Interface => }/Dialogs/InstallOptions.xaml.cs (100%) rename src/UniGetUI/{Interface => }/Dialogs/ReleaseNotes.xaml (100%) rename src/UniGetUI/{Interface => }/Dialogs/ReleaseNotes.xaml.cs (100%) rename src/UniGetUI/{Interface => }/MainView.xaml (100%) rename src/UniGetUI/{Interface => }/MainView.xaml.cs (100%) rename src/UniGetUI/{Interface => }/MainWindow.xaml (100%) rename src/UniGetUI/{Interface => }/MainWindow.xaml.cs (100%) rename src/UniGetUI/{PackageEngine/Operations => PackageOperations}/OperationControl.xaml (100%) rename src/UniGetUI/{PackageEngine/Operations => PackageOperations}/OperationControl.xaml.cs (100%) rename src/UniGetUI/{PackageEngine/Operations => PackageOperations}/PackageOperations.cs (100%) rename src/UniGetUI/{PackageEngine/Operations => PackageOperations}/SourceOperations.cs (100%) rename src/UniGetUI/{Interface => }/Pages/AboutPages/AboutUniGetUI.xaml (100%) rename src/UniGetUI/{Interface => }/Pages/AboutPages/AboutUniGetUI.xaml.cs (100%) rename src/UniGetUI/{Interface => }/Pages/AboutPages/Contributors.xaml (100%) rename src/UniGetUI/{Interface => }/Pages/AboutPages/Contributors.xaml.cs (100%) rename src/UniGetUI/{Interface => }/Pages/AboutPages/SupportMe.xaml (100%) rename src/UniGetUI/{Interface => }/Pages/AboutPages/SupportMe.xaml.cs (100%) rename src/UniGetUI/{Interface => }/Pages/AboutPages/ThirdPartyLicenses.xaml (100%) rename src/UniGetUI/{Interface => }/Pages/AboutPages/ThirdPartyLicenses.xaml.cs (100%) rename src/UniGetUI/{Interface => }/Pages/AboutPages/Translators.xaml (100%) rename src/UniGetUI/{Interface => }/Pages/AboutPages/Translators.xaml.cs (100%) rename src/UniGetUI/{Interface => }/Pages/HelpPage.xaml (100%) rename src/UniGetUI/{Interface => }/Pages/HelpPage.xaml.cs (100%) rename src/UniGetUI/{Interface => }/Pages/IPageWithKeyboardShortcuts.cs (100%) rename src/UniGetUI/{Interface => }/Pages/LogPage/AppLogPage.cs (100%) rename src/UniGetUI/{Interface => }/Pages/LogPage/LogPage.xaml (100%) rename src/UniGetUI/{Interface => }/Pages/LogPage/LogPage.xaml.cs (100%) rename src/UniGetUI/{Interface => }/Pages/LogPage/ManagerLogsPage.cs (100%) rename src/UniGetUI/{Interface => }/Pages/LogPage/OperationHistoryPage.cs (100%) rename src/UniGetUI/{Interface => }/Pages/PackageDetailsPage.xaml (100%) rename src/UniGetUI/{Interface => }/Pages/PackageDetailsPage.xaml.cs (100%) rename src/UniGetUI/{Interface => }/Pages/SettingsPage.xaml (100%) rename src/UniGetUI/{Interface => }/Pages/SettingsPage.xaml.cs (100%) rename src/UniGetUI/{Interface => }/SoftwarePages/AbstractPackagesPage.xaml (100%) rename src/UniGetUI/{Interface => }/SoftwarePages/AbstractPackagesPage.xaml.cs (100%) rename src/UniGetUI/{Interface => }/SoftwarePages/DiscoverSoftwarePage.cs (100%) rename src/UniGetUI/{Interface => }/SoftwarePages/InstalledPackagesPage.cs (100%) rename src/UniGetUI/{Interface => }/SoftwarePages/PackageBundlesPage.cs (100%) rename src/UniGetUI/{Interface => }/SoftwarePages/SoftwareUpdatesPage.cs (100%) rename src/UniGetUI/{Interface => }/Widgets/Announcer.xaml (100%) rename src/UniGetUI/{Interface => }/Widgets/Announcer.xaml.cs (100%) rename src/UniGetUI/{Interface => }/Widgets/ButtonCard.cs (100%) rename src/UniGetUI/{Interface => }/Widgets/CheckboxCard.cs (100%) rename src/UniGetUI/{Interface => }/Widgets/ComboboxCard.cs (100%) rename src/UniGetUI/{Interface => }/Widgets/DialogCloseButton.xaml (100%) rename src/UniGetUI/{Interface => }/Widgets/DialogCloseButton.xaml.cs (100%) rename src/UniGetUI/{Interface => }/Widgets/LocalIcon.cs (100%) rename src/UniGetUI/{Interface => }/Widgets/MenuForPackage.cs (100%) rename src/UniGetUI/{Interface => }/Widgets/NavButton.xaml (100%) rename src/UniGetUI/{Interface => }/Widgets/NavButton.xaml.cs (100%) rename src/UniGetUI/{Interface => }/Widgets/PackageItemContainer.cs (100%) rename src/UniGetUI/{Interface => }/Widgets/SettingsEntry.cs (100%) rename src/UniGetUI/{Interface => }/Widgets/SourceManager.xaml (100%) rename src/UniGetUI/{Interface => }/Widgets/SourceManager.xaml.cs (100%) rename src/UniGetUI/{Interface => }/Widgets/TextboxCard.cs (100%) rename src/UniGetUI/{Interface => }/Widgets/TranslatedTextBlock.xaml (100%) rename src/UniGetUI/{Interface => }/Widgets/TranslatedTextBlock.xaml.cs (100%) diff --git a/src/UniGetUI/Interface/Dialogs/AboutUniGetUI.xaml b/src/UniGetUI/Dialogs/AboutUniGetUI.xaml similarity index 100% rename from src/UniGetUI/Interface/Dialogs/AboutUniGetUI.xaml rename to src/UniGetUI/Dialogs/AboutUniGetUI.xaml diff --git a/src/UniGetUI/Interface/Dialogs/AboutUniGetUI.xaml.cs b/src/UniGetUI/Dialogs/AboutUniGetUI.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/Dialogs/AboutUniGetUI.xaml.cs rename to src/UniGetUI/Dialogs/AboutUniGetUI.xaml.cs diff --git a/src/UniGetUI/Interface/Dialogs/IgnoredUpdates.xaml b/src/UniGetUI/Dialogs/IgnoredUpdates.xaml similarity index 100% rename from src/UniGetUI/Interface/Dialogs/IgnoredUpdates.xaml rename to src/UniGetUI/Dialogs/IgnoredUpdates.xaml diff --git a/src/UniGetUI/Interface/Dialogs/IgnoredUpdates.xaml.cs b/src/UniGetUI/Dialogs/IgnoredUpdates.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/Dialogs/IgnoredUpdates.xaml.cs rename to src/UniGetUI/Dialogs/IgnoredUpdates.xaml.cs diff --git a/src/UniGetUI/Interface/Dialogs/InstallOptions.xaml b/src/UniGetUI/Dialogs/InstallOptions.xaml similarity index 100% rename from src/UniGetUI/Interface/Dialogs/InstallOptions.xaml rename to src/UniGetUI/Dialogs/InstallOptions.xaml diff --git a/src/UniGetUI/Interface/Dialogs/InstallOptions.xaml.cs b/src/UniGetUI/Dialogs/InstallOptions.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/Dialogs/InstallOptions.xaml.cs rename to src/UniGetUI/Dialogs/InstallOptions.xaml.cs diff --git a/src/UniGetUI/Interface/Dialogs/ReleaseNotes.xaml b/src/UniGetUI/Dialogs/ReleaseNotes.xaml similarity index 100% rename from src/UniGetUI/Interface/Dialogs/ReleaseNotes.xaml rename to src/UniGetUI/Dialogs/ReleaseNotes.xaml diff --git a/src/UniGetUI/Interface/Dialogs/ReleaseNotes.xaml.cs b/src/UniGetUI/Dialogs/ReleaseNotes.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/Dialogs/ReleaseNotes.xaml.cs rename to src/UniGetUI/Dialogs/ReleaseNotes.xaml.cs diff --git a/src/UniGetUI/Interface/MainView.xaml b/src/UniGetUI/MainView.xaml similarity index 100% rename from src/UniGetUI/Interface/MainView.xaml rename to src/UniGetUI/MainView.xaml diff --git a/src/UniGetUI/Interface/MainView.xaml.cs b/src/UniGetUI/MainView.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/MainView.xaml.cs rename to src/UniGetUI/MainView.xaml.cs diff --git a/src/UniGetUI/Interface/MainWindow.xaml b/src/UniGetUI/MainWindow.xaml similarity index 100% rename from src/UniGetUI/Interface/MainWindow.xaml rename to src/UniGetUI/MainWindow.xaml diff --git a/src/UniGetUI/Interface/MainWindow.xaml.cs b/src/UniGetUI/MainWindow.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/MainWindow.xaml.cs rename to src/UniGetUI/MainWindow.xaml.cs diff --git a/src/UniGetUI/PackageEngine/Operations/OperationControl.xaml b/src/UniGetUI/PackageOperations/OperationControl.xaml similarity index 100% rename from src/UniGetUI/PackageEngine/Operations/OperationControl.xaml rename to src/UniGetUI/PackageOperations/OperationControl.xaml diff --git a/src/UniGetUI/PackageEngine/Operations/OperationControl.xaml.cs b/src/UniGetUI/PackageOperations/OperationControl.xaml.cs similarity index 100% rename from src/UniGetUI/PackageEngine/Operations/OperationControl.xaml.cs rename to src/UniGetUI/PackageOperations/OperationControl.xaml.cs diff --git a/src/UniGetUI/PackageEngine/Operations/PackageOperations.cs b/src/UniGetUI/PackageOperations/PackageOperations.cs similarity index 100% rename from src/UniGetUI/PackageEngine/Operations/PackageOperations.cs rename to src/UniGetUI/PackageOperations/PackageOperations.cs diff --git a/src/UniGetUI/PackageEngine/Operations/SourceOperations.cs b/src/UniGetUI/PackageOperations/SourceOperations.cs similarity index 100% rename from src/UniGetUI/PackageEngine/Operations/SourceOperations.cs rename to src/UniGetUI/PackageOperations/SourceOperations.cs diff --git a/src/UniGetUI/Interface/Pages/AboutPages/AboutUniGetUI.xaml b/src/UniGetUI/Pages/AboutPages/AboutUniGetUI.xaml similarity index 100% rename from src/UniGetUI/Interface/Pages/AboutPages/AboutUniGetUI.xaml rename to src/UniGetUI/Pages/AboutPages/AboutUniGetUI.xaml diff --git a/src/UniGetUI/Interface/Pages/AboutPages/AboutUniGetUI.xaml.cs b/src/UniGetUI/Pages/AboutPages/AboutUniGetUI.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/Pages/AboutPages/AboutUniGetUI.xaml.cs rename to src/UniGetUI/Pages/AboutPages/AboutUniGetUI.xaml.cs diff --git a/src/UniGetUI/Interface/Pages/AboutPages/Contributors.xaml b/src/UniGetUI/Pages/AboutPages/Contributors.xaml similarity index 100% rename from src/UniGetUI/Interface/Pages/AboutPages/Contributors.xaml rename to src/UniGetUI/Pages/AboutPages/Contributors.xaml diff --git a/src/UniGetUI/Interface/Pages/AboutPages/Contributors.xaml.cs b/src/UniGetUI/Pages/AboutPages/Contributors.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/Pages/AboutPages/Contributors.xaml.cs rename to src/UniGetUI/Pages/AboutPages/Contributors.xaml.cs diff --git a/src/UniGetUI/Interface/Pages/AboutPages/SupportMe.xaml b/src/UniGetUI/Pages/AboutPages/SupportMe.xaml similarity index 100% rename from src/UniGetUI/Interface/Pages/AboutPages/SupportMe.xaml rename to src/UniGetUI/Pages/AboutPages/SupportMe.xaml diff --git a/src/UniGetUI/Interface/Pages/AboutPages/SupportMe.xaml.cs b/src/UniGetUI/Pages/AboutPages/SupportMe.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/Pages/AboutPages/SupportMe.xaml.cs rename to src/UniGetUI/Pages/AboutPages/SupportMe.xaml.cs diff --git a/src/UniGetUI/Interface/Pages/AboutPages/ThirdPartyLicenses.xaml b/src/UniGetUI/Pages/AboutPages/ThirdPartyLicenses.xaml similarity index 100% rename from src/UniGetUI/Interface/Pages/AboutPages/ThirdPartyLicenses.xaml rename to src/UniGetUI/Pages/AboutPages/ThirdPartyLicenses.xaml diff --git a/src/UniGetUI/Interface/Pages/AboutPages/ThirdPartyLicenses.xaml.cs b/src/UniGetUI/Pages/AboutPages/ThirdPartyLicenses.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/Pages/AboutPages/ThirdPartyLicenses.xaml.cs rename to src/UniGetUI/Pages/AboutPages/ThirdPartyLicenses.xaml.cs diff --git a/src/UniGetUI/Interface/Pages/AboutPages/Translators.xaml b/src/UniGetUI/Pages/AboutPages/Translators.xaml similarity index 100% rename from src/UniGetUI/Interface/Pages/AboutPages/Translators.xaml rename to src/UniGetUI/Pages/AboutPages/Translators.xaml diff --git a/src/UniGetUI/Interface/Pages/AboutPages/Translators.xaml.cs b/src/UniGetUI/Pages/AboutPages/Translators.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/Pages/AboutPages/Translators.xaml.cs rename to src/UniGetUI/Pages/AboutPages/Translators.xaml.cs diff --git a/src/UniGetUI/Interface/Pages/HelpPage.xaml b/src/UniGetUI/Pages/HelpPage.xaml similarity index 100% rename from src/UniGetUI/Interface/Pages/HelpPage.xaml rename to src/UniGetUI/Pages/HelpPage.xaml diff --git a/src/UniGetUI/Interface/Pages/HelpPage.xaml.cs b/src/UniGetUI/Pages/HelpPage.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/Pages/HelpPage.xaml.cs rename to src/UniGetUI/Pages/HelpPage.xaml.cs diff --git a/src/UniGetUI/Interface/Pages/IPageWithKeyboardShortcuts.cs b/src/UniGetUI/Pages/IPageWithKeyboardShortcuts.cs similarity index 100% rename from src/UniGetUI/Interface/Pages/IPageWithKeyboardShortcuts.cs rename to src/UniGetUI/Pages/IPageWithKeyboardShortcuts.cs diff --git a/src/UniGetUI/Interface/Pages/LogPage/AppLogPage.cs b/src/UniGetUI/Pages/LogPage/AppLogPage.cs similarity index 100% rename from src/UniGetUI/Interface/Pages/LogPage/AppLogPage.cs rename to src/UniGetUI/Pages/LogPage/AppLogPage.cs diff --git a/src/UniGetUI/Interface/Pages/LogPage/LogPage.xaml b/src/UniGetUI/Pages/LogPage/LogPage.xaml similarity index 100% rename from src/UniGetUI/Interface/Pages/LogPage/LogPage.xaml rename to src/UniGetUI/Pages/LogPage/LogPage.xaml diff --git a/src/UniGetUI/Interface/Pages/LogPage/LogPage.xaml.cs b/src/UniGetUI/Pages/LogPage/LogPage.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/Pages/LogPage/LogPage.xaml.cs rename to src/UniGetUI/Pages/LogPage/LogPage.xaml.cs diff --git a/src/UniGetUI/Interface/Pages/LogPage/ManagerLogsPage.cs b/src/UniGetUI/Pages/LogPage/ManagerLogsPage.cs similarity index 100% rename from src/UniGetUI/Interface/Pages/LogPage/ManagerLogsPage.cs rename to src/UniGetUI/Pages/LogPage/ManagerLogsPage.cs diff --git a/src/UniGetUI/Interface/Pages/LogPage/OperationHistoryPage.cs b/src/UniGetUI/Pages/LogPage/OperationHistoryPage.cs similarity index 100% rename from src/UniGetUI/Interface/Pages/LogPage/OperationHistoryPage.cs rename to src/UniGetUI/Pages/LogPage/OperationHistoryPage.cs diff --git a/src/UniGetUI/Interface/Pages/PackageDetailsPage.xaml b/src/UniGetUI/Pages/PackageDetailsPage.xaml similarity index 100% rename from src/UniGetUI/Interface/Pages/PackageDetailsPage.xaml rename to src/UniGetUI/Pages/PackageDetailsPage.xaml diff --git a/src/UniGetUI/Interface/Pages/PackageDetailsPage.xaml.cs b/src/UniGetUI/Pages/PackageDetailsPage.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/Pages/PackageDetailsPage.xaml.cs rename to src/UniGetUI/Pages/PackageDetailsPage.xaml.cs diff --git a/src/UniGetUI/Interface/Pages/SettingsPage.xaml b/src/UniGetUI/Pages/SettingsPage.xaml similarity index 100% rename from src/UniGetUI/Interface/Pages/SettingsPage.xaml rename to src/UniGetUI/Pages/SettingsPage.xaml diff --git a/src/UniGetUI/Interface/Pages/SettingsPage.xaml.cs b/src/UniGetUI/Pages/SettingsPage.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/Pages/SettingsPage.xaml.cs rename to src/UniGetUI/Pages/SettingsPage.xaml.cs diff --git a/src/UniGetUI/Interface/SoftwarePages/AbstractPackagesPage.xaml b/src/UniGetUI/SoftwarePages/AbstractPackagesPage.xaml similarity index 100% rename from src/UniGetUI/Interface/SoftwarePages/AbstractPackagesPage.xaml rename to src/UniGetUI/SoftwarePages/AbstractPackagesPage.xaml diff --git a/src/UniGetUI/Interface/SoftwarePages/AbstractPackagesPage.xaml.cs b/src/UniGetUI/SoftwarePages/AbstractPackagesPage.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/SoftwarePages/AbstractPackagesPage.xaml.cs rename to src/UniGetUI/SoftwarePages/AbstractPackagesPage.xaml.cs diff --git a/src/UniGetUI/Interface/SoftwarePages/DiscoverSoftwarePage.cs b/src/UniGetUI/SoftwarePages/DiscoverSoftwarePage.cs similarity index 100% rename from src/UniGetUI/Interface/SoftwarePages/DiscoverSoftwarePage.cs rename to src/UniGetUI/SoftwarePages/DiscoverSoftwarePage.cs diff --git a/src/UniGetUI/Interface/SoftwarePages/InstalledPackagesPage.cs b/src/UniGetUI/SoftwarePages/InstalledPackagesPage.cs similarity index 100% rename from src/UniGetUI/Interface/SoftwarePages/InstalledPackagesPage.cs rename to src/UniGetUI/SoftwarePages/InstalledPackagesPage.cs diff --git a/src/UniGetUI/Interface/SoftwarePages/PackageBundlesPage.cs b/src/UniGetUI/SoftwarePages/PackageBundlesPage.cs similarity index 100% rename from src/UniGetUI/Interface/SoftwarePages/PackageBundlesPage.cs rename to src/UniGetUI/SoftwarePages/PackageBundlesPage.cs diff --git a/src/UniGetUI/Interface/SoftwarePages/SoftwareUpdatesPage.cs b/src/UniGetUI/SoftwarePages/SoftwareUpdatesPage.cs similarity index 100% rename from src/UniGetUI/Interface/SoftwarePages/SoftwareUpdatesPage.cs rename to src/UniGetUI/SoftwarePages/SoftwareUpdatesPage.cs diff --git a/src/UniGetUI/UniGetUI.csproj b/src/UniGetUI/UniGetUI.csproj index ec5d76616..2a2333fd8 100644 --- a/src/UniGetUI/UniGetUI.csproj +++ b/src/UniGetUI/UniGetUI.csproj @@ -40,6 +40,9 @@ + + Designer + @@ -97,9 +100,6 @@ $(DefaultXamlRuntime) - - $(DefaultXamlRuntime) - $(DefaultXamlRuntime) Designer @@ -176,21 +176,6 @@ Always - - MSBuild:Compile - - - MSBuild:Compile - - - MSBuild:Compile - - - MSBuild:Compile - - - MSBuild:Compile - @@ -222,16 +207,6 @@ MSBuild:Compile - - - MSBuild:Compile - - - - - MSBuild:Compile - - MSBuild:Compile @@ -242,9 +217,6 @@ MSBuild:Compile - - - diff --git a/src/UniGetUI/UniGetUI.csproj.user b/src/UniGetUI/UniGetUI.csproj.user index 7ea6f4053..2cf29ce2d 100644 --- a/src/UniGetUI/UniGetUI.csproj.user +++ b/src/UniGetUI/UniGetUI.csproj.user @@ -13,39 +13,6 @@ Designer - - Designer - - - Designer - - - Designer - - - Designer - - - Designer - - - Designer - - - Designer - - - Designer - - - Designer - - - Designer - - - Designer - Designer diff --git a/src/UniGetUI/Interface/Widgets/Announcer.xaml b/src/UniGetUI/Widgets/Announcer.xaml similarity index 100% rename from src/UniGetUI/Interface/Widgets/Announcer.xaml rename to src/UniGetUI/Widgets/Announcer.xaml diff --git a/src/UniGetUI/Interface/Widgets/Announcer.xaml.cs b/src/UniGetUI/Widgets/Announcer.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/Widgets/Announcer.xaml.cs rename to src/UniGetUI/Widgets/Announcer.xaml.cs diff --git a/src/UniGetUI/Interface/Widgets/ButtonCard.cs b/src/UniGetUI/Widgets/ButtonCard.cs similarity index 100% rename from src/UniGetUI/Interface/Widgets/ButtonCard.cs rename to src/UniGetUI/Widgets/ButtonCard.cs diff --git a/src/UniGetUI/Interface/Widgets/CheckboxCard.cs b/src/UniGetUI/Widgets/CheckboxCard.cs similarity index 100% rename from src/UniGetUI/Interface/Widgets/CheckboxCard.cs rename to src/UniGetUI/Widgets/CheckboxCard.cs diff --git a/src/UniGetUI/Interface/Widgets/ComboboxCard.cs b/src/UniGetUI/Widgets/ComboboxCard.cs similarity index 100% rename from src/UniGetUI/Interface/Widgets/ComboboxCard.cs rename to src/UniGetUI/Widgets/ComboboxCard.cs diff --git a/src/UniGetUI/Interface/Widgets/DialogCloseButton.xaml b/src/UniGetUI/Widgets/DialogCloseButton.xaml similarity index 100% rename from src/UniGetUI/Interface/Widgets/DialogCloseButton.xaml rename to src/UniGetUI/Widgets/DialogCloseButton.xaml diff --git a/src/UniGetUI/Interface/Widgets/DialogCloseButton.xaml.cs b/src/UniGetUI/Widgets/DialogCloseButton.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/Widgets/DialogCloseButton.xaml.cs rename to src/UniGetUI/Widgets/DialogCloseButton.xaml.cs diff --git a/src/UniGetUI/Interface/Widgets/LocalIcon.cs b/src/UniGetUI/Widgets/LocalIcon.cs similarity index 100% rename from src/UniGetUI/Interface/Widgets/LocalIcon.cs rename to src/UniGetUI/Widgets/LocalIcon.cs diff --git a/src/UniGetUI/Interface/Widgets/MenuForPackage.cs b/src/UniGetUI/Widgets/MenuForPackage.cs similarity index 100% rename from src/UniGetUI/Interface/Widgets/MenuForPackage.cs rename to src/UniGetUI/Widgets/MenuForPackage.cs diff --git a/src/UniGetUI/Interface/Widgets/NavButton.xaml b/src/UniGetUI/Widgets/NavButton.xaml similarity index 100% rename from src/UniGetUI/Interface/Widgets/NavButton.xaml rename to src/UniGetUI/Widgets/NavButton.xaml diff --git a/src/UniGetUI/Interface/Widgets/NavButton.xaml.cs b/src/UniGetUI/Widgets/NavButton.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/Widgets/NavButton.xaml.cs rename to src/UniGetUI/Widgets/NavButton.xaml.cs diff --git a/src/UniGetUI/Interface/Widgets/PackageItemContainer.cs b/src/UniGetUI/Widgets/PackageItemContainer.cs similarity index 100% rename from src/UniGetUI/Interface/Widgets/PackageItemContainer.cs rename to src/UniGetUI/Widgets/PackageItemContainer.cs diff --git a/src/UniGetUI/Interface/Widgets/SettingsEntry.cs b/src/UniGetUI/Widgets/SettingsEntry.cs similarity index 100% rename from src/UniGetUI/Interface/Widgets/SettingsEntry.cs rename to src/UniGetUI/Widgets/SettingsEntry.cs diff --git a/src/UniGetUI/Interface/Widgets/SourceManager.xaml b/src/UniGetUI/Widgets/SourceManager.xaml similarity index 100% rename from src/UniGetUI/Interface/Widgets/SourceManager.xaml rename to src/UniGetUI/Widgets/SourceManager.xaml diff --git a/src/UniGetUI/Interface/Widgets/SourceManager.xaml.cs b/src/UniGetUI/Widgets/SourceManager.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/Widgets/SourceManager.xaml.cs rename to src/UniGetUI/Widgets/SourceManager.xaml.cs diff --git a/src/UniGetUI/Interface/Widgets/TextboxCard.cs b/src/UniGetUI/Widgets/TextboxCard.cs similarity index 100% rename from src/UniGetUI/Interface/Widgets/TextboxCard.cs rename to src/UniGetUI/Widgets/TextboxCard.cs diff --git a/src/UniGetUI/Interface/Widgets/TranslatedTextBlock.xaml b/src/UniGetUI/Widgets/TranslatedTextBlock.xaml similarity index 100% rename from src/UniGetUI/Interface/Widgets/TranslatedTextBlock.xaml rename to src/UniGetUI/Widgets/TranslatedTextBlock.xaml diff --git a/src/UniGetUI/Interface/Widgets/TranslatedTextBlock.xaml.cs b/src/UniGetUI/Widgets/TranslatedTextBlock.xaml.cs similarity index 100% rename from src/UniGetUI/Interface/Widgets/TranslatedTextBlock.xaml.cs rename to src/UniGetUI/Widgets/TranslatedTextBlock.xaml.cs From 8a1cab5c792cd5aa84859220567dca5c455a153b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Fri, 30 Aug 2024 23:56:35 +0200 Subject: [PATCH 02/13] Add new ObservableQueue --- .../ObservableQueueTests.cs | 36 +++++++++++++++++++ src/UniGetUI.Core.Classes/ObservableQueue.cs | 25 +++++++++++++ src/UniGetUI/MainWindow.xaml.cs | 3 ++ 3 files changed, 64 insertions(+) create mode 100644 src/UniGetUI.Core.Classes.Tests/ObservableQueueTests.cs create mode 100644 src/UniGetUI.Core.Classes/ObservableQueue.cs diff --git a/src/UniGetUI.Core.Classes.Tests/ObservableQueueTests.cs b/src/UniGetUI.Core.Classes.Tests/ObservableQueueTests.cs new file mode 100644 index 000000000..f2620ea05 --- /dev/null +++ b/src/UniGetUI.Core.Classes.Tests/ObservableQueueTests.cs @@ -0,0 +1,36 @@ +namespace UniGetUI.Core.Classes.Tests; + +public class ObservableQueueTests +{ + [Fact] + public void TestObservableQueue() + { + var queue = new ObservableQueue(); + + List enqueuedElements = new(); + List dequeuedElements = new(); + + queue.ItemEnqueued += (s, e) => enqueuedElements.Add(e.Item); + queue.ItemDequeued += (s, e) => dequeuedElements.Add(e.Item); + + queue.Enqueue(1); + queue.Enqueue(2); + Assert.Equal(1, queue.Dequeue()); + queue.Enqueue(4); + queue.Enqueue(3); + + Assert.Equal(2, queue.Dequeue()); + Assert.Equal(4, queue.Dequeue()); + + Assert.Equal(4, enqueuedElements.Count); + Assert.Equal(1, enqueuedElements[0]); + Assert.Equal(2, enqueuedElements[1]); + Assert.Equal(4, enqueuedElements[2]); + Assert.Equal(3, enqueuedElements[3]); + + Assert.Equal(3, dequeuedElements.Count); + Assert.Equal(1, dequeuedElements[0]); + Assert.Equal(2, dequeuedElements[1]); + Assert.Equal(4, dequeuedElements[2]); + } +} diff --git a/src/UniGetUI.Core.Classes/ObservableQueue.cs b/src/UniGetUI.Core.Classes/ObservableQueue.cs new file mode 100644 index 000000000..af03b6ed6 --- /dev/null +++ b/src/UniGetUI.Core.Classes/ObservableQueue.cs @@ -0,0 +1,25 @@ +namespace UniGetUI.Core.Classes; + +public class ObservableQueue : Queue +{ + public class EventArgs(T item) + { + public readonly T Item = item; + } + + public event EventHandler ItemEnqueued; + public event EventHandler ItemDequeued; + + public new void Enqueue(T item) + { + base.Enqueue(item); + ItemEnqueued?.Invoke(this, new EventArgs(item)); + } + + public new T Dequeue() + { + T item = base.Dequeue(); + ItemDequeued?.Invoke(this, new EventArgs(item)); + return item; + } +} diff --git a/src/UniGetUI/MainWindow.xaml.cs b/src/UniGetUI/MainWindow.xaml.cs index 1e16cc9d8..bf17927ba 100644 --- a/src/UniGetUI/MainWindow.xaml.cs +++ b/src/UniGetUI/MainWindow.xaml.cs @@ -81,6 +81,9 @@ public struct MONITORINFO public List DialogQueue = []; public List NavButtonList = []; + + public static Queue ParametersToProcess; + #pragma warning disable CS8618 public MainWindow() { From 610d76e07391fb35055e5d43bdc8743126966441 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Sat, 31 Aug 2024 00:57:07 +0200 Subject: [PATCH 03/13] The app will now redirect exe arguments to the current instance --- UniGetUI.iss | 7 ++ src/UniGetUI.Core.Classes/ObservableQueue.cs | 4 +- src/UniGetUI/App.xaml.cs | 74 ++++++++++++-------- src/UniGetUI/EntryPoint.cs | 12 ++-- src/UniGetUI/MainWindow.xaml.cs | 32 ++++++--- 5 files changed, 83 insertions(+), 46 deletions(-) diff --git a/UniGetUI.iss b/UniGetUI.iss index a8d286a49..5f16affae 100644 --- a/UniGetUI.iss +++ b/UniGetUI.iss @@ -198,6 +198,13 @@ Name: "regularinstall\chocoinstall"; Description: "{cm:ChocoInstall}"; GroupDesc [Registry] Root: HKCU; Subkey: "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"; ValueType: string; ValueName: "WingetUI"; ValueData: """{app}\UniGetUI.exe"" --daemon"; Flags: uninsdeletevalue; Tasks: regularinstall +// Register the unigetui:// deep-link protocol +Root: HKA; Subkey: "Software\Classes\unigetui"; ValueType: "string"; ValueData: "URL:UniGetUI Protocol"; Flags: uninsdeletekey +Root: HKA; Subkey: "Software\Classes\unigetui"; ValueType: "string"; ValueName: "URL Protocol"; ValueData: "" +Root: HKA; Subkey: "Software\Classes\unigetui\DefaultIcon"; ValueType: "string"; ValueData: "{app}\{#MyAppExeName},0" +Root: HKA; Subkey: "Software\Classes\unigetui\shell\open\command"; ValueType: "string"; ValueData: """{app}\{#MyAppExeName}"" ""%1""" + + [Files] Source: "unigetui_bin\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion; BeforeInstall: TripleKill('WingetUI.exe', 'UniGetUI.exe', 'choco.exe'); Source: "unigetui_bin\*"; DestDir: "{app}"; Flags: createallsubdirs ignoreversion recursesubdirs; diff --git a/src/UniGetUI.Core.Classes/ObservableQueue.cs b/src/UniGetUI.Core.Classes/ObservableQueue.cs index af03b6ed6..ebc57e53b 100644 --- a/src/UniGetUI.Core.Classes/ObservableQueue.cs +++ b/src/UniGetUI.Core.Classes/ObservableQueue.cs @@ -7,8 +7,8 @@ public class EventArgs(T item) public readonly T Item = item; } - public event EventHandler ItemEnqueued; - public event EventHandler ItemDequeued; + public event EventHandler? ItemEnqueued; + public event EventHandler? ItemDequeued; public new void Enqueue(T item) { diff --git a/src/UniGetUI/App.xaml.cs b/src/UniGetUI/App.xaml.cs index 46a3c2c79..be04bf095 100644 --- a/src/UniGetUI/App.xaml.cs +++ b/src/UniGetUI/App.xaml.cs @@ -1,6 +1,8 @@ using System.Diagnostics; using System.Globalization; using System.Security.Cryptography; +using System.Text.RegularExpressions; +using Windows.ApplicationModel.Activation; using CommunityToolkit.WinUI.Helpers; using CommunityToolkit.WinUI.Notifications; using Microsoft.UI.Xaml; @@ -15,7 +17,11 @@ using UniGetUI.PackageEngine.Classes.Manager.Classes; using UniGetUI.PackageEngine.Operations; using Windows.Foundation.Collections; +using Microsoft.CSharp.RuntimeBinder; +using Microsoft.Windows.AppLifecycle; using Microsoft.Windows.AppNotifications; +using UniGetUI.PackageEngine.ManagerClasses.Manager; +using LaunchActivatedEventArgs = Microsoft.UI.Xaml.LaunchActivatedEventArgs; namespace UniGetUI { @@ -70,7 +76,6 @@ public MainApp() RegisterErrorHandling(); SetUpWebViewUserDataFolder(); InitializeMainWindow(); - ClearNotificationHistory_Safe(); RegisterNotificationService(); LoadComponentsAsync().ConfigureAwait(false); @@ -172,8 +177,8 @@ private void InitializeMainWindow() MainWindow.Closed += (sender, args) => DisposeAndQuit(0); nint hWnd = MainWindow.GetWindowHandle(); - Microsoft.UI.WindowId windowId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(hWnd); - Microsoft.UI.Windowing.AppWindow appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId); + var windowId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(hWnd); + var appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId); if (appWindow != null) { @@ -181,21 +186,6 @@ private void InitializeMainWindow() } } - /// - /// Clear the notification history, if possible - /// - private static void ClearNotificationHistory_Safe() - { - try - { - ToastNotificationManagerCompat.History.Clear(); - } - catch (Exception ex) - { - Logger.Warn(ex); - } - } - /// /// Register the notification activation event /// @@ -284,17 +274,14 @@ private async Task LoadComponentsAsync() // Load package managers await PEInterface.Initialize(); + Logger.Info("LoadComponentsAsync finished executing. All managers loaded. Proceeding to interface."); MainWindow.SwitchToInterface(); RaiseExceptionAsFatal = false; - if (Environment.GetCommandLineArgs().Contains("--load-and-quit")) - { - DisposeAndQuit(0); - } - await CheckForMissingDependencies(); - - Logger.Info("LoadComponentsAsync finished executing. All managers loaded. Proceeding to interface."); + MainWindow.ProcessCommandLineParameters(); + MainWindow.ParametersToProcess.ItemEnqueued += (s, e) => MainWindow.ProcessCommandLineParameters(); + await CheckForMissingDependencies(); } catch (Exception e) { @@ -306,7 +293,7 @@ private async Task CheckForMissingDependencies() { // Check for missing dependencies on package managers List missing_deps = []; - foreach (PackageEngine.ManagerClasses.Manager.PackageManager manager in PEInterface.Managers) + foreach (PackageManager manager in PEInterface.Managers) { if (!manager.IsReady()) { @@ -352,18 +339,47 @@ protected override async void OnLaunched(LaunchActivatedEventArgs args) { if (!CoreData.IsDaemon) { - await ShowMainWindowFromRedirectAsync(); + await ShowMainWindowFromLaunchAsync(); } CoreData.IsDaemon = false; } - public async Task ShowMainWindowFromRedirectAsync() + public async Task ShowMainWindowFromRedirectAsync(AppActivationArguments rawArgs) { while (MainWindow == null) - { await Task.Delay(100); + + ExtendedActivationKind kind = rawArgs.Kind; + if (kind is ExtendedActivationKind.Launch) + { + if (rawArgs.Data is ILaunchActivatedEventArgs launchArguments) + { + // If the app redirection event comes from a launch, extract + // the CLI arguments and redirect them to the ParameterProcessor + foreach (Match argument in Regex.Matches(launchArguments.Arguments, + "([^ \"']+|\"[^\"]+\"|'[^']+')")) + { + MainWindow.ParametersToProcess.Enqueue(argument.Value); + } + } + else + { + Logger.Error("REDIRECTOR ACTIVATOR: args.Data was null when casted to ILaunchActivatedEventArgs"); + } } + else + { + Logger.Error("REDIRECTOR ACTIVATOR: args.Kind is not Launch but rather " + kind); + } + + MainWindow.DispatcherQueue.TryEnqueue(MainWindow.Activate); + } + + public async Task ShowMainWindowFromLaunchAsync() + { + while (MainWindow == null) + await Task.Delay(100); MainWindow.DispatcherQueue.TryEnqueue(MainWindow.Activate); } diff --git a/src/UniGetUI/EntryPoint.cs b/src/UniGetUI/EntryPoint.cs index eef1aea46..48bf05fcd 100644 --- a/src/UniGetUI/EntryPoint.cs +++ b/src/UniGetUI/EntryPoint.cs @@ -72,7 +72,7 @@ Welcome to UniGetUI Version {CoreData.VersionName} DispatcherQueueSynchronizationContext context = new( DispatcherQueue.GetForCurrentThread()); SynchronizationContext.SetSynchronizationContext(context); - new MainApp(); + var app = new MainApp(); }); } } @@ -92,25 +92,23 @@ private static async Task DecideRedirection() // IDK how does this work, I copied it from the MS Docs // example on single-instance apps using unpackaged AppSdk + WinUI3 bool isRedirect = false; - AppActivationArguments args = AppInstance.GetCurrent().GetActivatedEventArgs(); - ExtendedActivationKind kind = args.Kind; - AppInstance keyInstance = AppInstance.FindOrRegisterForKey("MartiCliment.UniGetUI.MainInterface"); + var keyInstance = AppInstance.FindOrRegisterForKey("MartiCliment.UniGetUI.MainInterface"); if (keyInstance.IsCurrent) { keyInstance.Activated += async (s, e) => { - MainApp? AppInstance = MainApp.Current as MainApp; - if (AppInstance != null) + if (MainApp.Current is MainApp baseInstance) { - await AppInstance.ShowMainWindowFromRedirectAsync(); + await baseInstance.ShowMainWindowFromRedirectAsync(e); } }; } else { isRedirect = true; + AppActivationArguments args = AppInstance.GetCurrent().GetActivatedEventArgs(); await keyInstance.RedirectActivationToAsync(args); } return isRedirect; diff --git a/src/UniGetUI/MainWindow.xaml.cs b/src/UniGetUI/MainWindow.xaml.cs index bf17927ba..b193640b0 100644 --- a/src/UniGetUI/MainWindow.xaml.cs +++ b/src/UniGetUI/MainWindow.xaml.cs @@ -21,6 +21,7 @@ using Windows.ApplicationModel.DataTransfer; using Windows.Foundation.Collections; using Microsoft.Windows.AppNotifications; +using UniGetUI.Core.Classes; using UniGetUI.Interface.Enums; namespace UniGetUI.Interface @@ -63,9 +64,9 @@ public struct MONITORINFO } public delegate bool MonitorEnumDelegate(IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, IntPtr dwData); [DllImport("user32.dll")] - public static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, MonitorEnumDelegate lpfnEnum, IntPtr dwData); + private static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, MonitorEnumDelegate lpfnEnum, IntPtr dwData); [DllImport("user32.dll")] - public static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi); + private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi); /* END INTEROP STUFF */ private TaskbarIcon? TrayIcon; @@ -78,25 +79,25 @@ public struct MONITORINFO private int LoadingDialogCount; - public List DialogQueue = []; + private List DialogQueue = []; public List NavButtonList = []; - public static Queue ParametersToProcess; + public static readonly ObservableQueue ParametersToProcess = new(); #pragma warning disable CS8618 public MainWindow() { InitializeComponent(); - LoadTrayMenu(); ExtendsContentIntoTitleBar = true; SetTitleBar(__content_root); ContentRoot = __content_root; - ApplyTheme(); - SizeChanged += (s, e) => { SaveGeometry(); }; - AppWindow.SetIcon(Path.Join(CoreData.UniGetUIExecutableDirectory, "Assets", "Images", "icon.ico")); + + LoadTrayMenu(); + ApplyTheme(); + if (CoreTools.IsAdministrator()) { Title = "UniGetUI " + CoreTools.Translate("[RAN AS ADMINISTRATOR]"); @@ -109,8 +110,14 @@ public MainWindow() Title = CoreTools.Translate("Please wait"), Content = new ProgressBar { IsIndeterminate = true, Width = 300 } }; + + foreach (var arg in Environment.GetCommandLineArgs()) + { + ParametersToProcess.Enqueue(arg); + } } #pragma warning restore CS8618 + public void HandleNotificationActivation(AppNotificationActivatedEventArgs args) { args.Arguments.TryGetValue("action", out string? action); @@ -182,6 +189,15 @@ public async void HandleClosingEvent(AppWindow sender, AppWindowClosingEventArgs } } + public async void ProcessCommandLineParameters() + { + while (ParametersToProcess.Count > 0) + { + string param = ParametersToProcess.Dequeue(); + Logger.Warn(param); + } + } + public new void Activate() { if (!HasLoadedLastGeometry) From 2920869c1418c92e631c8138de2a3cbe40195b66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Sat, 31 Aug 2024 12:13:14 +0200 Subject: [PATCH 04/13] User can open package bundled by opening them with UniGetUI. When a bundle is invalid, the user will be warned --- .../SerializableBundle_v1.cs | 2 +- src/UniGetUI/App.xaml.cs | 7 ++- src/UniGetUI/MainWindow.xaml.cs | 42 +++++++++++--- .../SoftwarePages/PackageBundlesPage.cs | 57 +++++++++++++------ .../SoftwarePages/SoftwareUpdatesPage.cs | 2 +- 5 files changed, 81 insertions(+), 29 deletions(-) diff --git a/src/UniGetUI.PackageEngine.Serializable/SerializableBundle_v1.cs b/src/UniGetUI.PackageEngine.Serializable/SerializableBundle_v1.cs index ec5210ab2..a928fabce 100644 --- a/src/UniGetUI.PackageEngine.Serializable/SerializableBundle_v1.cs +++ b/src/UniGetUI.PackageEngine.Serializable/SerializableBundle_v1.cs @@ -2,7 +2,7 @@ { public class SerializableBundle_v1 { - public double export_version { get; set; } = 2.0; + public double export_version { get; set; } = -1; public List packages { get; set; } = new(); public string incompatible_packages_info { get; set; } = "Incompatible packages cannot be installed from WingetUI, but they have been listed here for logging purposes."; public List incompatible_packages { get; set; } = new(); diff --git a/src/UniGetUI/App.xaml.cs b/src/UniGetUI/App.xaml.cs index be04bf095..223cbf1f5 100644 --- a/src/UniGetUI/App.xaml.cs +++ b/src/UniGetUI/App.xaml.cs @@ -279,7 +279,10 @@ private async Task LoadComponentsAsync() RaiseExceptionAsFatal = false; MainWindow.ProcessCommandLineParameters(); - MainWindow.ParametersToProcess.ItemEnqueued += (s, e) => MainWindow.ProcessCommandLineParameters(); + MainWindow.ParametersToProcess.ItemEnqueued += (s, e) => + { + MainWindow.DispatcherQueue.TryEnqueue(MainWindow.ProcessCommandLineParameters); + }; await CheckForMissingDependencies(); } @@ -370,7 +373,7 @@ public async Task ShowMainWindowFromRedirectAsync(AppActivationArguments rawArgs } else { - Logger.Error("REDIRECTOR ACTIVATOR: args.Kind is not Launch but rather " + kind); + Logger.Warn("REDIRECTOR ACTIVATOR: args.Kind is not Launch but rather " + kind); } MainWindow.DispatcherQueue.TryEnqueue(MainWindow.Activate); diff --git a/src/UniGetUI/MainWindow.xaml.cs b/src/UniGetUI/MainWindow.xaml.cs index b193640b0..f339e1d06 100644 --- a/src/UniGetUI/MainWindow.xaml.cs +++ b/src/UniGetUI/MainWindow.xaml.cs @@ -23,6 +23,7 @@ using Microsoft.Windows.AppNotifications; using UniGetUI.Core.Classes; using UniGetUI.Interface.Enums; +using UniGetUI.Interface.SoftwarePages; namespace UniGetUI.Interface { @@ -189,12 +190,40 @@ public async void HandleClosingEvent(AppWindow sender, AppWindowClosingEventArgs } } - public async void ProcessCommandLineParameters() + public void ProcessCommandLineParameters() { while (ParametersToProcess.Count > 0) { - string param = ParametersToProcess.Dequeue(); - Logger.Warn(param); + string param = ParametersToProcess.Dequeue().Trim('\'').Trim('"'); + if (param.Length > 2 && param[0] == '-' && param[1] == '-') + { + Logger.ImportantInfo("Ignoring CLI-parameter " + param); + // Handle other --param command-line parameters + } + else if (param.Length > 11 && param.ToLower().StartsWith("unigetui://")) + { + string baseUrl = param[11..]; + Logger.ImportantInfo("Begin handle of deep link with body " + baseUrl); + // Handle URLs + } + else if (Path.IsPathFullyQualified(param) && File.Exists(param)) + { + if (param.EndsWith(".json") || param.EndsWith(".xml") || param.EndsWith(".yaml")) + { + // Handle potential JSON files + Logger.ImportantInfo("Begin attempt to open the package bundle " + param); + NavigationPage.BundlesNavButton.ForceClick(); + _ = NavigationPage.BundlesPage.OpenFromFile(param); + } + else + { + Logger.Warn("Attempted to open the unrecognized file " + param); + } + } + else + { + Logger.Warn("Did not know how to handle the parameter " + param); + } } } @@ -445,7 +474,7 @@ public void ShowLoadingDialog(string text) { LoadingSthDalog.Title = text; LoadingSthDalog.XamlRoot = NavigationPage.XamlRoot; - _ = LoadingSthDalog.ShowAsync(); + _ = ShowDialogAsync(LoadingSthDalog, HighPriority: true); } LoadingDialogCount++; } @@ -473,12 +502,11 @@ public void SharePackage(IPackage? package) IntPtr hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this); IDataTransferManagerInterop interop = - Windows.ApplicationModel.DataTransfer.DataTransferManager.As - (); + DataTransferManager.As(); IntPtr result = interop.GetForWindow(hWnd, _dtm_iid); DataTransferManager dataTransferManager = WinRT.MarshalInterface - .FromAbi(result); + .FromAbi(result); dataTransferManager.DataRequested += (sender, args) => { diff --git a/src/UniGetUI/SoftwarePages/PackageBundlesPage.cs b/src/UniGetUI/SoftwarePages/PackageBundlesPage.cs index 7c504e675..4296ad64b 100644 --- a/src/UniGetUI/SoftwarePages/PackageBundlesPage.cs +++ b/src/UniGetUI/SoftwarePages/PackageBundlesPage.cs @@ -229,7 +229,7 @@ public override void GenerateToolBar() OpenBundle.Click += async (s, e) => { Loader.ClearPackages(); - await OpenFile(); + await OpenFromFile(); }; ExportBundle.Click += async (s, e) => @@ -367,15 +367,18 @@ private void MenuRemoveFromList_Invoked(object sender, RoutedEventArgs args) } - public async Task OpenFile() + public async Task OpenFromFile(string? file = null) { try { - // Select file - FileOpenPicker picker = new(MainApp.Instance.MainWindow.GetWindowHandle()); - string file = picker.Show(new List { "*.json", "*.yaml", "*.xml" }); - if (file == String.Empty) - return; + if (file == null) + { + // Select file + FileOpenPicker picker = new(MainApp.Instance.MainWindow.GetWindowHandle()); + file = picker.Show(new List { "*.json", "*.yaml", "*.xml" }); + if (file == String.Empty) + return; + } MainApp.Instance.MainWindow.ShowLoadingDialog(CoreTools.Translate("Loading packages, please wait...")); @@ -398,9 +401,20 @@ public async Task OpenFile() } catch (Exception ex) { - Logger.Error("Could not load packages from a file"); + + Logger.Error("An error occurred while attempting to open a bundle"); Logger.Error(ex); + var warningDialog = new ContentDialog + { + Title = CoreTools.Translate("The package bundle is not valid"), + Content = CoreTools.Translate("The bundle you are trying to load appears to be invalid. Please check the file and try again.") + "\n\n" + ex.Message, + CloseButtonText = CoreTools.Translate("Ok"), + DefaultButton = ContentDialogButton.Close, + XamlRoot = MainApp.Instance.MainWindow.Content.XamlRoot // Ensure the dialog is shown in the correct context + }; + MainApp.Instance.MainWindow.HideLoadingDialog(); + await MainApp.Instance.MainWindow.ShowDialogAsync(warningDialog); } } @@ -450,6 +464,7 @@ public async Task SaveFile() public static async Task CreateBundle(IEnumerable packages, BundleFormatType formatType = BundleFormatType.JSON) { SerializableBundle_v1 exportable = new(); + exportable.export_version = 2.0; foreach (IPackage package in packages) if (package is Package && !package.Source.IsVirtualManager) exportable.packages.Add(await package.AsSerializable()); @@ -485,17 +500,21 @@ public static async Task CreateBundle(IEnumerable packages, Bu public async Task AddFromBundle(string content, BundleFormatType format) { + // Deserialize data SerializableBundle_v1? DeserializedData; - if (format == BundleFormatType.JSON) + if (format is BundleFormatType.JSON) { - DeserializedData = JsonSerializer.Deserialize(content); + DeserializedData = await Task.Run(() => JsonSerializer.Deserialize(content)); + Logger.Error(DeserializedData.packages.Count.ToString()); + Logger.Error(DeserializedData.export_version.ToString()); } - else if (format == BundleFormatType.YAML) + else if (format is BundleFormatType.YAML) { - YamlDotNet.Serialization.IDeserializer deserializer = new YamlDotNet.Serialization.DeserializerBuilder() - .Build(); - DeserializedData = deserializer.Deserialize(content); + YamlDotNet.Serialization.IDeserializer deserializer = + new YamlDotNet.Serialization.DeserializerBuilder() + .Build(); + DeserializedData = await Task.Run(() => deserializer.Deserialize(content)); } else { @@ -503,14 +522,14 @@ public async Task AddFromBundle(string content, BundleFormatType format) await File.WriteAllTextAsync(tempfile, content); StreamReader reader = new(tempfile); XmlSerializer serializer = new(typeof(SerializableBundle_v1)); - DeserializedData = serializer.Deserialize(reader) as SerializableBundle_v1; + DeserializedData = await Task.Run(() => serializer.Deserialize(reader) as SerializableBundle_v1); reader.Close(); File.Delete(tempfile); } - if (DeserializedData is null) + if (DeserializedData is null || DeserializedData.export_version is -1) { - throw new InvalidDataException($"Deserialized data was null for content {content} and format {format}"); + throw new ArgumentException("DeserializedData was null"); } List packages = new List(); @@ -520,12 +539,14 @@ public async Task AddFromBundle(string content, BundleFormatType format) packages.Add(PackageFromSerializable(DeserializedPackage)); } - foreach (SerializableIncompatiblePackage_v1 DeserializedPackage in DeserializedData.incompatible_packages) + foreach (SerializableIncompatiblePackage_v1 DeserializedPackage in DeserializedData + .incompatible_packages) { packages.Add(InvalidPackageFromSerializable(DeserializedPackage, NullSource.Instance)); } await PEInterface.PackageBundlesLoader.AddPackagesAsync(packages); + } public static IPackage PackageFromSerializable(SerializablePackage_v1 raw_package) diff --git a/src/UniGetUI/SoftwarePages/SoftwareUpdatesPage.cs b/src/UniGetUI/SoftwarePages/SoftwareUpdatesPage.cs index b9acb3f2d..86f4160e6 100644 --- a/src/UniGetUI/SoftwarePages/SoftwareUpdatesPage.cs +++ b/src/UniGetUI/SoftwarePages/SoftwareUpdatesPage.cs @@ -426,7 +426,7 @@ protected override void WhenPackagesLoaded(ReloadReason reason) .SetTag(CoreData.UpdatesAvailableNotificationTag.ToString()) .AddText(CoreTools.Translate("Updates found!")) - .AddText(CoreTools.Translate("{0} can be updated", upgradablePackages.Count)) + .AddText(CoreTools.Translate("{0} packages can be updated", upgradablePackages.Count)) .SetAttributionText(attribution) .AddButton(new AppNotificationButton(CoreTools.Translate("Open WingetUI")) From d470fe55f6266d01c14759aa6719f73f3cbca93c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Sat, 31 Aug 2024 12:24:23 +0200 Subject: [PATCH 05/13] Fix packages not properly exporting their installation options --- .../Packages/ImportedPackage.cs | 15 +++++++++++++++ .../Packages/Package.cs | 2 +- src/UniGetUI/SoftwarePages/PackageBundlesPage.cs | 7 ++++--- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/ImportedPackage.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/ImportedPackage.cs index 1bf962305..962c7046c 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/ImportedPackage.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/ImportedPackage.cs @@ -32,5 +32,20 @@ public async Task RegisterAndGetPackageAsync() return new Package(Name, Id, Version, Source, Manager); } + + public override async Task AsSerializable() + { + return new SerializablePackage_v1 + { + Id = Id, + Name = Name, + Version = Version, + Source = Source.Name, + ManagerName = Manager.Name, + InstallationOptions = installation_options, + Updates = updates_options + }; + } + } } diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Package.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Package.cs index 7d08d3dbf..b82b09b86 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Package.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Package.cs @@ -357,7 +357,7 @@ public virtual bool NewerVersionIsInstalled() return PackageCacher.NewerVersionIsInstalled(this); } - public async Task AsSerializable() + public virtual async Task AsSerializable() { return new SerializablePackage_v1 { diff --git a/src/UniGetUI/SoftwarePages/PackageBundlesPage.cs b/src/UniGetUI/SoftwarePages/PackageBundlesPage.cs index 4296ad64b..07df12639 100644 --- a/src/UniGetUI/SoftwarePages/PackageBundlesPage.cs +++ b/src/UniGetUI/SoftwarePages/PackageBundlesPage.cs @@ -228,7 +228,6 @@ public override void GenerateToolBar() OpenBundle.Click += async (s, e) => { - Loader.ClearPackages(); await OpenFromFile(); }; @@ -393,6 +392,7 @@ public async Task OpenFromFile(string? file = null) string fileContent = await File.ReadAllTextAsync(file); + Loader.ClearPackages(); // Import packages to list await AddFromBundle(fileContent, formatType); @@ -471,11 +471,11 @@ public static async Task CreateBundle(IEnumerable packages, Bu else exportable.incompatible_packages.Add(package.AsSerializable_Incompatible()); - Logger.Debug("Finished loading serializable objects. Serializing with format " + formatType.ToString()); + Logger.Debug("Finished loading serializable objects. Serializing with format " + formatType); string ExportableData; if (formatType == BundleFormatType.JSON) - ExportableData = JsonSerializer.Serialize(exportable, new JsonSerializerOptions { WriteIndented = true }); + ExportableData = JsonSerializer.Serialize(exportable, new JsonSerializerOptions { WriteIndented = true }); else if (formatType == BundleFormatType.YAML) { YamlDotNet.Serialization.ISerializer serializer = new YamlDotNet.Serialization.SerializerBuilder() @@ -545,6 +545,7 @@ public async Task AddFromBundle(string content, BundleFormatType format) packages.Add(InvalidPackageFromSerializable(DeserializedPackage, NullSource.Instance)); } + await PEInterface.PackageBundlesLoader.AddPackagesAsync(packages); } From dac8edd39f447cfdadb7143e52e6adf7985d0f10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Sat, 31 Aug 2024 13:12:20 +0200 Subject: [PATCH 06/13] Improvements to how shared packages are searched --- .../SoftwarePages/DiscoverSoftwarePage.cs | 111 ++++++++++-------- 1 file changed, 61 insertions(+), 50 deletions(-) diff --git a/src/UniGetUI/SoftwarePages/DiscoverSoftwarePage.cs b/src/UniGetUI/SoftwarePages/DiscoverSoftwarePage.cs index 14baab446..d855f7377 100644 --- a/src/UniGetUI/SoftwarePages/DiscoverSoftwarePage.cs +++ b/src/UniGetUI/SoftwarePages/DiscoverSoftwarePage.cs @@ -360,76 +360,87 @@ private void MenuInstallSettings_Invoked(object sender, RoutedEventArgs e) ShowInstallationOptionsForPackage(SelectedItem); } - public void ShowSharedPackage_ThreadSafe(string pId, string pSource) + public void ShowSharedPackage_ThreadSafe(string id, string combinedSourceName) { - MainApp.Instance.MainWindow.DispatcherQueue.TryEnqueue(() => { ShowSharedPackage(pId, pSource); }); + var contents = combinedSourceName.Split(':'); + string managerName = contents[0]; + string sourceName = ""; + if (contents.Length > 1) sourceName = contents[1]; + MainApp.Instance.MainWindow.DispatcherQueue.TryEnqueue(() => { ShowSharedPackage(id, managerName, sourceName); }); } - private async void ShowSharedPackage(string pId, string pSource) + public void ShowSharedPackage_ThreadSafe(string id, string managerName, string sourceName) { - Logger.Info($"Showing shared package with pId=${pId} and pSource=${pSource}..."); + MainApp.Instance.MainWindow.DispatcherQueue.TryEnqueue(() => { ShowSharedPackage(id, managerName, sourceName); }); + } - MainApp.Instance.MainWindow.Activate(); + private async void ShowSharedPackage(string id, string managerName, string sourceName) + { + try + { + Logger.Info($"Showing shared package with pId={id} and pSource={managerName}: ´{sourceName} ..."); + MainApp.Instance.MainWindow.Activate(); + MainApp.Instance.MainWindow.ShowLoadingDialog(CoreTools.Translate("Please wait...", id)); - MainApp.Instance.MainWindow.ShowLoadingDialog(CoreTools.Translate("Please wait...", pId)); - MainApp.Instance.MainWindow.NavigationPage.DiscoverNavButton.ForceClick(); - MegaQueryBlock.Visibility = Visibility.Collapsed; - MegaFindButton.Visibility = Visibility.Collapsed; + IPackageManager? manager = null; - QueryIdRadio.IsChecked = true; - QueryBlock.Text = pId; - await PEInterface.DiscoveredPackagesLoader.ReloadPackages(pId); - QueryBothRadio.IsChecked = true; - MainApp.Instance.MainWindow.HideLoadingDialog(); - if (FilteredPackages.Count == 1) - { - Logger.Debug("Only one package was found for pId=" + pId + ", showing it."); - ShowDetailsForPackage(FilteredPackages[0].Package); - } - else if (FilteredPackages.Count > 1) - { - // Find a package that matches both the Id and the Source - string managerName = pSource.Contains(':') ? pSource.Split(':')[0] : pSource; - foreach (IPackage match in FilteredPackages.GetPackages()) + foreach (var candidate in PEInterface.Managers) { - if (match.Source.Manager.Name == managerName && match.Id == pId) + if (candidate.Name == managerName || candidate.DisplayName == managerName) { - Logger.Debug("Equivalent package for pId=" + pId + " and pSource=" + pSource + " found: " + match.ToString()); - ShowDetailsForPackage(match); - return; + if (candidate.IsEnabled()) + { + manager = candidate; + break; + } + throw new ArgumentException(CoreTools.Translate("The Package Manager {0} is disabled", + candidate.DisplayName)); } } - - Logger.Info($"No package was found with Id={pId} and Source={pSource}, checking for Id only."); - // Find a package that matches the Id only - foreach (IPackage match in FilteredPackages.GetPackages()) + + if (manager is null) { - if (match.Id == pId) - { - Logger.Debug("Equivalent package for pId=" + pId + " and pSource=" + pSource + " found: " + match.ToString()); - ShowDetailsForPackage(match); - return; - } + throw new ArgumentException(CoreTools.Translate("The package manager {0} was not found", managerName)); } - Logger.Debug("No package found with the exact same manager, showing the first one."); - ShowDetailsForPackage(FilteredPackages[0].Package); + var results = await manager.FindPackages(id); + var candidates = results.Where(p => p.Id == id).ToArray(); + + if (candidates.Length == 0) + { + throw new ArgumentException(CoreTools.Translate("The package {0} was not found on {1}", id, manager.DisplayName)); + } + + IPackage package = candidates[0]; + + // Get package from best source + if (candidates.Length >= 1 && manager.Capabilities.SupportsCustomSources) + foreach (var candidate in candidates) + if (candidate.Source.Name == sourceName) + package = candidate; + + Logger.ImportantInfo($"Found package {package.Id} on manager {package.Manager.Name}, showing it..."); + MainApp.Instance.MainWindow.HideLoadingDialog(); + ShowDetailsForPackage(package); + } - else + catch (Exception ex) { - Logger.Error("No packages were found matching the given pId=" + pId); - ContentDialog c = new() + Logger.Error($"An error occurred while attempting to show the package with id {id}"); + Logger.Error(ex); + var warningDialog = new ContentDialog { - XamlRoot = XamlRoot, - Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style, Title = CoreTools.Translate("Package not found"), - Content = CoreTools.Translate("The package {0} from {1} was not found.", pId, pSource), - PrimaryButtonText = CoreTools.Translate("OK"), - DefaultButton = ContentDialogButton.Primary + Content = CoreTools.Translate("An error occurred when attempting to show the package with Id {0}", id) + ":\n" + ex.Message, + CloseButtonText = CoreTools.Translate("Ok"), + DefaultButton = ContentDialogButton.Close, + XamlRoot = MainApp.Instance.MainWindow.Content.XamlRoot // Ensure the dialog is shown in the correct context }; - await MainApp.Instance.MainWindow.ShowDialogAsync(c); + + MainApp.Instance.MainWindow.HideLoadingDialog(); + await MainApp.Instance.MainWindow.ShowDialogAsync(warningDialog); + } } - } } From 449cf0f608096aabe4fb44164c78a9596eb001f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Sat, 31 Aug 2024 13:27:29 +0200 Subject: [PATCH 07/13] Handle the unigetui:// protocol to both launch UniGetUI and show shared packages --- src/UniGetUI/MainWindow.xaml.cs | 44 ++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/UniGetUI/MainWindow.xaml.cs b/src/UniGetUI/MainWindow.xaml.cs index f339e1d06..19f77d9cc 100644 --- a/src/UniGetUI/MainWindow.xaml.cs +++ b/src/UniGetUI/MainWindow.xaml.cs @@ -1,5 +1,6 @@ using System.Diagnostics; using System.Runtime.InteropServices; +using System.Text.RegularExpressions; using CommunityToolkit.WinUI.Notifications; using H.NotifyIcon; using Microsoft.UI; @@ -20,10 +21,13 @@ using UniGetUI.PackageEngine.Interfaces; using Windows.ApplicationModel.DataTransfer; using Windows.Foundation.Collections; +using Windows.UI.WebUI; using Microsoft.Windows.AppNotifications; using UniGetUI.Core.Classes; using UniGetUI.Interface.Enums; using UniGetUI.Interface.SoftwarePages; +using UniGetUI.PackageEngine.PackageClasses; +using YamlDotNet.Core.Tokens; namespace UniGetUI.Interface { @@ -204,7 +208,41 @@ public void ProcessCommandLineParameters() { string baseUrl = param[11..]; Logger.ImportantInfo("Begin handle of deep link with body " + baseUrl); - // Handle URLs + + if (baseUrl.StartsWith("showPackage?")) + { + string Id = Regex.Match(baseUrl, "id=([^&]+)").Value.Split("=")[^1]; + string CombinedManagerName = Regex.Match(baseUrl, "combinedManagerName=([^&]+)").Value.Split("=")[^1]; + string ManagerName = Regex.Match(baseUrl, "managerName=([^&]+)").Value.Split("=")[^1]; + string SourceName = Regex.Match(baseUrl, "sourceName=([^&]+)").Value.Split("=")[^1]; + + + if (Id != "" && CombinedManagerName != "" && ManagerName == "" && SourceName == "") + { + Logger.Warn($"URI {param} follows old scheme"); + NavigationPage.DiscoverPage.ShowSharedPackage_ThreadSafe(Id, CombinedManagerName); + } + else if (Id != "" && ManagerName != "" && SourceName != "") + { + NavigationPage.DiscoverPage.ShowSharedPackage_ThreadSafe(Id, ManagerName, SourceName); + } + else + { + Logger.Error(new UriFormatException($"Malformed URL {param}")); + } + } + else if (baseUrl.StartsWith("showUniGetUI")) + { + // Do nothing, window already shown + } + else if (baseUrl.StartsWith("showUpdatesPage")) + { + NavigationPage.UpdatesNavButton.ForceClick(); + } + else + { + Logger.Error(new UriFormatException($"Malformed URL {param}")); + } } else if (Path.IsPathFullyQualified(param) && File.Exists(param)) { @@ -220,6 +258,10 @@ public void ProcessCommandLineParameters() Logger.Warn("Attempted to open the unrecognized file " + param); } } + else if (param.EndsWith("UniGetUI.exe") || param.EndsWith("UniGetUI.dll")) + { + // Skip + } else { Logger.Warn("Did not know how to handle the parameter " + param); From 89c596e6ff2ee1f362a26e9995aa62bc0e45a758 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Sat, 31 Aug 2024 22:29:32 +0200 Subject: [PATCH 08/13] Add --help handler, add new unigetui:// deep links --- src/UniGetUI/MainWindow.xaml.cs | 111 ++++++++++++++++++++------------ 1 file changed, 70 insertions(+), 41 deletions(-) diff --git a/src/UniGetUI/MainWindow.xaml.cs b/src/UniGetUI/MainWindow.xaml.cs index 19f77d9cc..e2f8be510 100644 --- a/src/UniGetUI/MainWindow.xaml.cs +++ b/src/UniGetUI/MainWindow.xaml.cs @@ -1,7 +1,11 @@ +using System; +using System.Collections.Generic; using System.Diagnostics; +using System.IO; +using System.Linq; using System.Runtime.InteropServices; using System.Text.RegularExpressions; -using CommunityToolkit.WinUI.Notifications; +using System.Threading.Tasks; using H.NotifyIcon; using Microsoft.UI; using Microsoft.UI.Windowing; @@ -20,14 +24,9 @@ using UniGetUI.PackageEngine.Classes.Manager.Classes; using UniGetUI.PackageEngine.Interfaces; using Windows.ApplicationModel.DataTransfer; -using Windows.Foundation.Collections; -using Windows.UI.WebUI; using Microsoft.Windows.AppNotifications; using UniGetUI.Core.Classes; using UniGetUI.Interface.Enums; -using UniGetUI.Interface.SoftwarePages; -using UniGetUI.PackageEngine.PackageClasses; -using YamlDotNet.Core.Tokens; namespace UniGetUI.Interface { @@ -194,6 +193,62 @@ public async void HandleClosingEvent(AppWindow sender, AppWindowClosingEventArgs } } + /// + /// For a given deep link, perform the appropiate action + /// + /// the unigetui:// deep link to handle + private void HandleDeepLink(string link) + { + string baseUrl = link[11..]; + Logger.ImportantInfo("Begin handle of deep link with body " + baseUrl); + + if (baseUrl.StartsWith("showPackage?")) + { + string Id = Regex.Match(baseUrl, "id=([^&]+)").Value.Split("=")[^1]; + string CombinedManagerName = Regex.Match(baseUrl, "combinedManagerName=([^&]+)").Value.Split("=")[^1]; + string ManagerName = Regex.Match(baseUrl, "managerName=([^&]+)").Value.Split("=")[^1]; + string SourceName = Regex.Match(baseUrl, "sourceName=([^&]+)").Value.Split("=")[^1]; + + + if (Id != "" && CombinedManagerName != "" && ManagerName == "" && SourceName == "") + { + Logger.Warn($"URI {link} follows old scheme"); + NavigationPage.DiscoverPage.ShowSharedPackage_ThreadSafe(Id, CombinedManagerName); + } + else if (Id != "" && ManagerName != "" && SourceName != "") + { + NavigationPage.DiscoverPage.ShowSharedPackage_ThreadSafe(Id, ManagerName, SourceName); + } + else + { + Logger.Error(new UriFormatException($"Malformed URL {link}")); + } + } + else if (baseUrl.StartsWith("showUniGetUI")) + { + // Do nothing, window already shown + } + else if (baseUrl.StartsWith("showDiscoverPage")) + { + NavigationPage.DiscoverNavButton.ForceClick(); + } + else if (baseUrl.StartsWith("showUpdatesPage")) + { + NavigationPage.UpdatesNavButton.ForceClick(); + } + else if (baseUrl.StartsWith("showInstalledPage")) + { + NavigationPage.InstalledNavButton.ForceClick(); + } + else + { + Logger.Error(new UriFormatException($"Malformed URL {link}")); + } + } + + /// + /// Will process any remaining CLI parameter stored on MainWindow.ParametersToProcess + /// public void ProcessCommandLineParameters() { while (ParametersToProcess.Count > 0) @@ -201,49 +256,23 @@ public void ProcessCommandLineParameters() string param = ParametersToProcess.Dequeue().Trim('\'').Trim('"'); if (param.Length > 2 && param[0] == '-' && param[1] == '-') { - Logger.ImportantInfo("Ignoring CLI-parameter " + param); - // Handle other --param command-line parameters - } - else if (param.Length > 11 && param.ToLower().StartsWith("unigetui://")) - { - string baseUrl = param[11..]; - Logger.ImportantInfo("Begin handle of deep link with body " + baseUrl); - - if (baseUrl.StartsWith("showPackage?")) - { - string Id = Regex.Match(baseUrl, "id=([^&]+)").Value.Split("=")[^1]; - string CombinedManagerName = Regex.Match(baseUrl, "combinedManagerName=([^&]+)").Value.Split("=")[^1]; - string ManagerName = Regex.Match(baseUrl, "managerName=([^&]+)").Value.Split("=")[^1]; - string SourceName = Regex.Match(baseUrl, "sourceName=([^&]+)").Value.Split("=")[^1]; - - - if (Id != "" && CombinedManagerName != "" && ManagerName == "" && SourceName == "") - { - Logger.Warn($"URI {param} follows old scheme"); - NavigationPage.DiscoverPage.ShowSharedPackage_ThreadSafe(Id, CombinedManagerName); - } - else if (Id != "" && ManagerName != "" && SourceName != "") - { - NavigationPage.DiscoverPage.ShowSharedPackage_ThreadSafe(Id, ManagerName, SourceName); - } - else - { - Logger.Error(new UriFormatException($"Malformed URL {param}")); - } - } - else if (baseUrl.StartsWith("showUniGetUI")) + if (param == "--help") { - // Do nothing, window already shown + NavigationPage.ShowHelp(); } - else if (baseUrl.StartsWith("showUpdatesPage")) + else if (new[]{ "--daemon", "--updateapps", "--report-all-errors", "--uninstall-unigetui", "--migrate-wingetui-to-unigetui" }.Contains(param)) { - NavigationPage.UpdatesNavButton.ForceClick(); + // Pass, this parameters are handled elsewhere } else { - Logger.Error(new UriFormatException($"Malformed URL {param}")); + Logger.Warn("Unknown parameter " + param); } } + else if (param.Length > 11 && param.ToLower().StartsWith("unigetui://")) + { + HandleDeepLink(param); + } else if (Path.IsPathFullyQualified(param) && File.Exists(param)) { if (param.EndsWith(".json") || param.EndsWith(".xml") || param.EndsWith(".yaml")) From de6660dd73e50c15fb96cda2379191affcb24d4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Sat, 31 Aug 2024 22:38:52 +0200 Subject: [PATCH 09/13] Handle when the PackageManager is enabled but not ready --- src/UniGetUI/MainWindow.xaml.cs | 12 ++------ .../SoftwarePages/DiscoverSoftwarePage.cs | 30 +++++++++++-------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/src/UniGetUI/MainWindow.xaml.cs b/src/UniGetUI/MainWindow.xaml.cs index e2f8be510..25545a9d2 100644 --- a/src/UniGetUI/MainWindow.xaml.cs +++ b/src/UniGetUI/MainWindow.xaml.cs @@ -225,9 +225,7 @@ private void HandleDeepLink(string link) } } else if (baseUrl.StartsWith("showUniGetUI")) - { - // Do nothing, window already shown - } + { /* Skip */ } else if (baseUrl.StartsWith("showDiscoverPage")) { NavigationPage.DiscoverNavButton.ForceClick(); @@ -261,9 +259,7 @@ public void ProcessCommandLineParameters() NavigationPage.ShowHelp(); } else if (new[]{ "--daemon", "--updateapps", "--report-all-errors", "--uninstall-unigetui", "--migrate-wingetui-to-unigetui" }.Contains(param)) - { - // Pass, this parameters are handled elsewhere - } + { /* Skip */ } else { Logger.Warn("Unknown parameter " + param); @@ -288,9 +284,7 @@ public void ProcessCommandLineParameters() } } else if (param.EndsWith("UniGetUI.exe") || param.EndsWith("UniGetUI.dll")) - { - // Skip - } + { /* Skip */ } else { Logger.Warn("Did not know how to handle the parameter " + param); diff --git a/src/UniGetUI/SoftwarePages/DiscoverSoftwarePage.cs b/src/UniGetUI/SoftwarePages/DiscoverSoftwarePage.cs index d855f7377..bc91bc85c 100644 --- a/src/UniGetUI/SoftwarePages/DiscoverSoftwarePage.cs +++ b/src/UniGetUI/SoftwarePages/DiscoverSoftwarePage.cs @@ -366,15 +366,19 @@ public void ShowSharedPackage_ThreadSafe(string id, string combinedSourceName) string managerName = contents[0]; string sourceName = ""; if (contents.Length > 1) sourceName = contents[1]; - MainApp.Instance.MainWindow.DispatcherQueue.TryEnqueue(() => { ShowSharedPackage(id, managerName, sourceName); }); + ShowSharedPackage_ThreadSafe(id, managerName, sourceName); } public void ShowSharedPackage_ThreadSafe(string id, string managerName, string sourceName) { - MainApp.Instance.MainWindow.DispatcherQueue.TryEnqueue(() => { ShowSharedPackage(id, managerName, sourceName); }); + MainApp.Instance.MainWindow.DispatcherQueue.TryEnqueue(async () => + { + IPackage? package = await GetPackageFromIdAndManager(id, managerName, sourceName); + if (package is not null) ShowDetailsForPackage(package); + }); } - private async void ShowSharedPackage(string id, string managerName, string sourceName) + private static async Task GetPackageFromIdAndManager(string id, string managerName, string sourceName) { try { @@ -388,13 +392,8 @@ private async void ShowSharedPackage(string id, string managerName, string sourc { if (candidate.Name == managerName || candidate.DisplayName == managerName) { - if (candidate.IsEnabled()) - { - manager = candidate; - break; - } - throw new ArgumentException(CoreTools.Translate("The Package Manager {0} is disabled", - candidate.DisplayName)); + manager = candidate; + break; } } @@ -403,6 +402,12 @@ private async void ShowSharedPackage(string id, string managerName, string sourc throw new ArgumentException(CoreTools.Translate("The package manager {0} was not found", managerName)); } + if(!manager.IsEnabled()) + throw new ArgumentException(CoreTools.Translate("The package manager {0} is disabled", manager.DisplayName)); + + if(!manager.Status.Found) + throw new ArgumentException(CoreTools.Translate("The package manager {0} is not properly set up", manager.DisplayName)); + var results = await manager.FindPackages(id); var candidates = results.Where(p => p.Id == id).ToArray(); @@ -421,8 +426,7 @@ private async void ShowSharedPackage(string id, string managerName, string sourc Logger.ImportantInfo($"Found package {package.Id} on manager {package.Manager.Name}, showing it..."); MainApp.Instance.MainWindow.HideLoadingDialog(); - ShowDetailsForPackage(package); - + return package; } catch (Exception ex) { @@ -439,7 +443,7 @@ private async void ShowSharedPackage(string id, string managerName, string sourc MainApp.Instance.MainWindow.HideLoadingDialog(); await MainApp.Instance.MainWindow.ShowDialogAsync(warningDialog); - + return null; } } } From 40f247a2500e8e2568302ac92fd7965c1942eaf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Sat, 31 Aug 2024 22:42:36 +0200 Subject: [PATCH 10/13] better message --- src/UniGetUI/SoftwarePages/DiscoverSoftwarePage.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/UniGetUI/SoftwarePages/DiscoverSoftwarePage.cs b/src/UniGetUI/SoftwarePages/DiscoverSoftwarePage.cs index bc91bc85c..0b30b5c5f 100644 --- a/src/UniGetUI/SoftwarePages/DiscoverSoftwarePage.cs +++ b/src/UniGetUI/SoftwarePages/DiscoverSoftwarePage.cs @@ -406,7 +406,7 @@ public void ShowSharedPackage_ThreadSafe(string id, string managerName, string s throw new ArgumentException(CoreTools.Translate("The package manager {0} is disabled", manager.DisplayName)); if(!manager.Status.Found) - throw new ArgumentException(CoreTools.Translate("The package manager {0} is not properly set up", manager.DisplayName)); + throw new ArgumentException(CoreTools.Translate("There is an error with the configuration of the package manager {0}", manager.DisplayName)); var results = await manager.FindPackages(id); var candidates = results.Where(p => p.Id == id).ToArray(); From e2a3e77f67ab78404450360351c0050204ffddfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Sat, 31 Aug 2024 23:19:13 +0200 Subject: [PATCH 11/13] Update translations --- README.md | 8 +++---- .../Assets/Data/TranslatedPercentages.json | 3 +-- .../Assets/Languages/lang_de.json | 24 +++++++++---------- .../Assets/Languages/lang_lt.json | 10 ++++---- 4 files changed, 22 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index e0fadd793..24788ee89 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ To translate UniGetUI to other languages or to update an old translation, please |   Catalan - Català | 100% | [marticliment](https://github.com/marticliment) | |   Czech - Čeština | 98% | [mlisko](https://github.com/mlisko), [panther7](https://github.com/panther7), [xtorlukas](https://github.com/xtorlukas) | |   Danish - Dansk | 74% | [AAUCrisp](https://github.com/AAUCrisp), [mikkolukas](https://github.com/mikkolukas), [yrjarv](https://github.com/yrjarv) | -|   German - Deutsch | 98% | [1270o1](https://github.com/1270o1), [alxhu-dev](https://github.com/alxhu-dev), [CanePlayz](https://github.com/CanePlayz), [Datacra5H](https://github.com/Datacra5H), [ebnater](https://github.com/ebnater), [michaelmairegger](https://github.com/michaelmairegger), [Seeloewen](https://github.com/Seeloewen), [yrjarv](https://github.com/yrjarv) | +|   German - Deutsch | 100% | [1270o1](https://github.com/1270o1), [alxhu-dev](https://github.com/alxhu-dev), [CanePlayz](https://github.com/CanePlayz), [Datacra5H](https://github.com/Datacra5H), [ebnater](https://github.com/ebnater), [michaelmairegger](https://github.com/michaelmairegger), [Seeloewen](https://github.com/Seeloewen), [yrjarv](https://github.com/yrjarv) | |   Greek - Ελληνικά | 97% | [antwnhsx](https://github.com/antwnhsx), [thunderstrike116](https://github.com/thunderstrike116), [wobblerrrgg](https://github.com/wobblerrrgg) | |   Estonian - Eesti | 18% | [artjom3729](https://github.com/artjom3729) | |   English - English | 100% | [marticliment](https://github.com/marticliment), [ppvnf](https://github.com/ppvnf) | @@ -136,11 +136,11 @@ To translate UniGetUI to other languages or to update an old translation, please |   Indonesian - Bahasa Indonesia | 82% | [arthackrc](https://github.com/arthackrc), [joenior](https://github.com/joenior) | |   Japanese - 日本語 | 92% | [nob-swik](https://github.com/nob-swik), sho9029, [tacostea](https://github.com/tacostea), Yuki Takase | |   Korean - 한국어 | 83% | [minbert](https://github.com/minbert), [shblue21](https://github.com/shblue21), [VenusGirl](https://github.com/VenusGirl) | -|   Lithuanian - Lietuvių | 72% | [dziugas1959](https://github.com/dziugas1959), Džiugas Januševičius | +|   Lithuanian - Lietuvių | 75% | [dziugas1959](https://github.com/dziugas1959), Džiugas Januševičius | |   Macedonian - Македонски | 62% | LordDeatHunter | |   Norwegian (bokmål) | 98% | [yrjarv](https://github.com/yrjarv) | |   Norwegian (nynorsk) | 98% | [yrjarv](https://github.com/yrjarv) | -|   Dutch - Nederlands | 98% | [abbydiode](https://github.com/abbydiode), [CateyeNL](https://github.com/CateyeNL), [Stephan-P](https://github.com/Stephan-P) | +|   Dutch - Nederlands | 100% | [abbydiode](https://github.com/abbydiode), [CateyeNL](https://github.com/CateyeNL), [Stephan-P](https://github.com/Stephan-P) | |   Polish - Polski | 98% | [KamilZielinski](https://github.com/KamilZielinski), [kwiateusz](https://github.com/kwiateusz), [RegularGvy13](https://github.com/RegularGvy13), [ThePhaseless](https://github.com/ThePhaseless) | |   Portuguese (Brazil) | 98% | [maisondasilva](https://github.com/maisondasilva), [ppvnf](https://github.com/ppvnf), [Rodrigo-Matsuura](https://github.com/Rodrigo-Matsuura), [thiagojramos](https://github.com/thiagojramos), [wanderleihuttel](https://github.com/wanderleihuttel) | |   Portuguese (Portugal) | 98% | [PoetaGA](https://github.com/PoetaGA), [Tiago_Ferreira](https://github.com/Tiago_Ferreira) | @@ -161,7 +161,7 @@ To translate UniGetUI to other languages or to update an old translation, please |   Simplified Chinese (China) | 100% | Aaron Liu, adfnekc, [arthurfsy2](https://github.com/arthurfsy2), [bai0012](https://github.com/bai0012), BUGP Association, ciaran, CnYeSheng, Cololi, [dongfengweixiao](https://github.com/dongfengweixiao), [FloatStream](https://github.com/FloatStream), [seanyu0](https://github.com/seanyu0), [Sigechaishijie](https://github.com/Sigechaishijie), [SpaceTimee](https://github.com/SpaceTimee), Yisme | |   Traditional Chinese (Taiwan) | 93% | Aaron Liu, CnYeSheng, Cololi, [Henryliu880922](https://github.com/Henryliu880922), [yrctw](https://github.com/yrctw) | -Last updated: Sat Aug 31 00:12:02 2024 +Last updated: Sat Aug 31 22:51:42 2024 diff --git a/src/UniGetUI.Core.LanguageEngine/Assets/Data/TranslatedPercentages.json b/src/UniGetUI.Core.LanguageEngine/Assets/Data/TranslatedPercentages.json index b67a14b48..8032b2a9d 100644 --- a/src/UniGetUI.Core.LanguageEngine/Assets/Data/TranslatedPercentages.json +++ b/src/UniGetUI.Core.LanguageEngine/Assets/Data/TranslatedPercentages.json @@ -4,7 +4,6 @@ "bn": "82%", "cs": "98%", "da": "74%", - "de": "98%", "el": "97%", "es": "98%", "et": "18%", @@ -21,7 +20,7 @@ "ja": "92%", "kn": "0%", "ko": "83%", - "lt": "74%", + "lt": "75%", "mk": "62%", "nb": "98%", "nn": "98%", diff --git a/src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_de.json b/src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_de.json index 5cad926e6..55870c4fb 100644 --- a/src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_de.json +++ b/src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_de.json @@ -28,8 +28,8 @@ "Add a timestamp to the backup file names" : "Zeitstempel an Dateinamen von Sicherungsdateien anhängen", "Add a timestamp to the backup files" : "Zeitstempel an Sicherungsdateien anhängen", "Add packages or open an existing bundle" : "Pakete hinzufügen oder existierendes Bündel öffnen", - "Add packages or open an existing package bundle" : null, - "Add packages to start" : null, + "Add packages or open an existing package bundle" : "Pakete hinzufügen oder ein vorhandenes Paket-Bündel öffnen", + "Add packages to start" : "Pakete zum Starten hinzufügen", "Add selection to bundle" : "Auswahl zum Bündel hinzufügen", "Add source" : "Quelle hinzufügen", "Adding source {source} to {manager}" : "Quelle {source} wird zu {manager} hinzugefügt", @@ -100,7 +100,7 @@ "Clear selection" : "Auswahl aufheben", "Clearing Scoop cache - WingetUI" : "Scoop-Cache leeren - WingetUI", "Clearing Scoop cache..." : "Scoop-Cache leeren...", - "Click on Install to begin the installation process. If you skip the installation, UniGetUI may not work as expected." : null, + "Click on Install to begin the installation process. If you skip the installation, UniGetUI may not work as expected." : "Klicken Sie auf Installieren, um den Installationsprozess zu starten. Wenn Sie die Installation überspringen, funktioniert UniGetUI möglicherweise nicht wie erwartet.", "Close" : "Schließen", "Close WingetUI to the notification area" : "Schließe WingetUI in den Infobereich", "Command-line Output" : "Kommandozeilen-Ausgabe", @@ -300,7 +300,7 @@ "Open backup location" : "Sicherungsverzeichnis öffnen", "Open existing bundle" : "Vorhandenes Bündel öffnen", "Open the welcome wizard" : "Begrüßungsbildschirm öffnen", - "Operation canceled by user" : null, + "Operation canceled by user" : "Vorgang vom Benutzer abgebrochen", "Operation cancelled" : "Vorgang abgebrochen", "Operation history" : "Vorgangsverlauf", "Operation in progress" : "Vorgang läuft", @@ -419,10 +419,10 @@ "Show WingetUI" : "WingetUI anzeigen", "Show a notification when an installation fails" : "Benachrichtigung anzeigen, wenn eine Installation fehlschlägt", "Show a notification when an installation finishes successfully" : "Benachrichtigung anzeigen, wenn eine Installation erfolgreich abgeschlossen wurde", - "Show a notification when an operation fails" : null, - "Show a notification when an operation finishes successfully" : null, + "Show a notification when an operation fails" : "Benachrichtigung anzeigen, wenn ein Vorgang fehlschlägt", + "Show a notification when an operation finishes successfully" : "Benachrichtigung anzeigen, wenn ein Vorgang erfolgreich abgeschlossen wurde", "Show a notification when there are available updates" : "Benachrichtigung anzeigen, wenn Updates verfügbar sind", - "Show a silent notification when an operation is running" : null, + "Show a silent notification when an operation is running" : "Stille Benachrichtigung anzeigen, wenn ein Vorgang ausgeführt wird", "Show details" : "Details anzeigen", "Show info about the package on the Updates tab" : "Informationen über das Paket auf der Registerkarte „Updates“ anzeigen", "Show missing translation strings" : "Fehlende Übersetzungen anzeigen", @@ -464,7 +464,7 @@ "The backup will include the complete list of the installed packages and their installation options. Ignored updates and skipped versions will also be saved." : "Die Sicherung enthält eine vollständige Liste der installierten Pakete und deren Installationsoptionen. Ignorierte Updates und übersprungene Versionen werden ebenfalls gespeichert.", "The checksum of the installer does not coincide with the expected value, and the authenticity of the installer can't be verified. If you trust the publisher, {0} the package again skipping the hash check." : "Die Prüfsumme der Installationsdatei stimmt nicht mit dem erwarteten Wert überein und die Authentizität des Installers kann nicht verifiziert werden. Wenn Sie dem Herausgeber vertrauen, {0} das Paket erneut und überspringt die Hash-Prüfung.", "The classical package manager for windows. You'll find everything there.
Contains: General Software" : "Der klassische Paketmanager für Windows. Dort finden Sie alles.
Enthält: Allgemeine Software", - "The current bundle has no packages. Add some packages to get started" : null, + "The current bundle has no packages. Add some packages to get started" : "Das aktuelle Bündel enthält keine Pakete. Fügen Sie zum Start ein paar Pakete hinzu.", "The following packages are going to be exported to a JSON file. No user data or binaries are going to be saved." : "Die folgenden Pakete werden in eine JSON-Datei exportiert. Es werden keine Benutzerdaten oder Programmdateien gespeichert.", "The following packages are going to be installed on your system." : "Die folgenden Pakete werden auf Ihrem System installiert.", "The following settings will be applied each time this package is installed, updated or removed." : "Die folgenden Einstellungen werden jedes Mal angewendet, wenn dieses Paket installiert, aktualisiert oder entfernt wird.", @@ -490,7 +490,7 @@ "This could represent a security risk." : "Dies kann ein Sicherheitsrisiko darstellen.", "This is probably due to the fact that the package you were sent was removed, or published on a package manager that you don't have enabled. The received ID is {0}" : "Dies liegt wahrscheinlich daran, dass das Paket, das Sie gesendet haben, entfernt oder in einem Paketmanager veröffentlicht wurde, den Sie nicht aktiviert haben. Die empfangene ID ist {0}", "This is the default choice." : "Dies ist die Standardauswahl.", - "This may help if WinGet packages are not shown" : null, + "This may help if WinGet packages are not shown" : "Dies kann helfen, wenn WinGet-Pakete nicht angezeigt werden", "This may take a minute or two" : "Dies kann ein oder zwei Minuten dauern.", "This package can be updated" : "Dieses Paket kann aktualisiert werden", "This package can be updated to version {0}" : "Dieses Paket kann auf Version {0} aktualisiert werden", @@ -547,14 +547,14 @@ "Use Legacy bundled WinGet instead of PowerShell CMDLets" : "Verwenden Sie das mitgelieferte Legacy WinGet anstelle von PowerShell CMDLets", "Use a custom icon and screenshot database URL" : "Benutzerdefinierte Datenbank-URL für Icons und Screenshots verwenden", "Use bundled WinGet instead of PowerShell CMDlets" : "Mitgeliefertes WinGet anstelle von PowerShell CMDlets verwenden", - "Use bundled WinGet instead of system WinGet" : null, + "Use bundled WinGet instead of system WinGet" : "Mitgeliefertes WinGet anstelle des systemischen WinGet verwenden", "Use installed GSudo instead of the bundled one" : "Installiertes GSudo anstelle des Mitgelieferten verwenden (Neustart erforderlich)", "Use system Chocolatey" : "Systeminternes Chocolatey verwenden", "Use system Chocolatey (Needs a restart)" : "Systeminternes Chocolatey verwenden (Neustart notwendig)", "Use system Winget (Needs a restart)" : "Systeminternes Winget verwenden (Neustart notwendig)", "Use system Winget (System language must be set to english)" : "Systeminternes Winget verwenden (Systemsprache muss auf Englisch festgelegt sein)", "Use the WinGet COM API to fetch packages" : "Verwenden Sie die WinGet COM API zum Abrufen von Paketen", - "Use the WinGet PowerShell Module instead of the WinGet COM API" : null, + "Use the WinGet PowerShell Module instead of the WinGet COM API" : "Verwende das WinGet PowerShell Modul anstelle der WinGet COM API", "Useful links" : "Nützliche Links", "User" : "Benutzer", "User interface preferences" : "Einstellungen der Benutzeroberfläche", @@ -579,7 +579,7 @@ "Which package managers do you want to use?" : "Welcher Paketmanager soll verwendet werden?", "Which source do you want to add?" : "Welche Quelle möchtest du hinzufügen?", "While Winget can be used within WingetUI, WingetUI can be used with other package managers, which can be confusing. In the past, WingetUI was designed to work only with Winget, but this is not true anymore, and therefore WingetUI does not represent what this project aims to become." : "Während Winget innerhalb von WingetUI verwendet werden kann, kann WingetUI auch mit anderen Paketmanagern verwendet werden, was verwirrend sein kann. In der Vergangenheit war WingetUI darauf ausgerichtet, nur mit Winget zu funktionieren, aber das ist nicht länger der Fall, sodass der Name \"WingetUI\" nicht mehr das repräsentiert, was dieses Projekt anstrebt zu sein.", - "WingetUI" : null, + "WingetUI" : "WingetUI", "WingetUI - Everything is up to date" : "WingetUI – Alles ist auf dem neuesten Stand", "WingetUI - {0} updates are available" : "WingetUI - {0} Updates sind verfügbar", "WingetUI - {0} {1}" : "WingetUI - {0} {1}", diff --git a/src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_lt.json b/src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_lt.json index 0730871f2..4cee8f9bb 100644 --- a/src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_lt.json +++ b/src/UniGetUI.Core.LanguageEngine/Assets/Languages/lang_lt.json @@ -300,7 +300,7 @@ "Open backup location" : "Atidaryti atsarginės kopijos vietovę", "Open existing bundle" : "Atidaryti jau egzistuojanti rinkinį", "Open the welcome wizard" : "Atidaryti „Sveiki!“ sąranka/vedly", - "Operation canceled by user" : null, + "Operation canceled by user" : "Operacija atšaukta naudotojo/vartotojo", "Operation cancelled" : "Operacija atšaukta", "Operation history" : "Operacijos istorija", "Operation in progress" : "Operacija vykdoma", @@ -383,11 +383,11 @@ "Running the updater..." : "Vykdomas naujinys...", "Save File" : "Išsaugoti failą", "Save and close" : "Išsaugoti ir uždaryti", - "Save bundle as" : null, + "Save bundle as" : "Išsaugoti rinkinį kaip", "Save now" : "Išsaugoti dabar", "Saving packages, please wait..." : "Išsaugomi paketai, prašome palaukti...", - "Scoop Installer - WingetUI" : null, - "Scoop Uninstaller - WingetUI" : null, + "Scoop Installer - WingetUI" : "„Scoop“ įdiegiklis – „WingetUI“", + "Scoop Uninstaller - WingetUI" : "„Scoop“ išdiegiklis – „WingetUI“", "Scoop package" : "„Scoop“ paketas", "Search" : "Ieškoti", "Search for desktop software, warn me when updates are available and do not do nerdy things. I don't want WingetUI to overcomplicate, I just want a simple software store" : null, @@ -490,7 +490,7 @@ "This could represent a security risk." : null, "This is probably due to the fact that the package you were sent was removed, or published on a package manager that you don't have enabled. The received ID is {0}" : null, "This is the default choice." : null, - "This may help if WinGet packages are not shown" : null, + "This may help if WinGet packages are not shown" : "Šis gali padėti, jei „WinGet“ paketai nesirodo", "This may take a minute or two" : "Šis gali užtrukti minutę ar dvi", "This package can be updated" : "Šis paketas gali būti atnaujintas", "This package can be updated to version {0}" : "Šis paketas gali būti atnaujintas į versiją – {0}", From 364c7950aa6ea56a108d343a688e0b9d2fd34ea6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Sat, 31 Aug 2024 23:19:34 +0200 Subject: [PATCH 12/13] Allow bundles to be imported/exported with the .ubundle extension --- src/UniGetUI/MainWindow.xaml.cs | 6 +++--- .../SoftwarePages/InstalledPackagesPage.cs | 2 +- .../SoftwarePages/PackageBundlesPage.cs | 21 +++++++++++-------- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/UniGetUI/MainWindow.xaml.cs b/src/UniGetUI/MainWindow.xaml.cs index 25545a9d2..287ea03e3 100644 --- a/src/UniGetUI/MainWindow.xaml.cs +++ b/src/UniGetUI/MainWindow.xaml.cs @@ -199,10 +199,10 @@ public async void HandleClosingEvent(AppWindow sender, AppWindowClosingEventArgs /// the unigetui:// deep link to handle private void HandleDeepLink(string link) { - string baseUrl = link[11..]; + string baseUrl = Uri.UnescapeDataString(link[11..]); Logger.ImportantInfo("Begin handle of deep link with body " + baseUrl); - if (baseUrl.StartsWith("showPackage?")) + if (baseUrl.StartsWith("showPackage")) { string Id = Regex.Match(baseUrl, "id=([^&]+)").Value.Split("=")[^1]; string CombinedManagerName = Regex.Match(baseUrl, "combinedManagerName=([^&]+)").Value.Split("=")[^1]; @@ -271,7 +271,7 @@ public void ProcessCommandLineParameters() } else if (Path.IsPathFullyQualified(param) && File.Exists(param)) { - if (param.EndsWith(".json") || param.EndsWith(".xml") || param.EndsWith(".yaml")) + if (param.EndsWith(".ubundle") || param.EndsWith(".json") || param.EndsWith(".xml") || param.EndsWith(".yaml")) { // Handle potential JSON files Logger.ImportantInfo("Begin attempt to open the package bundle " + param); diff --git a/src/UniGetUI/SoftwarePages/InstalledPackagesPage.cs b/src/UniGetUI/SoftwarePages/InstalledPackagesPage.cs index 1188768a0..b0f006427 100644 --- a/src/UniGetUI/SoftwarePages/InstalledPackagesPage.cs +++ b/src/UniGetUI/SoftwarePages/InstalledPackagesPage.cs @@ -376,7 +376,7 @@ public async Task BackupPackages() fileName += " " + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"); } - fileName += ".json"; + fileName += ".ubundle"; string filePath = Path.Combine(dirName, fileName); await File.WriteAllTextAsync(filePath, BackupContents); diff --git a/src/UniGetUI/SoftwarePages/PackageBundlesPage.cs b/src/UniGetUI/SoftwarePages/PackageBundlesPage.cs index 07df12639..a25fc26db 100644 --- a/src/UniGetUI/SoftwarePages/PackageBundlesPage.cs +++ b/src/UniGetUI/SoftwarePages/PackageBundlesPage.cs @@ -374,7 +374,7 @@ public async Task OpenFromFile(string? file = null) { // Select file FileOpenPicker picker = new(MainApp.Instance.MainWindow.GetWindowHandle()); - file = picker.Show(new List { "*.json", "*.yaml", "*.xml" }); + file = picker.Show(new List { "*.ubundle", "*.json", "*.yaml", "*.xml" }); if (file == String.Empty) return; } @@ -383,17 +383,19 @@ public async Task OpenFromFile(string? file = null) // Read file BundleFormatType formatType; - if (file.Split('.')[^1].ToLower() == "yaml") + string EXT = file.Split('.')[^1].ToLower(); + if (EXT == "yaml") formatType = BundleFormatType.YAML; - else if (file.Split('.')[^1].ToLower() == "xml") + else if (EXT == "xml") formatType = BundleFormatType.XML; + else if (EXT == "json" || EXT == "ubundle") + formatType = BundleFormatType.JSON; else formatType = BundleFormatType.JSON; string fileContent = await File.ReadAllTextAsync(file); Loader.ClearPackages(); - // Import packages to list await AddFromBundle(fileContent, formatType); MainApp.Instance.MainWindow.HideLoadingDialog(); @@ -424,7 +426,7 @@ public async Task SaveFile() { // Get file // Save file - string file = (new FileSavePicker(MainApp.Instance.MainWindow.GetWindowHandle())).Show(new List { "*.json", "*.yaml", "*.xml" }, CoreTools.Translate("Package bundle") + ".json"); + string file = (new FileSavePicker(MainApp.Instance.MainWindow.GetWindowHandle())).Show(new List { "*.ubundle", "*.json", "*.yaml", "*.xml" }, CoreTools.Translate("Package bundle") + ".ubundle"); if (file != String.Empty) { // Loading dialog @@ -432,10 +434,13 @@ public async Task SaveFile() // Select appropriate format BundleFormatType formatType; - if (file.Split('.')[^1].ToLower() == "yaml") + string EXT = file.Split('.')[^1].ToLower(); + if (EXT == "yaml") formatType = BundleFormatType.YAML; - else if (file.Split('.')[^1].ToLower() == "xml") + else if (EXT == "xml") formatType = BundleFormatType.XML; + else if (EXT == "json" || EXT == "ubundle") + formatType = BundleFormatType.JSON; else formatType = BundleFormatType.JSON; @@ -506,8 +511,6 @@ public async Task AddFromBundle(string content, BundleFormatType format) if (format is BundleFormatType.JSON) { DeserializedData = await Task.Run(() => JsonSerializer.Deserialize(content)); - Logger.Error(DeserializedData.packages.Count.ToString()); - Logger.Error(DeserializedData.export_version.ToString()); } else if (format is BundleFormatType.YAML) { From d10f5d3f66ec15091a61a680a9aca12c110bd42a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Climent?= Date: Sat, 31 Aug 2024 23:40:52 +0200 Subject: [PATCH 13/13] register .ubundle extension with UniGetUI --- InstallerExtras/CustomMessages.iss | 24 ++++++++++++++++++++++++ README.md | 2 +- UniGetUI.iss | 8 +++++++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/InstallerExtras/CustomMessages.iss b/InstallerExtras/CustomMessages.iss index a15d83807..2c926ef3f 100644 --- a/InstallerExtras/CustomMessages.iss +++ b/InstallerExtras/CustomMessages.iss @@ -9,6 +9,7 @@ RegInst=Perform a regular installation RegStartMmenuIcon=Create a shortcut on the Start menu RegDesktopIcon=Create a shortcut on the Desktop ChocoInstall=Install Chocolatey +PackageBundleName=UniGetUI package bundle ; Armenian Armenian.InstallType=Տեղադրման տեսակը @@ -18,6 +19,7 @@ Armenian.RegInst=Կատարել սովորական տեղադրում Armenian.RegStartMmenuIcon=Ստեղծեք դյուրանցում Start ընտրացանկում Armenian.RegDesktopIcon=Ստեղծեք դյուրանցում աշխատասեղանի վրա Armenian.ChocoInstall=Ինստալացնել Chocolatey +Armenian.PackageBundleName=UniGetUI փաթեթի փաթեթ ; BrazilianPortuguese BrazilianPortuguese.InstallType=Tipo de instalação @@ -27,6 +29,7 @@ BrazilianPortuguese.RegInst=Realizar uma instalação regular BrazilianPortuguese.RegStartMmenuIcon=Criar um atalho no menu Iniciar BrazilianPortuguese.RegDesktopIcon=Criar um atalho na área de trabalh BrazilianPortuguese.ChocoInstall=Instalar Chocolatey +BrazilianPortuguese.PackageBundleName=Coleção de pacotes UniGetUI ; Catalan Catalan.InstallType=Tipus d'instal·lació @@ -36,6 +39,7 @@ Catalan.RegInst=Feu una instal·lació regular Catalan.RegStartMmenuIcon=Creeu una drecera al menú Inici Catalan.RegDesktopIcon=Creeu una drecera a l'Escriptori Catalan.ChocoInstall=Instal·lar Chocolatey +Catalan.PackageBundleName=Col·lecció de paquets de l'UniGetUI ; Corsican Corsican.InstallType=Tipu d'installazione @@ -45,6 +49,7 @@ Corsican.RegInst=Eseguite una installazione regulare Corsican.RegStartMmenuIcon=Create una scorciatoia nant'à u menu Start Corsican.RegDesktopIcon=Create una scorciatoia nant'à u Desktop Corsican.ChocoInstall=Stallà Chocolatey +Corsican.PackageBundleName=Raccolta di pacchetti UniGetUI ; Czech Czech.InstallType=Typ instalace @@ -54,6 +59,7 @@ Czech.RegInst=Proveďte běžnou instalaci Czech.RegStartMmenuIcon=Vytvořte zástupce v nabídce Start Czech.RegDesktopIcon=Vytvořte zástupce na ploše Czech.ChocoInstall=Nainstalovat Chocolatey +Czech.PackageBundleName=Kolekce balíčků UniGetUI ; Danish Danish.InstallType=Installationstype @@ -63,6 +69,7 @@ Danish.RegInst=Udfør en almindelig installation Danish.RegStartMmenuIcon=Opret en genvej på Start-menuen Danish.RegDesktopIcon=Opret en genvej på skrivebordet Danish.ChocoInstall=Installer Chocolatey +Danish.PackageBundleName=Samling af UniGetUI-pakker ; Dutch Dutch.InstallType=Installatietype @@ -72,6 +79,7 @@ Dutch.RegInst=Voer een normale installatie uit Dutch.RegStartMmenuIcon=Maak een snelkoppeling in het Startmenu Dutch.RegDesktopIcon=Maak een snelkoppeling op het bureaublad Dutch.ChocoInstall=Installeer Chocolatey +Dutch.PackageBundleName=Verzameling UniGetUI-pakketten ; Finnish Finnish.InstallType=Asennustyyppi @@ -81,6 +89,7 @@ Finnish.RegInst=Suorita tavallinen asennus Finnish.RegStartMmenuIcon=Luo pikakuvake Käynnistä-valikkoon Finnish.RegDesktopIcon=Luo pikakuvake työpöydälle Finnish.ChocoInstall=Asenna Chocolatey +Finnish.PackageBundleName=Kokoelma UniGetUI-paketteja ; French French.InstallType=Type d'installation @@ -90,6 +99,7 @@ French.RegInst=Effectuer une installation normale French.RegStartMmenuIcon=Créer un raccourci dans le menu Démarrer French.RegDesktopIcon=Créer un raccourci sur le bureau French.ChocoInstall=Installer Chocolatey +French.PackageBundleName=Collection de packages UniGetUI ; German German.InstallType=Installationstyp @@ -99,6 +109,7 @@ German.RegInst=Führe eine normale Installation durch German.RegStartMmenuIcon=Erstelle eine Verknüpfung im Startmenü German.RegDesktopIcon=Erstelle eine Verknüpfung auf dem Desktop German.ChocoInstall=Chocolatey installieren +German.PackageBundleName=Sammlung von UniGetUI-Paketen ; Hebrew Hebrew.InstallType=סוג התקנה @@ -108,6 +119,7 @@ Hebrew.RegInst=בצע התקנה רגילה Hebrew.RegStartMmenuIcon=צור קיצור דרך בתפריט התחל Hebrew.RegDesktopIcon=צור קיצור דרך בשולחן העבודה Hebrew.ChocoInstall=להתקין את Chocolatey +Hebrew.PackageBundleName=אוסף חבילות UniGetUI ; Icelandic Icelandic.InstallType=Uppsetningargerð @@ -117,6 +129,7 @@ Icelandic.RegInst=Framkvæma reglulega uppsetningu Icelandic.RegStartMmenuIcon=Búa til flýtileið á Start valmyndinni Icelandic.RegDesktopIcon=Búa til flýtileið á skjáborðinu Icelandic.ChocoInstall=Setja upp Chocolatey +Icelandic.PackageBundleName=Safn af UniGetUI pakka ; Italian Italian.InstallType=Tipo di installazione @@ -126,6 +139,7 @@ Italian.RegInst=Esegui installazione normale Italian.RegStartMmenuIcon=Crea una scorciatoia nel menu Start Italian.RegDesktopIcon=Crea una scorciatoia sul Desktop Italian.ChocoInstall=Installa Chocolatey +Italian.PackageBundleName=Raccolta di pacchetti UniGetUI ; Japanese Japanese.InstallType=インストールの種類 @@ -135,6 +149,7 @@ Japanese.RegInst=通常のインストールを実行します Japanese.RegStartMmenuIcon=スタート メニューにショートカットを作成する Japanese.RegDesktopIcon=デスクトップにショートカットを作成する Japanese.ChocoInstall=Chocolatey をインストールする +Japanese.PackageBundleName=UniGetUI パッケージのコレクション ; Korean Korean.InstallType=설치 유형 @@ -144,6 +159,7 @@ Korean.RegInst=일반 설치 수행 Korean.RegStartMmenuIcon=시작 메뉴에 바로가기 만들기 Korean.RegDesktopIcon=바탕화면에 바로가기 생성 Korean.ChocoInstall=초콜릿 설치 +Korean.PackageBundleName=UniGetUI 패키지 컬렉션 ; Norwegian Norwegian.InstallType=Installasjonstype @@ -153,6 +169,7 @@ Norwegian.RegInst=Utfør en vanlig installasjon Norwegian.RegStartMmenuIcon=Lag en snarvei på Start-menyen Norwegian.RegDesktopIcon=Lag en snarvei på skrivebordet Norwegian.ChocoInstall=Installer Chocolatey +Norwegian.PackageBundleName=Samling av UniGetUI-pakker ; Polish Polish.InstallType=Typ instalacji @@ -162,6 +179,7 @@ Polish.RegInst=Przeprowadź zwykłą instalację Polish.RegStartMmenuIcon=Utwórz skrót w menu Start Polish.RegDesktopIcon=Utwórz skrót na pulpicie Polish.ChocoInstall=Zainstaluj Chocolatey +Polish.PackageBundleName=Kolekcja pakietów UniGetUI ; Portuguese Portuguese.InstallType=Tipo de instalação @@ -171,6 +189,7 @@ Portuguese.RegInst=Execute uma instalação regular Portuguese.RegStartMmenuIcon=Criar um atalho no menu Iniciar Portuguese.RegDesktopIcon=Criar um atalho na área de trabalho Portuguese.ChocoInstall=Instalar o Chocolatey +Portuguese.PackageBundleName=Coleção de pacotes UniGetUI ; Russian Russian.InstallType=Тип установки @@ -180,6 +199,7 @@ Russian.RegInst=Выполнить обычную установку Russian.RegStartMmenuIcon=Создать ярлык в меню «Пуск» Russian.RegDesktopIcon=Создать ярлык на рабочем столе Russian.ChocoInstall=Установить Chocolatey +Russian.PackageBundleName= ; Slovenian Slovenian.InstallType=Vrsta namestitve @@ -189,6 +209,7 @@ Slovenian.RegInst=Izvedite običajno namestitev Slovenian.RegStartMmenuIcon=Ustvarite bližnjico v meniju Start Slovenian.RegDesktopIcon=Ustvarite bližnjico na namizju Slovenian.ChocoInstall=Namesti Chocolatey +Slovenian.PackageBundleName=Коллекция пакетов UniGetUI ; Spanish Spanish.InstallType=Tipo de instalación @@ -198,6 +219,7 @@ Spanish.RegInst=Realizar una instalación regular Spanish.RegStartMmenuIcon=Crear un acceso directo en el menú Inicio Spanish.RegDesktopIcon=Crear un atajo en el escritorio Spanish.ChocoInstall=Instalar Chocolatey +Spanish.PackageBundleName=Coleción de paquetes del UniGetUI ; Turkish Turkish.InstallType=Yükleme türü @@ -207,6 +229,7 @@ Turkish.RegInst=Normal bir kurulum gerçekleştir Turkish.RegStartMmenuIcon=Başlat menüsünde bir kısayol oluştur Turkish.RegDesktopIcon=Masaüstünde bir kısayol oluştur Turkish.ChocoInstall=Chocolatey'i yükleyin +Turkish.PackageBundleName=UniGetUI paketlerinin toplanması ; Ukrainian Ukrainian.InstallType=Тип інсталяції @@ -216,3 +239,4 @@ Ukrainian.RegInst=Виконайте звичайну установку Ukrainian.RegStartMmenuIcon=Створити ярлик у меню «Пуск». Ukrainian.RegDesktopIcon=Створити ярлик на робочому столі Ukrainian.ChocoInstall=Встановити Chocolatey +Ukrainian.PackageBundleName=Колекція пакетів UniGetUI diff --git a/README.md b/README.md index 24788ee89..5696602ad 100644 --- a/README.md +++ b/README.md @@ -161,7 +161,7 @@ To translate UniGetUI to other languages or to update an old translation, please |   Simplified Chinese (China) | 100% | Aaron Liu, adfnekc, [arthurfsy2](https://github.com/arthurfsy2), [bai0012](https://github.com/bai0012), BUGP Association, ciaran, CnYeSheng, Cololi, [dongfengweixiao](https://github.com/dongfengweixiao), [FloatStream](https://github.com/FloatStream), [seanyu0](https://github.com/seanyu0), [Sigechaishijie](https://github.com/Sigechaishijie), [SpaceTimee](https://github.com/SpaceTimee), Yisme | |   Traditional Chinese (Taiwan) | 93% | Aaron Liu, CnYeSheng, Cololi, [Henryliu880922](https://github.com/Henryliu880922), [yrctw](https://github.com/yrctw) | -Last updated: Sat Aug 31 22:51:42 2024 +Last updated: Sat Aug 31 23:37:24 2024 diff --git a/UniGetUI.iss b/UniGetUI.iss index 5f16affae..d79a7e7e6 100644 --- a/UniGetUI.iss +++ b/UniGetUI.iss @@ -198,12 +198,18 @@ Name: "regularinstall\chocoinstall"; Description: "{cm:ChocoInstall}"; GroupDesc [Registry] Root: HKCU; Subkey: "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"; ValueType: string; ValueName: "WingetUI"; ValueData: """{app}\UniGetUI.exe"" --daemon"; Flags: uninsdeletevalue; Tasks: regularinstall -// Register the unigetui:// deep-link protocol +// Register the unigetui:// deep link Root: HKA; Subkey: "Software\Classes\unigetui"; ValueType: "string"; ValueData: "URL:UniGetUI Protocol"; Flags: uninsdeletekey Root: HKA; Subkey: "Software\Classes\unigetui"; ValueType: "string"; ValueName: "URL Protocol"; ValueData: "" Root: HKA; Subkey: "Software\Classes\unigetui\DefaultIcon"; ValueType: "string"; ValueData: "{app}\{#MyAppExeName},0" Root: HKA; Subkey: "Software\Classes\unigetui\shell\open\command"; ValueType: "string"; ValueData: """{app}\{#MyAppExeName}"" ""%1""" +// Register the .ubundle file type +Root: HKA; Subkey: "Software\Classes\.ubundle"; ValueType: string; ValueData: "UniGetUI.PackageBundle"; Flags: uninsdeletekey +Root: HKA; Subkey: "Software\Classes\UniGetUI.PackageBundle"; ValueType: string; ValueData: {cm:PackageBundleName}; Flags: uninsdeletekey +Root: HKA; Subkey: "Software\Classes\UniGetUI.PackageBundle\DefaultIcon"; ValueType: string; ValueData: "{app}\{#MyAppExeName},0"; Flags: uninsdeletekey +Root: HKA; Subkey: "Software\Classes\UniGetUI.PackageBundle\shell\open\command"; ValueType: string; ValueData: """{app}\{#MyAppExeName}"" ""%1"""; Flags: uninsdeletekey + [Files] Source: "unigetui_bin\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion; BeforeInstall: TripleKill('WingetUI.exe', 'UniGetUI.exe', 'choco.exe');