--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace HostApiInvokerApp
+{
+ public static class HostFXR
+ {
+ internal static class hostfxr
+ {
+ [DllImport(nameof(hostfxr), CharSet = Utils.OSCharSet)]
+ internal static extern uint hostfxr_get_native_search_directories(
+ int argc,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)]
+ string[] argv,
+ StringBuilder buffer,
+ int bufferSize,
+ ref int required_buffer_size);
+
+ [Flags]
+ internal enum hostfxr_resolve_sdk2_flags_t : int
+ {
+ disallow_prerelease = 0x1,
+ }
+
+ internal enum hostfxr_resolve_sdk2_result_key_t : int
+ {
+ resolved_sdk_dir = 0,
+ global_json_path = 1,
+ }
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = Utils.OSCharSet)]
+ internal delegate void hostfxr_resolve_sdk2_result_fn(
+ hostfxr_resolve_sdk2_result_key_t key,
+ string value);
+
+ [DllImport(nameof(hostfxr), CharSet = Utils.OSCharSet, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int hostfxr_resolve_sdk2(
+ string exe_dir,
+ string working_dir,
+ hostfxr_resolve_sdk2_flags_t flags,
+ hostfxr_resolve_sdk2_result_fn result);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = Utils.OSCharSet)]
+ internal delegate void hostfxr_get_available_sdks_result_fn(
+ int sdk_count,
+ [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)]
+ string[] sdk_dirs);
+
+ [DllImport(nameof(hostfxr), CharSet = Utils.OSCharSet, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern int hostfxr_get_available_sdks(
+ string exe_dir,
+ hostfxr_get_available_sdks_result_fn result);
+
+ internal const uint HostApiBufferTooSmall = 0x80008098;
+ }
+
+ /// <summary>
+ /// Test invoking the native hostfxr api hostfxr_get_native_search_directories
+ /// </summary>
+ /// <param name="args[0]">hostfxr_get_native_search_directories</param>
+ /// <param name="args[1]">Path to dotnet.exe</param>
+ /// <param name="args[2]">Path to application</param>
+ static void Test_hostfxr_get_native_search_directories(string[] args)
+ {
+ if (args.Length != 3)
+ {
+ throw new ArgumentException("Invalid number of arguments passed");
+ }
+
+ string pathToDotnet = args[1];
+ string pathToApp = args[2];
+ string[] argv = new[] { pathToDotnet, pathToApp };
+
+ // Start with 0 bytes allocated to test re-entry and required_buffer_size
+ StringBuilder buffer = new StringBuilder(0);
+ int required_buffer_size = 0;
+
+ uint rc = 0;
+ for (int i = 0; i < 2; i++)
+ {
+ rc = hostfxr.hostfxr_get_native_search_directories(argv.Length, argv, buffer, buffer.Capacity + 1, ref required_buffer_size);
+ if (rc != hostfxr.HostApiBufferTooSmall)
+ {
+ break;
+ }
+
+ buffer = new StringBuilder(required_buffer_size);
+ }
+
+ if (rc == 0)
+ {
+ Console.WriteLine("hostfxr_get_native_search_directories:Success");
+ Console.WriteLine($"hostfxr_get_native_search_directories buffer:[{buffer}]");
+ }
+ else
+ {
+ Console.WriteLine($"hostfxr_get_native_search_directories:Fail[{rc}]");
+ }
+ }
+
+ /// <summary>
+ /// Test invoking the native hostfxr api hostfxr_resolve_sdk2
+ /// </summary>
+ /// <param name="args[0]">hostfxr_get_available_sdks</param>
+ /// <param name="args[1]">Directory of dotnet executable</param>
+ /// <param name="args[2]">Working directory where search for global.json begins</param>
+ /// <param name="args[3]">Flags</param>
+ static void Test_hostfxr_resolve_sdk2(string[] args)
+ {
+ if (args.Length != 4)
+ {
+ throw new ArgumentException("Invalid number of arguments passed");
+ }
+
+ var data = new List<(hostfxr.hostfxr_resolve_sdk2_result_key_t, string)>();
+ int rc = hostfxr.hostfxr_resolve_sdk2(
+ exe_dir: args[1],
+ working_dir: args[2],
+ flags: Enum.Parse<hostfxr.hostfxr_resolve_sdk2_flags_t>(args[3]),
+ result: (key, value) => data.Add((key, value)));
+
+ if (rc == 0)
+ {
+ Console.WriteLine("hostfxr_resolve_sdk2:Success");
+ }
+ else
+ {
+ Console.WriteLine($"hostfxr_resolve_sdk2:Fail[{rc}]");
+ }
+
+ Console.WriteLine($"hostfxr_resolve_sdk2 data:[{string.Join(';', data)}]");
+ }
+
+ /// <summary>
+ /// Test invoking the native hostfxr api hostfxr_get_available_sdks
+ /// </summary>
+ /// <param name="args[0]">hostfxr_get_available_sdks</param>
+ /// <param name="args[1]">Directory of dotnet executable</param>
+ static void Test_hostfxr_get_available_sdks(string[] args)
+ {
+ if (args.Length != 2)
+ {
+ throw new ArgumentException("Invalid number of arguments passed");
+ }
+
+ string[] sdks = null;
+ int rc = hostfxr.hostfxr_get_available_sdks(
+ exe_dir: args[1],
+ (sdk_count, sdk_dirs) => sdks = sdk_dirs);
+
+ if (rc == 0)
+ {
+ Console.WriteLine("hostfxr_get_available_sdks:Success");
+ Console.WriteLine($"hostfxr_get_available_sdks sdks:[{string.Join(';', sdks)}]");
+ }
+ else
+ {
+ Console.WriteLine($"hostfxr_get_available_sdks:Fail[{rc}]");
+ }
+ }
+
+ public static bool RunTest(string apiToTest, string[] args)
+ {
+ switch (apiToTest)
+ {
+ case nameof(hostfxr.hostfxr_get_native_search_directories):
+ Test_hostfxr_get_native_search_directories(args);
+ break;
+ case nameof(hostfxr.hostfxr_resolve_sdk2):
+ Test_hostfxr_resolve_sdk2(args);
+ break;
+ case nameof(hostfxr.hostfxr_get_available_sdks):
+ Test_hostfxr_get_available_sdks(args);
+ break;
+ default:
+ return false;
+ }
+
+ Utils.LogModulePath("hostfxr");
+
+ return true;
+ }
+ }
+}
\ No newline at end of file
using System.Runtime.InteropServices;
using System.Text;
-namespace StandaloneApp
+namespace HostApiInvokerApp
{
public static class Program
{
-#if WINDOWS
- const CharSet OSCharSet = CharSet.Unicode;
-#else
- const CharSet OSCharSet = CharSet.Ansi; // actually UTF8 on Unix
-#endif
-
- [DllImport("hostfxr", CharSet = OSCharSet)]
- static extern uint hostfxr_get_native_search_directories(
- int argc,
- [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)]
- string[] argv,
- StringBuilder buffer,
- int bufferSize,
- ref int required_buffer_size);
-
- [Flags]
- internal enum hostfxr_resolve_sdk2_flags_t : int
- {
- disallow_prerelease = 0x1,
- }
-
- internal enum hostfxr_resolve_sdk2_result_key_t : int
- {
- resolved_sdk_dir = 0,
- global_json_path = 1,
- }
-
- [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = OSCharSet)]
- internal delegate void hostfxr_resolve_sdk2_result_fn(
- hostfxr_resolve_sdk2_result_key_t key,
- string value);
-
- [DllImport("hostfxr", CharSet = OSCharSet, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int hostfxr_resolve_sdk2(
- string exe_dir,
- string working_dir,
- hostfxr_resolve_sdk2_flags_t flags,
- hostfxr_resolve_sdk2_result_fn result);
-
- [UnmanagedFunctionPointer(CallingConvention.Cdecl, CharSet = OSCharSet)]
- internal delegate void hostfxr_get_available_sdks_result_fn(
- int sdk_count,
- [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)]
- string[] sdk_dirs);
-
- [DllImport("hostfxr", CharSet = OSCharSet, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
- internal static extern int hostfxr_get_available_sdks(
- string exe_dir,
- hostfxr_get_available_sdks_result_fn result);
-
- const uint HostApiBufferTooSmall = 0x80008098;
-
public static int Main(string[] args)
{
- // write exception details to stdout so tha they can be seen in test assertion failures.
+ // write exception details to stdout so that they can be seen in test assertion failures.
try
{
MainCore(args);
}
string apiToTest = args[0];
- switch (apiToTest)
- {
- case nameof(hostfxr_get_native_search_directories):
- Test_hostfxr_get_native_search_directories(args);
- break;
- case nameof(hostfxr_resolve_sdk2):
- Test_hostfxr_resolve_sdk2(args);
- break;
- case nameof(hostfxr_get_available_sdks):
- Test_hostfxr_get_available_sdks(args);
- break;
- default:
- throw new ArgumentException($"Invalid API to test passed as args[0]): {apiToTest}");
- }
- }
-
- /// <summary>
- /// Test invoking the native hostfxr api hostfxr_get_native_search_directories
- /// </summary>
- /// <param name="args[0]">hostfxr_get_native_search_directories</param>
- /// <param name="args[1]">Path to dotnet.exe</param>
- /// <param name="args[2]">Path to application</param>
- static void Test_hostfxr_get_native_search_directories(string[] args)
- {
- if (args.Length != 3)
- {
- throw new ArgumentException("Invalid number of arguments passed");
- }
-
- string pathToDotnet = args[1];
- string pathToApp = args[2];
- string[] argv = new[] { pathToDotnet, pathToApp };
-
- // Start with 0 bytes allocated to test re-entry and required_buffer_size
- StringBuilder buffer = new StringBuilder(0);
- int required_buffer_size = 0;
-
- uint rc = 0;
- for (int i = 0; i < 2; i++)
- {
- rc = hostfxr_get_native_search_directories(argv.Length, argv, buffer, buffer.Capacity + 1, ref required_buffer_size);
- if (rc != HostApiBufferTooSmall)
- {
- break;
- }
-
- buffer = new StringBuilder(required_buffer_size);
- }
-
- if (rc == 0)
- {
- Console.WriteLine("hostfxr_get_native_search_directories:Success");
- Console.WriteLine($"hostfxr_get_native_search_directories buffer:[{buffer}]");
- }
- else
- {
- Console.WriteLine($"hostfxr_get_native_search_directories:Fail[{rc}]");
- }
- }
-
- /// <summary>
- /// Test invoking the native hostfxr api hostfxr_resolve_sdk2
- /// </summary>
- /// <param name="args[0]">hostfxr_get_available_sdks</param>
- /// <param name="args[1]">Directory of dotnet executable</param>
- /// <param name="args[2]">Working directory where search for global.json begins</param>
- /// <param name="args[3]">Flags</param>
- static void Test_hostfxr_resolve_sdk2(string[] args)
- {
- if (args.Length != 4)
- {
- throw new ArgumentException("Invalid number of arguments passed");
- }
-
- var data = new List<(hostfxr_resolve_sdk2_result_key_t, string)>();
- int rc = hostfxr_resolve_sdk2(
- exe_dir: args[1],
- working_dir: args[2],
- flags: Enum.Parse<hostfxr_resolve_sdk2_flags_t>(args[3]),
- result: (key, value) => data.Add((key, value)));
-
- if (rc == 0)
- {
- Console.WriteLine("hostfxr_resolve_sdk2:Success");
- }
- else
- {
- Console.WriteLine($"hostfxr_resolve_sdk2:Fail[{rc}]");
- }
-
- Console.WriteLine($"hostfxr_resolve_sdk2 data:[{string.Join(';', data)}]");
- }
-
- /// <summary>
- /// Test invoking the native hostfxr api hostfxr_get_available_sdks
- /// </summary>
- /// <param name="args[0]">hostfxr_get_available_sdks</param>
- /// <param name="args[1]">Directory of dotnet executable</param>
- static void Test_hostfxr_get_available_sdks(string[] args)
- {
- if (args.Length != 2)
- {
- throw new ArgumentException("Invalid number of arguments passed");
- }
-
- string[] sdks = null;
- int rc = hostfxr_get_available_sdks(
- exe_dir: args[1],
- (sdk_count, sdk_dirs) => sdks = sdk_dirs);
-
- if (rc == 0)
+ if (HostFXR.RunTest(apiToTest, args))
{
- Console.WriteLine("hostfxr_get_available_sdks:Success");
- Console.WriteLine($"hostfxr_get_available_sdks sdks:[{string.Join(';', sdks)}]");
+ return;
}
else
{
- Console.WriteLine($"hostfxr_get_native_search_directories:Fail[{rc}]");
+ throw new ArgumentException($"Invalid API to test passed as args[0]): {apiToTest}");
}
}
}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace HostApiInvokerApp
+{
+ public static class Utils
+ {
+#if WINDOWS
+ public const CharSet OSCharSet = CharSet.Unicode;
+#else
+ public const CharSet OSCharSet = CharSet.Ansi; // actually UTF8 on Unix
+#endif
+
+#if WINDOWS
+ internal static class kernel32
+ {
+ [DllImport(nameof(kernel32), CharSet = CharSet.Auto, BestFitMapping = false, SetLastError = true)]
+ internal static extern IntPtr GetModuleHandle(String moduleName);
+
+ [DllImport(nameof(kernel32), CharSet = CharSet.Auto)]
+ internal static extern uint GetModuleFileName(IntPtr hModule, StringBuilder fileName, int size);
+ }
+#endif
+
+ public static void LogModulePath(string moduleName)
+ {
+#if WINDOWS
+ IntPtr hModule = kernel32.GetModuleHandle(moduleName);
+ if (hModule == IntPtr.Zero)
+ {
+ Console.WriteLine($"Can't find module {moduleName} in the process.");
+ return;
+ }
+
+ StringBuilder buffer = new StringBuilder(2048);
+ if (kernel32.GetModuleFileName(hModule, buffer, buffer.Capacity) <= 0)
+ {
+ Console.WriteLine($"Failed to get module file path for module {moduleName}.");
+ return;
+ }
+
+ Console.WriteLine($"{moduleName}: {buffer.ToString()}");
+#endif
+ }
+ }
+}
// 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 Microsoft.DotNet.Cli.Build;
using System;
using System.IO;
using System.Runtime.InteropServices;
using Xunit;
-using FluentAssertions;
-using Microsoft.DotNet.CoreSetup.Test;
-using System.Collections.Generic;
-using Microsoft.DotNet.Cli.Build;
namespace Microsoft.DotNet.CoreSetup.Test.HostActivation.NativeHostApis
{
{
private SharedTestState sharedTestState;
- public GivenThatICareAboutNativeHostApis(GivenThatICareAboutNativeHostApis.SharedTestState fixture)
+ public GivenThatICareAboutNativeHostApis(SharedTestState fixture)
{
sharedTestState = fixture;
}