From 16c668784eabbf5a10d8faa32bff9f9efd6baedf Mon Sep 17 00:00:00 2001 From: Tom Deseyn Date: Mon, 29 Sep 2025 12:03:26 +0200 Subject: [PATCH 1/6] Fix hostfxr_get_available_sdks_result_fn array size type. (#340) This changes the array size type to 'int' so it matches the 'int32_t' native type. This was typed as an enum. The enum type is accepted by CoreCLR. Mono throws a MarshalDirectiveException because it requires the array size to be an integral type. --- src/MSBuildLocator/NativeMethods.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MSBuildLocator/NativeMethods.cs b/src/MSBuildLocator/NativeMethods.cs index 3a2b2371..6f1f3dcc 100644 --- a/src/MSBuildLocator/NativeMethods.cs +++ b/src/MSBuildLocator/NativeMethods.cs @@ -28,7 +28,7 @@ internal delegate void hostfxr_resolve_sdk2_result_fn( [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Auto)] internal delegate void hostfxr_get_available_sdks_result_fn( - hostfxr_resolve_sdk2_result_key_t key, + int sdk_count, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] string[] value); From ba5ddc1938aea0850761c45c12bc8156cebd8f20 Mon Sep 17 00:00:00 2001 From: Theodore Tsirpanis Date: Mon, 29 Sep 2025 13:08:00 +0300 Subject: [PATCH 2/6] Auto-generate binding redirects only when targeting .NET Framework. (#338) --- src/MSBuildLocator/build/Microsoft.Build.Locator.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MSBuildLocator/build/Microsoft.Build.Locator.props b/src/MSBuildLocator/build/Microsoft.Build.Locator.props index c84f551c..41dce9c6 100644 --- a/src/MSBuildLocator/build/Microsoft.Build.Locator.props +++ b/src/MSBuildLocator/build/Microsoft.Build.Locator.props @@ -1,6 +1,6 @@  - true + true From 6bbaaa5f19194601db8d6dd912d455badd0ab7c0 Mon Sep 17 00:00:00 2001 From: Theodore Tsirpanis Date: Tue, 30 Sep 2025 14:02:45 +0300 Subject: [PATCH 3/6] Modernize `DotNetSdkLocationHelper` and `hostfxr` interop. (#339) * Use framework API to resolve symlink. * Refactor hostfxr bindings and use the P/Invoke source generator. * Use newer APIs in `DotNetSdkLocationHelper`. * Use custom marshaller for auto-encoding strings. * Remove BOM. * Remove assertions inside native callbacks. * Some more cleanups. --- src/MSBuildLocator/DotNetSdkLocationHelper.cs | 57 +++------ .../Microsoft.Build.Locator.csproj | 1 + src/MSBuildLocator/NativeMethods.cs | 113 ++++++++++++++---- 3 files changed, 111 insertions(+), 60 deletions(-) diff --git a/src/MSBuildLocator/DotNetSdkLocationHelper.cs b/src/MSBuildLocator/DotNetSdkLocationHelper.cs index 58cb54d9..9c668d99 100644 --- a/src/MSBuildLocator/DotNetSdkLocationHelper.cs +++ b/src/MSBuildLocator/DotNetSdkLocationHelper.cs @@ -17,12 +17,13 @@ namespace Microsoft.Build.Locator { - internal static class DotNetSdkLocationHelper + internal static partial class DotNetSdkLocationHelper { - private static readonly Regex VersionRegex = new Regex(@"^(\d+)\.(\d+)\.(\d+)", RegexOptions.Multiline); - private static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); - private static readonly string ExeName = IsWindows ? "dotnet.exe" : "dotnet"; - private static readonly Lazy> s_dotnetPathCandidates = new(() => ResolveDotnetPathCandidates()); + [GeneratedRegex(@"^(\d+)\.(\d+)\.(\d+)", RegexOptions.Multiline)] + private static partial Regex VersionRegex(); + + private static string ExeName => OperatingSystem.IsWindows() ? "dotnet.exe" : "dotnet"; + private static readonly Lazy> s_dotnetPathCandidates = new(() => ResolveDotnetPathCandidates()); public static VisualStudioInstance? GetInstance(string dotNetSdkPath, bool allowQueryAllRuntimeVersions) { @@ -38,7 +39,7 @@ internal static class DotNetSdkLocationHelper } // Preview versions contain a hyphen after the numeric part of the version. Version.TryParse doesn't accept that. - Match versionMatch = VersionRegex.Match(File.ReadAllText(versionPath)); + Match versionMatch = VersionRegex().Match(File.ReadAllText(versionPath)); if (!versionMatch.Success) { @@ -116,10 +117,9 @@ public static IEnumerable GetInstances(string workingDirec static IEnumerable GetAllAvailableSDKs(bool allowAllDotnetLocations) { bool foundSdks = false; - string[]? resolvedPaths = null; foreach (string dotnetPath in s_dotnetPathCandidates.Value) { - int rc = NativeMethods.hostfxr_get_available_sdks(exe_dir: dotnetPath, result: (key, value) => resolvedPaths = value); + int rc = NativeMethods.hostfxr_get_available_sdks(exe_dir: dotnetPath, out string[]? resolvedPaths); if (rc == 0 && resolvedPaths != null) { @@ -150,13 +150,7 @@ static IEnumerable GetAllAvailableSDKs(bool allowAllDotnetLocations) string? resolvedSdk = null; foreach (string dotnetPath in s_dotnetPathCandidates.Value) { - int rc = NativeMethods.hostfxr_resolve_sdk2(exe_dir: dotnetPath, working_dir: workingDirectory, flags: 0, result: (key, value) => - { - if (key == NativeMethods.hostfxr_resolve_sdk2_result_key_t.resolved_sdk_dir) - { - resolvedSdk = value; - } - }); + int rc = NativeMethods.hostfxr_resolve_sdk2(exe_dir: dotnetPath, working_dir: workingDirectory, flags: 0, out resolvedSdk, out _); if (rc == 0) { @@ -178,7 +172,7 @@ static IEnumerable GetAllAvailableSDKs(bool allowAllDotnetLocations) private static void ModifyUnmanagedDllResolver(Action resolverAction) { // For Windows hostfxr is loaded in the process. - if (!IsWindows) + if (!OperatingSystem.IsWindows()) { var loadContext = AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()); if (loadContext != null) @@ -197,9 +191,9 @@ private static IntPtr HostFxrResolver(Assembly assembly, string libraryName) } string hostFxrLibName = - RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? + OperatingSystem.IsWindows() ? "hostfxr.dll" : - RuntimeInformation.IsOSPlatform(OSPlatform.OSX) ? "libhostfxr.dylib" : "libhostfxr.so"; + OperatingSystem.IsMacOS() ? "libhostfxr.dylib" : "libhostfxr.so"; string hostFxrRoot = string.Empty; // Get the dotnet path candidates @@ -237,12 +231,12 @@ private static IntPtr HostFxrResolver(Assembly assembly, string libraryName) private static string SdkResolutionExceptionMessage(string methodName) => $"Failed to find all versions of .NET Core MSBuild. Call to {methodName}. There may be more details in stderr."; - private static IList ResolveDotnetPathCandidates() + private static List ResolveDotnetPathCandidates() { var pathCandidates = new List(); AddIfValid(GetDotnetPathFromROOT()); - string? dotnetExePath = GetCurrentProcessPath(); + string? dotnetExePath = Environment.ProcessPath; bool isRunFromDotnetExecutable = !string.IsNullOrEmpty(dotnetExePath) && Path.GetFileName(dotnetExePath).Equals(ExeName, StringComparison.InvariantCultureIgnoreCase); @@ -254,9 +248,9 @@ private static IList ResolveDotnetPathCandidates() string? hostPath = Environment.GetEnvironmentVariable("DOTNET_HOST_PATH"); if (!string.IsNullOrEmpty(hostPath) && File.Exists(hostPath)) { - if (!IsWindows) + if (!OperatingSystem.IsWindows()) { - hostPath = realpath(hostPath) ?? hostPath; + hostPath = File.ResolveLinkTarget(hostPath, true)?.FullName ?? hostPath; } AddIfValid(Path.GetDirectoryName(hostPath)); @@ -289,8 +283,6 @@ void AddIfValid(string? path) return dotnetPath; } - private static string? GetCurrentProcessPath() => Environment.ProcessPath; - private static string? GetDotnetPathFromPATH() { string? dotnetPath = null; @@ -314,19 +306,6 @@ void AddIfValid(string? path) return dotnetPath; } - /// - /// This native method call determines the actual location of path, including - /// resolving symbolic links. - /// - private static string? realpath(string path) - { - IntPtr ptr = NativeMethods.realpath(path, IntPtr.Zero); - string? result = Marshal.PtrToStringAuto(ptr); - NativeMethods.free(ptr); - - return result; - } - private static string? FindDotnetPathFromEnvVariable(string environmentVariable) { string? dotnetPath = Environment.GetEnvironmentVariable(environmentVariable); @@ -347,9 +326,9 @@ private static void SetEnvironmentVariableIfEmpty(string name, string value) string fullPathToDotnetFromRoot = Path.Combine(dotnetPath, ExeName); if (File.Exists(fullPathToDotnetFromRoot)) { - if (!IsWindows) + if (!OperatingSystem.IsWindows()) { - fullPathToDotnetFromRoot = realpath(fullPathToDotnetFromRoot) ?? fullPathToDotnetFromRoot; + fullPathToDotnetFromRoot = File.ResolveLinkTarget(fullPathToDotnetFromRoot, true)?.FullName ?? fullPathToDotnetFromRoot; return File.Exists(fullPathToDotnetFromRoot) ? Path.GetDirectoryName(fullPathToDotnetFromRoot) : null; } diff --git a/src/MSBuildLocator/Microsoft.Build.Locator.csproj b/src/MSBuildLocator/Microsoft.Build.Locator.csproj index bdfe73d7..7308e50a 100644 --- a/src/MSBuildLocator/Microsoft.Build.Locator.csproj +++ b/src/MSBuildLocator/Microsoft.Build.Locator.csproj @@ -14,6 +14,7 @@ msbuildlocator;locator;buildlocator true 1.6.1 + true $(DefineConstants);FEATURE_VISUALSTUDIOSETUP diff --git a/src/MSBuildLocator/NativeMethods.cs b/src/MSBuildLocator/NativeMethods.cs index 6f1f3dcc..5072c7ab 100644 --- a/src/MSBuildLocator/NativeMethods.cs +++ b/src/MSBuildLocator/NativeMethods.cs @@ -1,12 +1,16 @@ // Copyright (c) Microsoft. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +#if NETCOREAPP using System; +using System.Diagnostics; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using System.Runtime.InteropServices.Marshalling; namespace Microsoft.Build.Locator { - internal class NativeMethods + internal partial class NativeMethods { internal const string HostFxrName = "hostfxr"; @@ -15,37 +19,104 @@ internal enum hostfxr_resolve_sdk2_flags_t disallow_prerelease = 0x1, }; - internal enum hostfxr_resolve_sdk2_result_key_t + private enum hostfxr_resolve_sdk2_result_key_t { resolved_sdk_dir = 0, global_json_path = 1, }; - [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Auto)] - internal delegate void hostfxr_resolve_sdk2_result_fn( - hostfxr_resolve_sdk2_result_key_t key, - string value); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = CharSet.Auto)] - internal delegate void hostfxr_get_available_sdks_result_fn( - int sdk_count, - [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] - string[] value); + internal static int hostfxr_resolve_sdk2(string exe_dir, string working_dir, hostfxr_resolve_sdk2_flags_t flags, out string resolved_sdk_dir, out string global_json_path) + { + Debug.Assert(t_resolve_sdk2_resolved_sdk_dir is null); + Debug.Assert(t_resolve_sdk2_global_json_path is null); + try + { + unsafe + { + int result = hostfxr_resolve_sdk2(exe_dir, working_dir, flags, &hostfxr_resolve_sdk2_callback); + resolved_sdk_dir = t_resolve_sdk2_resolved_sdk_dir; + global_json_path = t_resolve_sdk2_global_json_path; + return result; + } + } + finally + { + t_resolve_sdk2_resolved_sdk_dir = null; + t_resolve_sdk2_global_json_path = null; + } + } - [DllImport(HostFxrName, CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - internal static extern int hostfxr_resolve_sdk2( + [LibraryImport(HostFxrName, StringMarshallingCustomType = typeof(AutoStringMarshaller))] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + private static unsafe partial int hostfxr_resolve_sdk2( string exe_dir, string working_dir, hostfxr_resolve_sdk2_flags_t flags, - hostfxr_resolve_sdk2_result_fn result); + delegate* unmanaged[Cdecl] result); + + [ThreadStatic] + private static string t_resolve_sdk2_resolved_sdk_dir, t_resolve_sdk2_global_json_path; + + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])] + private static unsafe void hostfxr_resolve_sdk2_callback(hostfxr_resolve_sdk2_result_key_t key, void* value) + { + string str = AutoStringMarshaller.ConvertToManaged(value); + switch (key) + { + case hostfxr_resolve_sdk2_result_key_t.resolved_sdk_dir: + t_resolve_sdk2_resolved_sdk_dir = str; + break; + case hostfxr_resolve_sdk2_result_key_t.global_json_path: + t_resolve_sdk2_global_json_path = str; + break; + } + } + + internal static int hostfxr_get_available_sdks(string exe_dir, out string[] sdks) + { + Debug.Assert(t_get_available_sdks_result is null); + try + { + unsafe + { + int result = hostfxr_get_available_sdks(exe_dir, &hostfxr_get_available_sdks_callback); + sdks = t_get_available_sdks_result; + return result; + } + } + finally + { + t_get_available_sdks_result = null; + } + } + + [LibraryImport(HostFxrName, StringMarshallingCustomType = typeof(AutoStringMarshaller))] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + private static unsafe partial int hostfxr_get_available_sdks(string exe_dir, delegate* unmanaged[Cdecl] result); + + [ThreadStatic] + private static string[] t_get_available_sdks_result; - [DllImport(HostFxrName, 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); + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])] + private static unsafe void hostfxr_get_available_sdks_callback(int count, void** sdks) + { + string[] result = new string[count]; + for (int i = 0; i < count; i++) + { + result[i] = AutoStringMarshaller.ConvertToManaged(sdks[i]); + } + t_get_available_sdks_result = result; + } + + [CustomMarshaller(typeof(string), MarshalMode.Default, typeof(AutoStringMarshaller))] + internal static unsafe class AutoStringMarshaller + { + public static void* ConvertToUnmanaged(string s) => (void*)Marshal.StringToCoTaskMemAuto(s); - [DllImport("libc", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - internal static extern IntPtr realpath(string path, IntPtr buffer); + public static void Free(void* ptr) => Marshal.FreeCoTaskMem((nint)ptr); - [DllImport("libc", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] - internal static extern void free(IntPtr ptr); + public static string ConvertToManaged(void* ptr) => Marshal.PtrToStringAuto((nint)ptr); + } } } +#endif From 8acc4c3c0c5b15b95d5516647f04abc6fdd4ed16 Mon Sep 17 00:00:00 2001 From: Theodore Tsirpanis Date: Thu, 2 Oct 2025 16:38:24 +0300 Subject: [PATCH 4/6] Make SDK resolution error messages more helpful. (#341) * Make SDK resolution error messages more helpful. * Shorten exception message. --- src/MSBuildLocator/DotNetSdkLocationHelper.cs | 18 ++++--- src/MSBuildLocator/NativeMethods.cs | 49 ++++++++++++++++++- 2 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/MSBuildLocator/DotNetSdkLocationHelper.cs b/src/MSBuildLocator/DotNetSdkLocationHelper.cs index 9c668d99..7fa678f0 100644 --- a/src/MSBuildLocator/DotNetSdkLocationHelper.cs +++ b/src/MSBuildLocator/DotNetSdkLocationHelper.cs @@ -11,6 +11,7 @@ using System.Reflection; using System.Runtime.InteropServices; using System.Runtime.Loader; +using System.Text; using System.Text.RegularExpressions; #nullable enable @@ -117,11 +118,13 @@ public static IEnumerable GetInstances(string workingDirec static IEnumerable GetAllAvailableSDKs(bool allowAllDotnetLocations) { bool foundSdks = false; + int rc = 0; + StringBuilder? errorMessage = null; foreach (string dotnetPath in s_dotnetPathCandidates.Value) { - int rc = NativeMethods.hostfxr_get_available_sdks(exe_dir: dotnetPath, out string[]? resolvedPaths); + rc = NativeMethods.hostfxr_get_available_sdks(exe_dir: dotnetPath, out string[]? resolvedPaths, out errorMessage); - if (rc == 0 && resolvedPaths != null) + if (resolvedPaths != null) { foundSdks = true; @@ -140,7 +143,7 @@ static IEnumerable GetAllAvailableSDKs(bool allowAllDotnetLocations) // Errors are automatically printed to stderr. We should not continue to try to output anything if we failed. if (!foundSdks) { - throw new InvalidOperationException(SdkResolutionExceptionMessage(nameof(NativeMethods.hostfxr_get_available_sdks))); + throw new InvalidOperationException(SdkResolutionExceptionMessage(nameof(NativeMethods.hostfxr_get_available_sdks), rc, errorMessage)); } } @@ -148,9 +151,11 @@ static IEnumerable GetAllAvailableSDKs(bool allowAllDotnetLocations) static string? GetSdkFromGlobalSettings(string workingDirectory) { string? resolvedSdk = null; + int rc = 0; + StringBuilder? errorMessage = null; foreach (string dotnetPath in s_dotnetPathCandidates.Value) { - int rc = NativeMethods.hostfxr_resolve_sdk2(exe_dir: dotnetPath, working_dir: workingDirectory, flags: 0, out resolvedSdk, out _); + rc = NativeMethods.hostfxr_resolve_sdk2(exe_dir: dotnetPath, working_dir: workingDirectory, flags: 0, out resolvedSdk, out _, out errorMessage); if (rc == 0) { @@ -160,7 +165,7 @@ static IEnumerable GetAllAvailableSDKs(bool allowAllDotnetLocations) } return string.IsNullOrEmpty(resolvedSdk) - ? throw new InvalidOperationException(SdkResolutionExceptionMessage(nameof(NativeMethods.hostfxr_resolve_sdk2))) + ? throw new InvalidOperationException(SdkResolutionExceptionMessage(nameof(NativeMethods.hostfxr_resolve_sdk2), rc, errorMessage)) : resolvedSdk; } } @@ -229,7 +234,8 @@ private static IntPtr HostFxrResolver(Assembly assembly, string libraryName) throw new InvalidOperationException(error); } - private static string SdkResolutionExceptionMessage(string methodName) => $"Failed to find all versions of .NET Core MSBuild. Call to {methodName}. There may be more details in stderr."; + private static string SdkResolutionExceptionMessage(string methodName, int rc, StringBuilder? errorMessage) => + $"Error while calling hostfxr function {methodName}. Error code: {rc} Detailed error: {errorMessage}"; private static List ResolveDotnetPathCandidates() { diff --git a/src/MSBuildLocator/NativeMethods.cs b/src/MSBuildLocator/NativeMethods.cs index 5072c7ab..f3582713 100644 --- a/src/MSBuildLocator/NativeMethods.cs +++ b/src/MSBuildLocator/NativeMethods.cs @@ -7,6 +7,7 @@ using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.Marshalling; +using System.Text; namespace Microsoft.Build.Locator { @@ -25,7 +26,7 @@ private enum hostfxr_resolve_sdk2_result_key_t global_json_path = 1, }; - internal static int hostfxr_resolve_sdk2(string exe_dir, string working_dir, hostfxr_resolve_sdk2_flags_t flags, out string resolved_sdk_dir, out string global_json_path) + internal static int hostfxr_resolve_sdk2(string exe_dir, string working_dir, hostfxr_resolve_sdk2_flags_t flags, out string resolved_sdk_dir, out string global_json_path, out StringBuilder errorMessage) { Debug.Assert(t_resolve_sdk2_resolved_sdk_dir is null); Debug.Assert(t_resolve_sdk2_global_json_path is null); @@ -33,9 +34,11 @@ internal static int hostfxr_resolve_sdk2(string exe_dir, string working_dir, hos { unsafe { + using var errorHandler = new ErrorHandler(); int result = hostfxr_resolve_sdk2(exe_dir, working_dir, flags, &hostfxr_resolve_sdk2_callback); resolved_sdk_dir = t_resolve_sdk2_resolved_sdk_dir; global_json_path = t_resolve_sdk2_global_json_path; + errorMessage = t_hostfxr_error_builder; return result; } } @@ -72,15 +75,17 @@ private static unsafe void hostfxr_resolve_sdk2_callback(hostfxr_resolve_sdk2_re } } - internal static int hostfxr_get_available_sdks(string exe_dir, out string[] sdks) + internal static int hostfxr_get_available_sdks(string exe_dir, out string[] sdks, out StringBuilder errorMessage) { Debug.Assert(t_get_available_sdks_result is null); try { unsafe { + using var errorHandler = new ErrorHandler(); int result = hostfxr_get_available_sdks(exe_dir, &hostfxr_get_available_sdks_callback); sdks = t_get_available_sdks_result; + errorMessage = t_hostfxr_error_builder; return result; } } @@ -108,6 +113,29 @@ private static unsafe void hostfxr_get_available_sdks_callback(int count, void** t_get_available_sdks_result = result; } + [LibraryImport(HostFxrName)] + [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] + private static unsafe partial delegate* unmanaged[Cdecl] hostfxr_set_error_writer(delegate* unmanaged[Cdecl] error_writer); + + [ThreadStatic] + private static StringBuilder t_hostfxr_error_builder; + + [UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])] + private static unsafe void hostfxr_error_writer_callback(void* message) + { + t_hostfxr_error_builder ??= new StringBuilder(); + if (OperatingSystem.IsWindows()) + { + // Avoid allocating temporary string on Windows. + t_hostfxr_error_builder.Append(MemoryMarshal.CreateReadOnlySpanFromNullTerminated((char*)message)); + t_hostfxr_error_builder.AppendLine(); + } + else + { + t_hostfxr_error_builder.AppendLine(Utf8StringMarshaller.ConvertToManaged((byte*)message)); + } + } + [CustomMarshaller(typeof(string), MarshalMode.Default, typeof(AutoStringMarshaller))] internal static unsafe class AutoStringMarshaller { @@ -117,6 +145,23 @@ internal static unsafe class AutoStringMarshaller public static string ConvertToManaged(void* ptr) => Marshal.PtrToStringAuto((nint)ptr); } + + private unsafe readonly ref struct ErrorHandler + { + private readonly delegate* unmanaged[Cdecl] _previousCallback; + + public ErrorHandler() + { + Debug.Assert(t_hostfxr_error_builder is null); + _previousCallback = hostfxr_set_error_writer(&hostfxr_error_writer_callback); + } + + public void Dispose() + { + hostfxr_set_error_writer(_previousCallback); + t_hostfxr_error_builder = null; + } + } } } #endif From 097f57d41185701fb9206144f11f57014178a9e9 Mon Sep 17 00:00:00 2001 From: YuliiaKovalova <95473390+YuliiaKovalova@users.noreply.github.com> Date: Thu, 2 Oct 2025 15:51:33 +0200 Subject: [PATCH 5/6] Bump version from 1.9 to 1.10 (#343) --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.json b/version.json index 688d797c..17543530 100644 --- a/version.json +++ b/version.json @@ -1,5 +1,5 @@ { - "version": "1.9", + "version": "1.10", "assemblyVersion": "1.0.0.0", "publicReleaseRefSpec": [ "^refs/heads/release/.*" From 694ff392b2dcf6ac58fe865afd1c982eb9449014 Mon Sep 17 00:00:00 2001 From: YuliiaKovalova <95473390+YuliiaKovalova@users.noreply.github.com> Date: Thu, 2 Oct 2025 18:23:57 +0200 Subject: [PATCH 6/6] Update MicroBuildSigningPlugin version and parameters (#345) * Update MicroBuildSigningPlugin version and parameters * Update MicroBuild plugin configuration in pipeline --- azure-pipelines.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 6e1123d9..860e7417 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -59,10 +59,15 @@ extends: artifactName: logs condition: succeededOrFailed() steps: - - task: MicroBuildSigningPlugin@1 + - task: MicroBuildSigningPlugin@4 + displayName: Install MicroBuild plugin inputs: - signType: '$(SignType)' + signType: 'real' zipSources: true + feedSource: https://devdiv.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json + ConnectedPMEServiceName: 6cc74545-d7b9-4050-9dfa-ebefcc8961ea + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) - task: MSBuild@1 displayName: '/t:Pack' @@ -107,4 +112,4 @@ extends: TargetFolder: '$(Build.ArtifactStagingDirectory)\logs' - task: ms-vseng.MicroBuildTasks.521a94ea-9e68-468a-8167-6dcf361ea776.MicroBuildCleanup@1 - displayName: 'Execute cleanup tasks' \ No newline at end of file + displayName: 'Execute cleanup tasks'