diff --git a/src/dotnet-bootstrapper/BootstrapperCommandParser.cs b/src/dotnet-bootstrapper/BootstrapperCommandParser.cs index e754a6ae..547300f9 100644 --- a/src/dotnet-bootstrapper/BootstrapperCommandParser.cs +++ b/src/dotnet-bootstrapper/BootstrapperCommandParser.cs @@ -1,12 +1,19 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using System.Collections; +using System.Collections.Generic; using System.CommandLine; using System.CommandLine.Builder; +using System.CommandLine.Help; using System.CommandLine.Invocation; using System.CommandLine.Parsing; +using System.IO; +using System.Linq; using System.Reflection; +using System.Runtime.InteropServices; +using System.Text.Json; namespace Microsoft.DotNet.Tools.Bootstrapper { @@ -16,34 +23,195 @@ internal static class BootstrapperCommandParser public static RootCommand BootstrapperRootCommand = new RootCommand("dotnet bootstrapper"); - public static readonly Command VersionCommand = new Command("--version"); + public static readonly Command VersionCommand = new("--version") + { + Handler = CommandHandler.Create(() => + { + Assembly assembly = Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly(); + Console.WriteLine(assembly.GetCustomAttribute()?.InformationalVersion ?? assembly.GetName().Version.ToString()); + }) + }; + + public static readonly Command HelpCommand = new("--help") + { + Handler = CommandHandler.Create(() => + { + Console.WriteLine(LocalizableStrings.BootstrapperHelp); + }) + }; + + public static readonly Command ListCommand = new("list", LocalizableStrings.ListCommandDescription) + { + Handler = CommandHandler.Create((ParseResult parseResult) => + { + string dotnetDir = FindLocalDotnet(parseResult.ValueForOption(DotnetPath)); + if (dotnetDir is null) + { + Console.WriteLine("dotnet executable not found. Ensure you execute this command from a directory with it."); + return; + } + + foreach (string s in FindLocalSDKs(dotnetDir)) + { + Console.WriteLine(s); + } + }) + }; - private static readonly Lazy _assemblyVersion = - new Lazy(() => + public static readonly Command UninstallCommand = new("uninstall", LocalizableStrings.UninstallCommandDescription) + { + Handler = CommandHandler.Create((ParseResult parseResult) => { - var assembly = Assembly.GetEntryAssembly() ?? Assembly.GetExecutingAssembly(); - var assemblyVersionAttribute = assembly.GetCustomAttribute(); - if (assemblyVersionAttribute == null) + string dotnetDir = FindLocalDotnet(parseResult.ValueForOption(DotnetPath)); + if (dotnetDir is null) + { + Console.WriteLine("dotnet executable not found. Ensure you execute this command from a directory with it."); + return; + } + + string sdkToUninstall = parseResult.ValueForArgument(UninstallArgument); + + IEnumerable localSdks = FindLocalSDKs(dotnetDir).Where(sdk => sdk.EndsWith("foo")); + if (!localSdks.Any()) + { + Console.WriteLine("Failed to find SDK " + "foo"); + return; + } + + string sdkFolder = Path.Combine(Path.GetDirectoryName(dotnetDir), "sdk"); + foreach (string sdk in localSdks) { - return assembly.GetName().Version.ToString(); + Console.WriteLine("Deleting SDK " + sdk); + Directory.Delete(sdk, recursive: true); } - else + }) + }; + + public static readonly Command InstallCommand = new("install", LocalizableStrings.InstallCommandDescription) + { + Handler = CommandHandler.Create((ParseResult parseResult) => + { + string dotnetDir = FindLocalDotnet(parseResult.ValueForOption(DotnetPath)); + if (dotnetDir is null) { - return assemblyVersionAttribute.InformationalVersion; + // install dotnet.exe } - }); + }) + }; + + public static readonly Argument UninstallArgument = new() + { + Name = "uninstall", + Arity = ArgumentArity.ExactlyOne + }; + + public static readonly Option DotnetPath = new("--dotnetPath", getDefaultValue: () => null); + + internal enum hostfxr_resolve_sdk2_result_key_t + { + resolved_sdk_dir = 0, + global_json_path = 1, + }; + + [DllImport("hostfxr", CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] + internal static extern int hostfxr_get_available_sdks(string exe_dir, hostfxr_get_available_sdks_result_fn result); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Auto)] + internal delegate void hostfxr_get_available_sdks_result_fn( + hostfxr_resolve_sdk2_result_key_t key, + [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] + string[] value); + + private static string[] FindLocalSDKs(string dotnetDir) + { + string[] resolvedPaths = null; + int returnCode = hostfxr_get_available_sdks(exe_dir: dotnetDir, result: (key, value) => resolvedPaths = value); + if (returnCode == 0) + { + return resolvedPaths ?? []; + } + else + { + throw new InvalidOperationException("Failed to find SDKs"); + } + } + + private static string FindLocalDotnet(string pathFromSwitch) + { + if (pathFromSwitch is not null) + { + string pathToDotnet = CheckFile(pathFromSwitch) ?? pathFromSwitch; + if (!File.Exists(pathToDotnet)) + { + throw new ArgumentException($"Path {pathFromSwitch} does not lead to the dotnet executable."); + } + + return pathToDotnet; + } + + string currentDirectory = Directory.GetCurrentDirectory(); + + string path = FindAndParseGlobalJson(currentDirectory); + if (path is not null) + { + return path; + } + + return CheckFile(currentDirectory) ?? + CheckFile(Path.GetDirectoryName(currentDirectory)) ?? + Directory.GetDirectories(currentDirectory).SelectMany(subdirectory => + { + if (CheckFile(subdirectory) is string subDotnet) + { + return [subDotnet]; + } + + return Directory.GetDirectories(subdirectory).Select(CheckFile); + }).FirstOrDefault(path => path is not null); + } + + private static string FindAndParseGlobalJson(string startingDirectory) + { + string currentDirectory = startingDirectory; + string globalJsonPath = Path.Combine(currentDirectory, "global.json"); + while (!File.Exists(globalJsonPath)) + { + startingDirectory = Path.GetDirectoryName(startingDirectory); + if (startingDirectory is null) + { + return null; + } + + globalJsonPath = Path.Combine(currentDirectory, "global.json"); + } + + JsonDocument jsonDocument = JsonDocument.Parse(globalJsonPath); + jsonDocument.RootElement. + } + + private static string CheckFile(string directory) + { + string fileToCheck = Path.Combine(directory, "dotnet.exe"); + return File.Exists(fileToCheck) ? fileToCheck : null; + } static BootstrapperCommandParser() { BootstrapperRootCommand.AddCommand(VersionCommand); - VersionCommand.Handler = CommandHandler.Create(() => - { - Console.WriteLine(_assemblyVersion.Value); - }); + BootstrapperRootCommand.AddCommand(HelpCommand); + BootstrapperRootCommand.AddCommand(ListCommand); + BootstrapperRootCommand.AddCommand(UninstallCommand); + BootstrapperRootCommand.AddCommand(InstallCommand); + + ListCommand.AddOption(DotnetPath); + UninstallCommand.AddOption(DotnetPath); + InstallCommand.AddOption(DotnetPath); + + UninstallCommand.AddArgument(UninstallArgument); BootstrapParser = new CommandLineBuilder(BootstrapperRootCommand) .UseDefaults() - // .UseHelpBuilder(context => new UninstallHelpBuilder(context.Console)) + .UseHelpBuilder(context => new HelpBuilder(context.Console)) .Build(); } } diff --git a/src/dotnet-bootstrapper/LocalizableStrings.Designer.cs b/src/dotnet-bootstrapper/LocalizableStrings.Designer.cs new file mode 100644 index 00000000..85bffac8 --- /dev/null +++ b/src/dotnet-bootstrapper/LocalizableStrings.Designer.cs @@ -0,0 +1,90 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.DotNet.Tools.Bootstrapper { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class LocalizableStrings { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal LocalizableStrings() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.DotNet.Tools.Bootstrapper.LocalizableStrings", typeof(LocalizableStrings).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Bootstrapper help text. + /// + internal static string BootstrapperHelp { + get { + return ResourceManager.GetString("BootstrapperHelp", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to List out all currently installed SDKs.. + /// + internal static string ListCommandDescription { + get { + return ResourceManager.GetString("ListCommandDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Uninstall the specified SDK.. + /// + internal static string UninstallCommandDescription { + get { + return ResourceManager.GetString("UninstallCommandDescription", resourceCulture); + } + } + } +} diff --git a/src/dotnet-bootstrapper/LocalizableStrings.resx b/src/dotnet-bootstrapper/LocalizableStrings.resx index 8b2ff64a..e7a9b618 100644 --- a/src/dotnet-bootstrapper/LocalizableStrings.resx +++ b/src/dotnet-bootstrapper/LocalizableStrings.resx @@ -1,17 +1,17 @@  - @@ -117,4 +117,13 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Bootstrapper help text + + + List out all currently installed SDKs. + + + Uninstall the specified SDK. + \ No newline at end of file diff --git a/src/dotnet-bootstrapper/dotnet-bootstrapper.csproj b/src/dotnet-bootstrapper/dotnet-bootstrapper.csproj index 3c081deb..a4a49cbc 100644 --- a/src/dotnet-bootstrapper/dotnet-bootstrapper.csproj +++ b/src/dotnet-bootstrapper/dotnet-bootstrapper.csproj @@ -3,12 +3,11 @@ dotnet-bootstrapper Exe true + win-x86;osx-x64;osx-arm64 true net8.0 true true - false - true true true LatestMajor @@ -17,6 +16,7 @@ preview Microsoft.DotNet.Tools.Bootstrapper + Microsoft.DotNet.Tools.Bootstrapper diff --git a/src/dotnet-bootstrapper/xlf/LocalizableStrings.cs.xlf b/src/dotnet-bootstrapper/xlf/LocalizableStrings.cs.xlf index e028ecc8..6424f74b 100644 --- a/src/dotnet-bootstrapper/xlf/LocalizableStrings.cs.xlf +++ b/src/dotnet-bootstrapper/xlf/LocalizableStrings.cs.xlf @@ -1,6 +1,22 @@  - + + + Bootstrapper help text + Bootstrapper help text + + + + List out all currently installed SDKs. + List out all currently installed SDKs. + + + + Uninstall the specified SDK. + Uninstall the specified SDK. + + + \ No newline at end of file diff --git a/src/dotnet-bootstrapper/xlf/LocalizableStrings.de.xlf b/src/dotnet-bootstrapper/xlf/LocalizableStrings.de.xlf index 02f57c3c..55485d8f 100644 --- a/src/dotnet-bootstrapper/xlf/LocalizableStrings.de.xlf +++ b/src/dotnet-bootstrapper/xlf/LocalizableStrings.de.xlf @@ -1,6 +1,22 @@  - + + + Bootstrapper help text + Bootstrapper help text + + + + List out all currently installed SDKs. + List out all currently installed SDKs. + + + + Uninstall the specified SDK. + Uninstall the specified SDK. + + + \ No newline at end of file diff --git a/src/dotnet-bootstrapper/xlf/LocalizableStrings.es.xlf b/src/dotnet-bootstrapper/xlf/LocalizableStrings.es.xlf index bd51c90f..85c8c3e5 100644 --- a/src/dotnet-bootstrapper/xlf/LocalizableStrings.es.xlf +++ b/src/dotnet-bootstrapper/xlf/LocalizableStrings.es.xlf @@ -1,6 +1,22 @@  - + + + Bootstrapper help text + Bootstrapper help text + + + + List out all currently installed SDKs. + List out all currently installed SDKs. + + + + Uninstall the specified SDK. + Uninstall the specified SDK. + + + \ No newline at end of file diff --git a/src/dotnet-bootstrapper/xlf/LocalizableStrings.fr.xlf b/src/dotnet-bootstrapper/xlf/LocalizableStrings.fr.xlf index 353aa168..a5c8fc49 100644 --- a/src/dotnet-bootstrapper/xlf/LocalizableStrings.fr.xlf +++ b/src/dotnet-bootstrapper/xlf/LocalizableStrings.fr.xlf @@ -1,6 +1,22 @@  - + + + Bootstrapper help text + Bootstrapper help text + + + + List out all currently installed SDKs. + List out all currently installed SDKs. + + + + Uninstall the specified SDK. + Uninstall the specified SDK. + + + \ No newline at end of file diff --git a/src/dotnet-bootstrapper/xlf/LocalizableStrings.it.xlf b/src/dotnet-bootstrapper/xlf/LocalizableStrings.it.xlf index 8521fc88..a619fc37 100644 --- a/src/dotnet-bootstrapper/xlf/LocalizableStrings.it.xlf +++ b/src/dotnet-bootstrapper/xlf/LocalizableStrings.it.xlf @@ -1,6 +1,22 @@  - + + + Bootstrapper help text + Bootstrapper help text + + + + List out all currently installed SDKs. + List out all currently installed SDKs. + + + + Uninstall the specified SDK. + Uninstall the specified SDK. + + + \ No newline at end of file diff --git a/src/dotnet-bootstrapper/xlf/LocalizableStrings.ja.xlf b/src/dotnet-bootstrapper/xlf/LocalizableStrings.ja.xlf index a4bdbd56..ff133c70 100644 --- a/src/dotnet-bootstrapper/xlf/LocalizableStrings.ja.xlf +++ b/src/dotnet-bootstrapper/xlf/LocalizableStrings.ja.xlf @@ -1,6 +1,22 @@  - + + + Bootstrapper help text + Bootstrapper help text + + + + List out all currently installed SDKs. + List out all currently installed SDKs. + + + + Uninstall the specified SDK. + Uninstall the specified SDK. + + + \ No newline at end of file diff --git a/src/dotnet-bootstrapper/xlf/LocalizableStrings.ko.xlf b/src/dotnet-bootstrapper/xlf/LocalizableStrings.ko.xlf index dfe7ff8c..5aa7b3bd 100644 --- a/src/dotnet-bootstrapper/xlf/LocalizableStrings.ko.xlf +++ b/src/dotnet-bootstrapper/xlf/LocalizableStrings.ko.xlf @@ -1,6 +1,22 @@  - + + + Bootstrapper help text + Bootstrapper help text + + + + List out all currently installed SDKs. + List out all currently installed SDKs. + + + + Uninstall the specified SDK. + Uninstall the specified SDK. + + + \ No newline at end of file diff --git a/src/dotnet-bootstrapper/xlf/LocalizableStrings.pl.xlf b/src/dotnet-bootstrapper/xlf/LocalizableStrings.pl.xlf index edb8d7de..16856889 100644 --- a/src/dotnet-bootstrapper/xlf/LocalizableStrings.pl.xlf +++ b/src/dotnet-bootstrapper/xlf/LocalizableStrings.pl.xlf @@ -1,6 +1,22 @@  - + + + Bootstrapper help text + Bootstrapper help text + + + + List out all currently installed SDKs. + List out all currently installed SDKs. + + + + Uninstall the specified SDK. + Uninstall the specified SDK. + + + \ No newline at end of file diff --git a/src/dotnet-bootstrapper/xlf/LocalizableStrings.pt-BR.xlf b/src/dotnet-bootstrapper/xlf/LocalizableStrings.pt-BR.xlf index 616bbc89..f42d8714 100644 --- a/src/dotnet-bootstrapper/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/dotnet-bootstrapper/xlf/LocalizableStrings.pt-BR.xlf @@ -1,6 +1,22 @@  - + + + Bootstrapper help text + Bootstrapper help text + + + + List out all currently installed SDKs. + List out all currently installed SDKs. + + + + Uninstall the specified SDK. + Uninstall the specified SDK. + + + \ No newline at end of file diff --git a/src/dotnet-bootstrapper/xlf/LocalizableStrings.ru.xlf b/src/dotnet-bootstrapper/xlf/LocalizableStrings.ru.xlf index 8e47a5f3..e723ebec 100644 --- a/src/dotnet-bootstrapper/xlf/LocalizableStrings.ru.xlf +++ b/src/dotnet-bootstrapper/xlf/LocalizableStrings.ru.xlf @@ -1,6 +1,22 @@  - + + + Bootstrapper help text + Bootstrapper help text + + + + List out all currently installed SDKs. + List out all currently installed SDKs. + + + + Uninstall the specified SDK. + Uninstall the specified SDK. + + + \ No newline at end of file diff --git a/src/dotnet-bootstrapper/xlf/LocalizableStrings.tr.xlf b/src/dotnet-bootstrapper/xlf/LocalizableStrings.tr.xlf index 770cdf4a..9b43f0a4 100644 --- a/src/dotnet-bootstrapper/xlf/LocalizableStrings.tr.xlf +++ b/src/dotnet-bootstrapper/xlf/LocalizableStrings.tr.xlf @@ -1,6 +1,22 @@  - + + + Bootstrapper help text + Bootstrapper help text + + + + List out all currently installed SDKs. + List out all currently installed SDKs. + + + + Uninstall the specified SDK. + Uninstall the specified SDK. + + + \ No newline at end of file diff --git a/src/dotnet-bootstrapper/xlf/LocalizableStrings.zh-Hans.xlf b/src/dotnet-bootstrapper/xlf/LocalizableStrings.zh-Hans.xlf index 1832bb6c..6ddf01bf 100644 --- a/src/dotnet-bootstrapper/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/dotnet-bootstrapper/xlf/LocalizableStrings.zh-Hans.xlf @@ -1,6 +1,22 @@  - + + + Bootstrapper help text + Bootstrapper help text + + + + List out all currently installed SDKs. + List out all currently installed SDKs. + + + + Uninstall the specified SDK. + Uninstall the specified SDK. + + + \ No newline at end of file diff --git a/src/dotnet-bootstrapper/xlf/LocalizableStrings.zh-Hant.xlf b/src/dotnet-bootstrapper/xlf/LocalizableStrings.zh-Hant.xlf index 4a6c48aa..554bda39 100644 --- a/src/dotnet-bootstrapper/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/dotnet-bootstrapper/xlf/LocalizableStrings.zh-Hant.xlf @@ -1,6 +1,22 @@  - + + + Bootstrapper help text + Bootstrapper help text + + + + List out all currently installed SDKs. + List out all currently installed SDKs. + + + + Uninstall the specified SDK. + Uninstall the specified SDK. + + + \ No newline at end of file diff --git a/src/dotnet-core-uninstall/Shared/Configs/CommandLineConfigs.cs b/src/dotnet-core-uninstall/Shared/Configs/CommandLineConfigs.cs index 863b07c8..23935d08 100644 --- a/src/dotnet-core-uninstall/Shared/Configs/CommandLineConfigs.cs +++ b/src/dotnet-core-uninstall/Shared/Configs/CommandLineConfigs.cs @@ -20,7 +20,7 @@ namespace Microsoft.DotNet.Tools.Uninstall.Shared.Configs { - internal static class CommandLineConfigs + public static class CommandLineConfigs { public static Parser UninstallCommandParser; @@ -28,6 +28,7 @@ internal static class CommandLineConfigs private static readonly string DryRunCommandName = "dry-run"; private static readonly string WhatIfCommandName = "whatif"; private static readonly string RemoveCommandName = "remove"; + private static readonly string UninstallCommandName = "uninstall"; public static readonly RootCommand UninstallRootCommand = new RootCommand( RuntimeInfo.RunningOnWindows ? LocalizableStrings.UninstallNoOptionDescriptionWindows @@ -184,7 +185,7 @@ internal static class CommandLineConfigs ForceOption }; - public static readonly Dictionary VerbosityLevels = new Dictionary + internal static readonly Dictionary VerbosityLevels = new Dictionary { { "q", VerbosityLevel.Quiet }, { "quiet", VerbosityLevel.Quiet }, { "m", VerbosityLevel.Minimal }, { "minimal", VerbosityLevel.Minimal }, @@ -220,6 +221,7 @@ static CommandLineConfigs() UninstallRootCommand.AddCommand(ListCommand); UninstallRootCommand.AddCommand(DryRunCommand); UninstallRootCommand.AddCommand(RemoveCommand); + RemoveCommand.AddAlias(UninstallCommandName); // The verbiage that makes the most sense from the bootstrapper would be 'uninstall', so just adding an alias permits more code sharing UninstallRootCommand.AddCommand(VersionSubcommand); if (RuntimeInfo.RunningOnOSX) @@ -312,7 +314,7 @@ public static Option GetUninstallMainOption(this CommandResult commandResult) return specifiedOption; } - public static BundleType GetTypeSelection(this ParseResult parseResult) + internal static BundleType GetTypeSelection(this ParseResult parseResult) { var supportedBundleTypes = SupportedBundleTypeConfigs.GetSupportedBundleTypes(); @@ -326,7 +328,7 @@ public static BundleType GetTypeSelection(this ParseResult parseResult) typeSelection; } - public static BundleArch GetArchSelection(this ParseResult parseResult) + internal static BundleArch GetArchSelection(this ParseResult parseResult) { var archSelection = new[] { @@ -343,7 +345,7 @@ public static BundleArch GetArchSelection(this ParseResult parseResult) archSelection; } - public static VerbosityLevel GetVerbosityLevel(this CommandResult commandResult) + internal static VerbosityLevel GetVerbosityLevel(this CommandResult commandResult) { var optionResult = commandResult.FindResultFor(VerbosityOption); diff --git a/src/dotnet-core-uninstall/Shared/Exceptions/ExceptionHandler.cs b/src/dotnet-core-uninstall/Shared/Exceptions/ExceptionHandler.cs index 2497d18e..ec6007de 100644 --- a/src/dotnet-core-uninstall/Shared/Exceptions/ExceptionHandler.cs +++ b/src/dotnet-core-uninstall/Shared/Exceptions/ExceptionHandler.cs @@ -9,11 +9,11 @@ internal static class ExceptionHandler { public static Action HandleException(Action action) { - return (x) => + return x => { try { - action.Invoke(x); + action(x); } catch (DotNetUninstallException e) { diff --git a/src/dotnet-core-uninstall/dotnet-core-uninstall.csproj b/src/dotnet-core-uninstall/dotnet-core-uninstall.csproj index fd483523..5f61daa7 100644 --- a/src/dotnet-core-uninstall/dotnet-core-uninstall.csproj +++ b/src/dotnet-core-uninstall/dotnet-core-uninstall.csproj @@ -2,6 +2,7 @@ dotnet-core-uninstall Exe + true win-x86;osx-x64;osx-arm64 true net8.0