Skip to content

Commit 8f5ca8f

Browse files
authored
Re-enable telemetry for global.json state - set error writer to swallow expected error messages (#51089)
When getting the global.json state for telemetry, we avoid the work to actually resolve an SDK. However, this means that the actual SDK resolution (`hostfxr_resolve_sdk2`) fails, resulting in messages printed to stderr by default. This change uses `hostfxr_set_error_writer` to swallow the expected errors for the duration of that call.
1 parent 347c68a commit 8f5ca8f

File tree

3 files changed

+28
-5
lines changed

3 files changed

+28
-5
lines changed

src/Cli/dotnet/Program.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,7 @@ internal static int ProcessArgs(string[] args, TimeSpan startupTime)
240240
if (TelemetryClient.Enabled)
241241
{
242242
// Get the global.json state to report in telemetry along with this command invocation.
243-
// We don't care about the actual SDK resolution, just the global.json information,
244-
// so just pass empty string as executable directory for resolution.
245-
// NativeWrapper.SdkResolutionResult result = NativeWrapper.NETCoreSdkResolverNativeWrapper.ResolveSdk(string.Empty, Environment.CurrentDirectory);
246-
// globalJsonState = result.GlobalJsonState;
243+
globalJsonState = NativeWrapper.NETCoreSdkResolverNativeWrapper.GetGlobalJsonState(Environment.CurrentDirectory);
247244
}
248245

249246
TelemetryEventEntry.SendFiltered(Tuple.Create(parseResult, performanceData, globalJsonState));

src/Resolvers/Microsoft.DotNet.NativeWrapper/Interop.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ static Interop()
2828
}
2929

3030
// MSBuild SDK resolvers are required to be AnyCPU, but we have a native dependency and .NETFramework does not
31-
// have a built-in facility for dynamically loading user native dlls for the appropriate platform. We therefore
31+
// have a built-in facility for dynamically loading user native dlls for the appropriate platform. We therefore
3232
// preload the version with the correct architecture (from a corresponding sub-folder relative to us) on static
3333
// construction so that subsequent P/Invokes can find it.
3434
private static void PreloadWindowsLibrary(string dllFileName)
@@ -124,6 +124,12 @@ internal static extern int hostfxr_get_dotnet_environment_info(
124124
hostfxr_get_dotnet_environment_info_result_fn result,
125125
IntPtr result_context);
126126

127+
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
128+
internal delegate void hostfxr_error_writer_fn(IntPtr message);
129+
130+
[DllImport(Constants.HostFxr, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
131+
internal static extern IntPtr hostfxr_set_error_writer(IntPtr error_writer);
132+
127133
public static class Windows
128134
{
129135
private const CharSet UTF16 = CharSet.Unicode;

src/Resolvers/Microsoft.DotNet.NativeWrapper/NETCoreSdkResolverNativeWrapper.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,26 @@ public static SdkResolutionResult ResolveSdk(
2323
return result;
2424
}
2525

26+
public static string? GetGlobalJsonState(string globalJsonStartDirectory)
27+
{
28+
// We don't care about the actual SDK resolution, just the global.json information,
29+
// so just pass empty string as executable directory for resolution. This means that
30+
// we expect the call to fail to resolve an SDK. Set up the error writer to avoid
31+
// output going to stderr. We reset it after the call.
32+
var swallowErrors = new Interop.hostfxr_error_writer_fn(message => { });
33+
IntPtr errorWriter = Marshal.GetFunctionPointerForDelegate(swallowErrors);
34+
IntPtr previousErrorWriter = Interop.hostfxr_set_error_writer(errorWriter);
35+
try
36+
{
37+
SdkResolutionResult result = ResolveSdk(string.Empty, globalJsonStartDirectory);
38+
return result.GlobalJsonState;
39+
}
40+
finally
41+
{
42+
Interop.hostfxr_set_error_writer(previousErrorWriter);
43+
}
44+
}
45+
2646
private sealed class SdkList
2747
{
2848
public string[]? Entries;

0 commit comments

Comments
 (0)