diff --git a/src/UniGetUI.Core.IconStore/UniGetUI.Core.IconEngine.csproj b/src/UniGetUI.Core.IconStore/UniGetUI.Core.IconEngine.csproj index 60da03e101..29fd21b362 100644 --- a/src/UniGetUI.Core.IconStore/UniGetUI.Core.IconEngine.csproj +++ b/src/UniGetUI.Core.IconStore/UniGetUI.Core.IconEngine.csproj @@ -24,6 +24,6 @@ - + diff --git a/src/UniGetUI.Core.LanguageEngine/UniGetUI.Core.LanguageEngine.csproj b/src/UniGetUI.Core.LanguageEngine/UniGetUI.Core.LanguageEngine.csproj index a191fa73eb..625d9d0186 100644 --- a/src/UniGetUI.Core.LanguageEngine/UniGetUI.Core.LanguageEngine.csproj +++ b/src/UniGetUI.Core.LanguageEngine/UniGetUI.Core.LanguageEngine.csproj @@ -12,7 +12,7 @@ - + diff --git a/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs b/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs index 4777b2fd17..120e48f054 100644 --- a/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs +++ b/src/UniGetUI.PackageEngine.Operations/PackageOperations.cs @@ -157,7 +157,7 @@ protected override Task HandleSuccess() if (Settings.Get("AskToDeleteNewDesktopShortcuts")) { - DesktopShortcutsDatabase.TryRemoveNewShortcuts(DesktopShortcutsBeforeStart); + DesktopShortcutsDatabase.HandleNewShortcuts(DesktopShortcutsBeforeStart); } return Task.CompletedTask; } @@ -177,7 +177,7 @@ protected override void Initialize() if (Settings.Get("AskToDeleteNewDesktopShortcuts")) { - DesktopShortcutsBeforeStart = DesktopShortcutsDatabase.GetShortcuts(); + DesktopShortcutsBeforeStart = DesktopShortcutsDatabase.GetShortcutsOnDisk(); } } } @@ -209,7 +209,7 @@ protected override async Task HandleSuccess() if (Settings.Get("AskToDeleteNewDesktopShortcuts")) { - DesktopShortcutsDatabase.TryRemoveNewShortcuts(DesktopShortcutsBeforeStart); + DesktopShortcutsDatabase.HandleNewShortcuts(DesktopShortcutsBeforeStart); } if (await Package.HasUpdatesIgnoredAsync() && await Package.GetIgnoredUpdatesVersionAsync() != "*") @@ -231,7 +231,7 @@ protected override void Initialize() if (Settings.Get("AskToDeleteNewDesktopShortcuts")) { - DesktopShortcutsBeforeStart = DesktopShortcutsDatabase.GetShortcuts(); + DesktopShortcutsBeforeStart = DesktopShortcutsDatabase.GetShortcutsOnDisk(); } } } diff --git a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/DesktopShortcutsDatabase.cs b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/DesktopShortcutsDatabase.cs index ea04da8d0e..42fbc90e03 100644 --- a/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/DesktopShortcutsDatabase.cs +++ b/src/UniGetUI.PackageEngine.PackageManagerClasses/Packages/Classes/DesktopShortcutsDatabase.cs @@ -8,8 +8,8 @@ public static class DesktopShortcutsDatabase public enum Status { Maintain, // The user has explicitly requested this shortcut not be deleted - Delete, // The user has allowed the shortcut to be deleted Unknown, // The user has not said whether they want this shortcut to be deleted + Delete, // The user has allowed the shortcut to be deleted } private static readonly List UnknownShortcuts = []; @@ -28,10 +28,13 @@ public static void ResetDatabase() /// Adds a desktop shortcut to the deletable desktop shortcuts database /// /// The path of the shortcut to delete - /// Whether or not to mark this entry as deletable in the database. Defaults to true - public static void AddToDatabase(string shortcutPath, bool deletable = true) + /// The status to set + public static void AddToDatabase(string shortcutPath, Status shortcutStatus) { - Settings.SetDictionaryItem("DeletableDesktopShortcuts", shortcutPath, deletable); + if (shortcutStatus is Status.Unknown) + Settings.RemoveDictionaryKey("DeletableDesktopShortcuts", shortcutPath); + else + Settings.SetDictionaryItem("DeletableDesktopShortcuts", shortcutPath, shortcutStatus is Status.Delete); } /// @@ -54,28 +57,6 @@ public static bool Remove(string shortcutPath) return false; } - /// - /// Attempts to reset the configuration of a given shortcut path from the database. - /// This will make it so the user is asked about it the next time it is discovered. - /// Different from `Remove` as Remove simply marks it as non-deletable, whereas this removes the configuration entirely. - /// - /// The path of the shortcut to delete - /// True if the shortcut was completely removed, false if it was not there from the beginning - public static bool ResetShortcut(string shortcutPath) - { - // Remove the entry if present - if (Settings.DictionaryContainsKey("DeletableDesktopShortcuts", shortcutPath)) - { - // Remove the entry and propagate changes to disk - Settings.RemoveDictionaryKey("DeletableDesktopShortcuts", shortcutPath); - return true; - } - - // Do nothing if the entry was not there - Logger.Warn($"Attempted to reset a deletable desktop shortcut {{shortcutPath={shortcutPath}}} that was not found there"); - return false; - } - /// /// Attempts to delete the given shortcut path off the disk /// @@ -103,7 +84,7 @@ public static bool DeleteFromDisk(string shortcutPath) /// until a choice is given to the user and they explicitly request that it be deleted. /// /// The path of the shortcut to be deleted - /// True if the package is ignored, false otherwhise + /// The status of a shortcut public static Status GetStatus(string shortcutPath) { // Check if the package is ignored @@ -120,7 +101,7 @@ public static Status GetStatus(string shortcutPath) /// Get a list of shortcuts (.lnk files only) currently on the user's desktop /// /// A list of desktop shortcut paths - public static List GetShortcuts() + public static List GetShortcutsOnDisk() { List shortcuts = []; string UserDesktop = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); @@ -130,6 +111,23 @@ public static List GetShortcuts() return shortcuts; } + /// + /// Gets all the shortcuts exist on disk or/and on the database + /// + /// + public static List GetAllShortcuts() + { + var shortcuts = GetShortcutsOnDisk(); + + foreach (var item in Settings.GetDictionary("DeletableDesktopShortcuts")) + { + if (!shortcuts.Contains(item.Key)) + shortcuts.Add(item.Key); + } + + return shortcuts; + } + /// /// Remove a shortcut from the list of shortcuts whose deletion verdicts are unknown (as in, the user needs to be asked about deleting them when their operations finish) /// @@ -150,29 +148,52 @@ public static List GetUnknownShortcuts() } /// - /// Will attempt to remove new desktop shortcuts, if applicable. + /// Will handle the removal, if applicable, of any shortcut that is not present on the given PreviousShortCutList. /// - /// - public static void TryRemoveNewShortcuts(IReadOnlyList PreviousShortCutList) + /// The shortcuts that already existed + public static void HandleNewShortcuts(IReadOnlyList PreviousShortCutList) { - HashSet ShortcutSet = PreviousShortCutList.ToHashSet(); - List CurrentShortcutList = DesktopShortcutsDatabase.GetShortcuts(); - foreach (string shortcut in CurrentShortcutList) + bool DeleteUnknownShortcuts = Settings.Get("RemoveAllDesktopShortcuts"); + HashSet PreviousShortcuts = [.. PreviousShortCutList]; + List CurrentShortcuts = GetShortcutsOnDisk(); + + foreach (string shortcut in CurrentShortcuts) { - if (ShortcutSet.Contains(shortcut)) continue; - switch (DesktopShortcutsDatabase.GetStatus(shortcut)) + var status = GetStatus(shortcut); + if (status is Status.Maintain) + { + // Don't delete this shortcut, it has been set to be kept + } + else if (status is Status.Delete) + { + // If a shortcut is set to be deleted, delete it, + // even when it was not created during an UniGetUI operation + DeleteFromDisk(shortcut); + } + else if (status is Status.Unknown) { - case Status.Delete: - DesktopShortcutsDatabase.DeleteFromDisk(shortcut); - break; - case Status.Maintain: - Logger.Debug("Refraining from deleting new shortcut " + shortcut + ": user disabled its deletion"); - break; - case Status.Unknown: - if (UnknownShortcuts.Contains(shortcut)) continue; - Logger.Info("Marking the shortcut " + shortcut + " to be asked to be deleted"); - UnknownShortcuts.Add(shortcut); - break; + if (DeleteUnknownShortcuts) + { + // If a shortcut has not been detected yet, and it + // existed before an operation started, then do nothing. + if(PreviousShortcuts.Contains(shortcut)) + continue; + + // If the shortcut was created during an operation + // and autodelete is enabled, delete that icon + Logger.Warn($"New shortcut {shortcut} will be set for deletion (this shortcut was never seen before)"); + AddToDatabase(shortcut, Status.Delete); + DeleteFromDisk(shortcut); + } + else + { + // Mark the shortcut as unknown and prompt the user. + if (!UnknownShortcuts.Contains(shortcut)) + { + Logger.Info($"Marking the shortcut {shortcut} to be asked to be deleted"); + UnknownShortcuts.Add(shortcut); + } + } } } } diff --git a/src/UniGetUI/Pages/DialogPages/DesktopShortcuts.xaml b/src/UniGetUI/Pages/DialogPages/DesktopShortcuts.xaml index f0010776d0..d6e5afbe20 100644 --- a/src/UniGetUI/Pages/DialogPages/DesktopShortcuts.xaml +++ b/src/UniGetUI/Pages/DialogPages/DesktopShortcuts.xaml @@ -7,8 +7,7 @@ xmlns:local="using:UniGetUI.Interface" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:widgets="using:UniGetUI.Interface.Widgets" - Width="900" - MaxWidth="1100" + MaxWidth="950" mc:Ignorable="d"> @@ -30,7 +29,7 @@ VerticalAlignment="Bottom" Orientation="Vertical" Spacing="4"> - @@ -165,6 +190,7 @@ + diff --git a/src/UniGetUI/Pages/DialogPages/DesktopShortcuts.xaml.cs b/src/UniGetUI/Pages/DialogPages/DesktopShortcuts.xaml.cs index 756393c347..da5229fd0b 100644 --- a/src/UniGetUI/Pages/DialogPages/DesktopShortcuts.xaml.cs +++ b/src/UniGetUI/Pages/DialogPages/DesktopShortcuts.xaml.cs @@ -7,6 +7,8 @@ using Microsoft.UI.Xaml.Input; using UniGetUI.PackageEngine.Classes.Packages.Classes; using UniGetUI.Pages.DialogPages; +using UniGetUI.Core.SettingsEngine; +using UniGetUI.Core.Logging; // To learn more about WinUI, the WinUI project structure, // and more about our project templates, see: http://aka.ms/winui-project-info. @@ -19,81 +21,62 @@ namespace UniGetUI.Interface public sealed partial class DesktopShortcutsManager : Page { public event EventHandler? Close; - private readonly ObservableCollection desktopShortcuts = []; + private readonly ObservableCollection Shortcuts = []; - private readonly bool NewOnly; - - public DesktopShortcutsManager(List? NewShortcuts) + public DesktopShortcutsManager() { - if (NewShortcuts is not null) - { - NewOnly = true; - } - InitializeComponent(); - DeletableDesktopShortcutsList.ItemsSource = desktopShortcuts; - DeletableDesktopShortcutsList.DoubleTapped += DeletableDesktopShortcutsList_DoubleTapped; - UpdateData(NewShortcuts); + DeletableDesktopShortcutsList.ItemsSource = Shortcuts; + + AutoDeleteShortcutsCheckbox.IsChecked = Settings.Get("RemoveAllDesktopShortcuts"); + AutoDeleteShortcutsCheckbox.Checked += HandleAllDesktop_Checked; + AutoDeleteShortcutsCheckbox.Unchecked += HandleAllDesktop_Unchecked; } - private void UpdateData(List? NewShortcuts) + public void LoadShortcuts(IReadOnlyList NewShortcuts) { - desktopShortcuts.Clear(); - - if (NewShortcuts is not null) + Shortcuts.Clear(); + List items = new(); + foreach (var shortcut in NewShortcuts) { - foreach (var path in NewShortcuts) - { - desktopShortcuts.Add(new(path, false)); - } - } - else - { - foreach (var (shortcutPath, shortcutEnabled) in DesktopShortcutsDatabase.GetDatabase()) - { - var shortcutEntry = new ShortcutEntry(shortcutPath, shortcutEnabled); - desktopShortcuts.Add(shortcutEntry); - } + var status = DesktopShortcutsDatabase.GetStatus(shortcut); + var entry = new ShortcutEntry(shortcut, status is DesktopShortcutsDatabase.Status.Delete); + entry.OnReset += (_, _) => Shortcuts.Remove(entry); + items.Add(entry); } - foreach (var shortcut in desktopShortcuts) + foreach (var item in items.OrderBy(s => s.Name)) { - shortcut.OnReset += (sender, path) => - { - if (sender is not ShortcutEntry sh) - { - throw new InvalidOperationException(); - } - - DesktopShortcutsDatabase.ResetShortcut(sh.ShortcutPath); - desktopShortcuts.Remove(sh); - }; + Shortcuts.Add(item); } } - private void DeletableDesktopShortcutsList_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e) + /*private async void ManualScanButton_Click(object sender, RoutedEventArgs e) { - if (DeletableDesktopShortcutsList.SelectedItem is ShortcutEntry shortcut) + SaveChanges(); + var shortcutsOnDesktop = DesktopShortcutsDatabase.GetShortcutsOnDisk(); + List UnknownShortcuts = new(); + + foreach (var shortcut in shortcutsOnDesktop) { - shortcut.ResetConfiguration(); - desktopShortcuts.Remove(shortcut); + if(DesktopShortcutsDatabase.GetStatus(shortcut) is DesktopShortcutsDatabase.Status.Unknown) + { + UnknownShortcuts.Add(shortcut); + } } - } - - private async void ManualScanButton_Click(object sender, RoutedEventArgs e) - { - DesktopShortcutsDatabase.TryRemoveNewShortcuts([]); - Close?.Invoke(this, EventArgs.Empty); - var shortcuts = DesktopShortcutsDatabase.GetUnknownShortcuts(); - if (shortcuts.Any()) + if (UnknownShortcuts.Any()) { - await DialogHelper.ManageDesktopShortcuts(shortcuts); + LoadShortcuts(UnknownShortcuts); + ManualScanFlyout.Hide(); } else { - await DialogHelper.NoDesktopShortcutsFound(); + ManualScanFlyout.Hide(); + Close?.Invoke(this, EventArgs.Empty); + await DialogHelper.ManualScanDidNotFoundNewShortcuts(); + _ = DialogHelper.ManageDesktopShortcuts(); } - } + }*/ private void CloseButton_Click(object sender, RoutedEventArgs e) { @@ -102,11 +85,10 @@ private void CloseButton_Click(object sender, RoutedEventArgs e) private void YesResetButton_Click(object sender, RoutedEventArgs e) { - foreach (ShortcutEntry shortcut in desktopShortcuts.ToArray()) + foreach (ShortcutEntry shortcut in Shortcuts.ToArray()) { - shortcut.ResetConfiguration(); + shortcut.ResetShortcut(); } - desktopShortcuts.Clear(); ConfirmResetFlyout.Hide(); } @@ -115,54 +97,72 @@ private void NoResetButton_Click(object sender, RoutedEventArgs e) ConfirmResetFlyout.Hide(); } - public void SaveChangesAndClose() + private async void HandleAllDesktop_Checked(object sender, RoutedEventArgs e) { - Close?.Invoke(this, EventArgs.Empty); - foreach (var shortcut in desktopShortcuts) + SaveChanges(); + Close?.Invoke(this, new()); + await DialogHelper.ConfirmSetDeleteAllShortcutsSetting(); + await DialogHelper.ManageDesktopShortcuts(); + } + + private void HandleAllDesktop_Unchecked(object sender, RoutedEventArgs e) + { + Settings.Set("RemoveAllDesktopShortcuts", false); + } + + public void SaveChanges() + { + foreach (var shortcut in Shortcuts) { - DesktopShortcutsDatabase.AddToDatabase(shortcut.ShortcutPath, shortcut.IsChecked); - if (shortcut.IsChecked && File.Exists(shortcut.ShortcutPath)) + DesktopShortcutsDatabase.AddToDatabase(shortcut.Path, shortcut.IsDeletable? DesktopShortcutsDatabase.Status.Delete: DesktopShortcutsDatabase.Status.Maintain); + DesktopShortcutsDatabase.RemoveFromUnknownShortcuts(shortcut.Path); + + if (shortcut.IsDeletable && File.Exists(shortcut.Path)) { - DesktopShortcutsDatabase.DeleteFromDisk(shortcut.ShortcutPath); + DesktopShortcutsDatabase.DeleteFromDisk(shortcut.Path); } - DesktopShortcutsDatabase.RemoveFromUnknownShortcuts(shortcut.ShortcutPath); } } } public class ShortcutEntry : INotifyPropertyChanged { - public event EventHandler? OnReset; + public event EventHandler? OnReset; + + public string Path { get; } + public string Name { get; } + private bool _deletable; - public string ShortcutPath { get; } - private bool _enabled; - public bool IsChecked + public bool IsDeletable { - get => _enabled; + get => _deletable; set { - _enabled = value; + _deletable = value; OnPropertyChanged(); } } - public bool ShortcutExists + + public bool ExistsOnDisk { - get => File.Exists(ShortcutPath); + get => File.Exists(Path); } - public ShortcutEntry(string shortcutPath, bool enabled) + public ShortcutEntry(string path, bool isDeletable) { - ShortcutPath = shortcutPath; - IsChecked = enabled; + Path = path; + Name = string.Join('.', path.Split("\\")[^1].Split('.')[..^1]); + IsDeletable = isDeletable; } public void OpenShortcutPath() { - Process.Start("explorer.exe", "/select," + $"\"{ShortcutPath}\""); + Process.Start("explorer.exe", "/select," + $"\"{Path}\""); } - public void ResetConfiguration() + public void ResetShortcut() { + DesktopShortcutsDatabase.AddToDatabase(this.Path, DesktopShortcutsDatabase.Status.Unknown); OnReset?.Invoke(this, EventArgs.Empty); } @@ -172,17 +172,5 @@ protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } - - protected bool SetField(ref T field, T value, [CallerMemberName] string? propertyName = null) - { - if (EqualityComparer.Default.Equals(field, value)) - { - return false; - } - - field = value; - OnPropertyChanged(propertyName); - return true; - } } } diff --git a/src/UniGetUI/Pages/DialogPages/DialogHelper_Generic.cs b/src/UniGetUI/Pages/DialogPages/DialogHelper_Generic.cs index f36fe412e7..066e3601f4 100644 --- a/src/UniGetUI/Pages/DialogPages/DialogHelper_Generic.cs +++ b/src/UniGetUI/Pages/DialogPages/DialogHelper_Generic.cs @@ -283,18 +283,19 @@ public static async Task ManageIgnoredUpdates() await Window.ShowDialogAsync(dialog); } - public static async Task ManageDesktopShortcuts(List? NewShortucts = null) + public static async Task ManageDesktopShortcuts(IReadOnlyList? NewShortucts = null) { ContentDialog dialog = DialogFactory.Create(1400, 1000); - DesktopShortcutsManager DesktopShortcutsPage = new(NewShortucts); + DesktopShortcutsManager DesktopShortcutsPage = new(); + DesktopShortcutsPage.LoadShortcuts(NewShortucts ?? DesktopShortcutsDatabase.GetAllShortcuts()); DesktopShortcutsPage.Close += (_, _) => dialog.Hide(); dialog.Title = CoreTools.Translate("Automatic desktop shortcut remover"); dialog.Content = DesktopShortcutsPage; dialog.SecondaryButtonText = CoreTools.Translate("Save and close"); dialog.DefaultButton = ContentDialogButton.None; - dialog.SecondaryButtonClick += (_, _) => DesktopShortcutsPage.SaveChangesAndClose(); + dialog.SecondaryButtonClick += (_, _) => DesktopShortcutsPage.SaveChanges(); await Window.ShowDialogAsync(dialog); } @@ -588,13 +589,29 @@ public static void ShowTelemetryBanner() } - public static async Task NoDesktopShortcutsFound() + public static async Task ConfirmSetDeleteAllShortcutsSetting() + { + var dialog = DialogFactory.Create(); + dialog.Title = CoreTools.Translate("Are you sure you want to delete all shortcuts?"); + dialog.Content = CoreTools.Translate("Any new shorcuts created during an install or an update operation will be deleted automatically, instead of showing a confirmation prompt the first time they are detected.") + + " " + CoreTools.Translate("Any shorcuts created or modified outside of UniGetUI will be ignored. You will be able to add them via the {0} button.", $"{CoreTools.Translate("Manual scan")}") + + " " + CoreTools.Translate("Are you really sure you want to enable this feature?"); + dialog.PrimaryButtonText = CoreTools.Translate("Yes"); + dialog.CloseButtonText = CoreTools.Translate("No"); + dialog.DefaultButton = ContentDialogButton.Close; + if (await Window.ShowDialogAsync(dialog) is ContentDialogResult.Primary) + { + Settings.Set("RemoveAllDesktopShortcuts", true); + } + } + + /*public static async Task ManualScanDidNotFoundNewShortcuts() { var dialog = DialogFactory.Create(); dialog.Title = CoreTools.Translate("Manual scan"); dialog.Content = CoreTools.Translate("No new shortcuts were found during the scan."); - dialog.CloseButtonText = CoreTools.Translate("Close"); + dialog.PrimaryButtonText = CoreTools.Translate("Ok"); + dialog.DefaultButton = ContentDialogButton.Primary; await Window.ShowDialogAsync(dialog); - } + }*/ } - diff --git a/src/UniGetUI/UniGetUI.csproj b/src/UniGetUI/UniGetUI.csproj index 11c4ecba14..0f7e301dd0 100644 --- a/src/UniGetUI/UniGetUI.csproj +++ b/src/UniGetUI/UniGetUI.csproj @@ -81,9 +81,9 @@ - + - + diff --git a/src/WindowsPackageManager.Interop/ExternalLibraries.WindowsPackageManager.Interop.csproj b/src/WindowsPackageManager.Interop/ExternalLibraries.WindowsPackageManager.Interop.csproj index c991ff74bd..73fb151b3b 100644 --- a/src/WindowsPackageManager.Interop/ExternalLibraries.WindowsPackageManager.Interop.csproj +++ b/src/WindowsPackageManager.Interop/ExternalLibraries.WindowsPackageManager.Interop.csproj @@ -22,7 +22,7 @@ - + @@ -43,14 +43,14 @@ - Feed the $(TargetDir)\WINMD path to CsWinRT in order to generate the projected classes NOTE: Suppressing the warning only is not enough as this will cause CoreClrInitFailure (0x80008089) error. --> - + NU1701 true none false - + NU1701 true none @@ -59,6 +59,6 @@ - + diff --git a/src/WindowsPackageManager.Interop/WindowsPackageManager/WindowsPackageManagerElevatedFactory.cs b/src/WindowsPackageManager.Interop/WindowsPackageManager/WindowsPackageManagerElevatedFactory.cs index b3eb0c19ec..51f983a022 100644 --- a/src/WindowsPackageManager.Interop/WindowsPackageManager/WindowsPackageManagerElevatedFactory.cs +++ b/src/WindowsPackageManager.Interop/WindowsPackageManager/WindowsPackageManagerElevatedFactory.cs @@ -20,7 +20,7 @@ namespace WindowsPackageManager.Interop; /// This class is based on what the winget cmdlets do. See /// https://github.com/microsoft/winget-cli/blob/master/src/PowerShell/Microsoft.WinGet.Client/Helpers/ComObjectFactory.cs /// -public class WindowsPackageManagerElevatedFactory : WindowsPackageManagerFactory +/*public class WindowsPackageManagerElevatedFactory : WindowsPackageManagerFactory { // The only CLSID context supported by the DLL we call is Prod. // If we want to use Dev classes we have to use a Dev version of the DLL. @@ -56,4 +56,4 @@ private static extern unsafe int WinGetServerManualActivation_CreateInstance( in Guid iid, uint flags, out void* instance); -} +}*/