diff --git a/csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.shared.cs b/csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.shared.cs
index abe73b77f4071..c445453aa06c5 100644
--- a/csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.shared.cs
+++ b/csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.shared.cs
@@ -889,8 +889,8 @@ internal class NativeLib
#if !NETSTANDARD2_0 && !__ANDROID__ && !__IOS__
///
/// Custom DllImportResolver to handle platform-specific library loading.
- /// On Windows, it explicitly loads the library with a lowercase .dll extension to handle
- /// case-sensitive filesystems.
+ /// It handles the addition of "lib" prefix and file extensions (.so/.dylib) for Linux/macOS,
+ /// and .dll extension for Windows (handling case-sensitivity).
///
private static IntPtr DllImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
{
@@ -915,74 +915,10 @@ private static IntPtr DllImportResolver(string libraryName, Assembly assembly, D
if (mappedName != null)
{
- // 1. Try default loading (name only)
if (NativeLibrary.TryLoad(mappedName, assembly, searchPath, out IntPtr handle))
{
return handle;
}
-
- // 2. Try relative to assembly location (look into runtimes subfolders)
- string assemblyLocation = null;
- try { assemblyLocation = assembly.Location; } catch { }
- if (!string.IsNullOrEmpty(assemblyLocation))
- {
- string assemblyDir = System.IO.Path.GetDirectoryName(assemblyLocation);
- string rid = RuntimeInformation.RuntimeIdentifier;
-
- // Probe the specific RID first, then common fallbacks for the current OS
- string[] ridsToTry;
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
- {
- ridsToTry = new[] { rid, "win-x64", "win-arm64" };
- }
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
- {
- ridsToTry = new[] { rid, "linux-x64", "linux-arm64" };
- }
- else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
- {
- // We no longer provide osx-x64 in official package since 1.24.
- // However, we keep it in the list for build-from-source users.
- ridsToTry = new[] { rid, "osx-arm64", "osx-x64" };
- }
- else
- {
- ridsToTry = new[] { rid };
- }
-
- foreach (var tryRid in ridsToTry)
- {
- string probePath = System.IO.Path.Combine(assemblyDir, "runtimes", tryRid, "native", mappedName);
- if (System.IO.File.Exists(probePath) && NativeLibrary.TryLoad(probePath, assembly, searchPath, out handle))
- {
- LogLibLoad($"[DllImportResolver] Loaded {mappedName} from: {probePath}");
- return handle;
- }
- }
- }
-
- // 3. Try AppContext.BaseDirectory as a fallback
- string baseDir = AppContext.BaseDirectory;
- if (!string.IsNullOrEmpty(baseDir))
- {
- string probePath = System.IO.Path.Combine(baseDir, mappedName);
- if (NativeLibrary.TryLoad(probePath, assembly, searchPath, out handle))
- {
- LogLibLoad($"[DllImportResolver] Loaded {mappedName} from: {probePath}");
- return handle;
- }
-
- string rid = RuntimeInformation.RuntimeIdentifier;
- probePath = System.IO.Path.Combine(baseDir, "runtimes", rid, "native", mappedName);
- if (NativeLibrary.TryLoad(probePath, assembly, searchPath, out handle))
- {
- LogLibLoad($"[DllImportResolver] Loaded {mappedName} from: {probePath}");
- return handle;
- }
- }
-
- LogLibLoad($"[DllImportResolver] Failed loading {mappedName} (RID: {RuntimeInformation.RuntimeIdentifier}, Assembly: {assemblyLocation})");
-
}
}
@@ -990,14 +926,7 @@ private static IntPtr DllImportResolver(string libraryName, Assembly assembly, D
return IntPtr.Zero;
}
- private static void LogLibLoad(string message)
- {
- System.Diagnostics.Trace.WriteLine(message);
- if (!string.IsNullOrEmpty(Environment.GetEnvironmentVariable("ORT_LOADER_VERBOSITY")))
- {
- Console.WriteLine(message);
- }
- }
+
#endif
[DllImport(NativeLib.DllName, CharSet = CharSet.Ansi)]
diff --git a/csharp/src/Microsoft.ML.OnnxRuntime/targets/native/props.xml b/csharp/src/Microsoft.ML.OnnxRuntime/targets/native/props.xml
new file mode 100644
index 0000000000000..126f7e932200e
--- /dev/null
+++ b/csharp/src/Microsoft.ML.OnnxRuntime/targets/native/props.xml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+ $(MSBuildThisFileDirectory)include;
+ %(AdditionalIncludeDirectories)
+
+
+
+
+
+
+
+
+
+
+ $(MSBuildThisFileDirectory)..\..\runtimes\win-x64\native\onnxruntime.lib;
+ %(AdditionalDependencies)
+
+
+
+
+
+
+
+ $(MSBuildThisFileDirectory)..\..\runtimes\win-arm64\native\onnxruntime.lib;
+ %(AdditionalDependencies)
+
+
+
+
+
diff --git a/csharp/src/Microsoft.ML.OnnxRuntime/targets/native/targets.xml b/csharp/src/Microsoft.ML.OnnxRuntime/targets/native/targets.xml
new file mode 100644
index 0000000000000..33e38ece56a48
--- /dev/null
+++ b/csharp/src/Microsoft.ML.OnnxRuntime/targets/native/targets.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
diff --git a/csharp/src/Microsoft.ML.OnnxRuntime/targets/netstandard/props.xml b/csharp/src/Microsoft.ML.OnnxRuntime/targets/netstandard/props.xml
index c3cd38c9cd56b..66ace998dac0f 100644
--- a/csharp/src/Microsoft.ML.OnnxRuntime/targets/netstandard/props.xml
+++ b/csharp/src/Microsoft.ML.OnnxRuntime/targets/netstandard/props.xml
@@ -1,146 +1,37 @@
+
+
+
- $(MSBuildThisFileDirectory)../../build/native/include/;%(AdditionalIncludeDirectories)
+
+ $(MSBuildThisFileDirectory)..\native\include;
+ %(AdditionalIncludeDirectories)
+
-
- $(MSBuildThisFileDirectory)../../build/native/include/;%(AdditionalIncludeDirectories)
-
-
+
+
+
+
- $(MSBuildThisFileDirectory)../../runtimes/win-arm64/native/onnxruntime.lib;%(AdditionalDependencies)
+
+ $(MSBuildThisFileDirectory)..\..\runtimes\win-x64\native\onnxruntime.lib;
+ %(AdditionalDependencies)
+
-
+
- $(MSBuildThisFileDirectory)../../runtimes/win-arm/native/onnxruntime.lib;%(AdditionalDependencies)
+
+ $(MSBuildThisFileDirectory)..\..\runtimes\win-arm64\native\onnxruntime.lib;
+ %(AdditionalDependencies)
+
-
-
- $(MSBuildThisFileDirectory)../../runtimes/win-x64/native/onnxruntime.lib;%(AdditionalDependencies)
-
-
-
-
- arm64
- arm
- $(Platform)
-
-
-
- $(MSBuildThisFileDirectory)..\..\runtimes\win-$(EnginePlatform)\native\onnxruntime.dll
-
-
-
-
- true
- true
- true
-
-
-
-
-
- onnxruntime.dll
- PreserveNewest
- false
-
-
- onnxruntime_providers_shared.dll
- PreserveNewest
- false
-
-
- onnxruntime_providers_cuda.dll
- PreserveNewest
- false
-
-
- onnxruntime_providers_dnnl.dll
- PreserveNewest
- false
-
-
- onnxruntime_providers_tensorrt.dll
- PreserveNewest
- false
-
-
- onnxruntime_providers_openvino.dll
- PreserveNewest
- false
-
-
- dnnl.dll
- PreserveNewest
- false
-
-
- mklml.dll
- PreserveNewest
- false
-
-
- libiomp5md.dll
- PreserveNewest
- false
-
-
-
-
- onnxruntime.dll
- PreserveNewest
- false
-
-
- onnxruntime_providers_shared.dll
- PreserveNewest
- false
-
-
-
-
- onnxruntime.dll
- PreserveNewest
- false
-
-
- onnxruntime_providers_shared.dll
- PreserveNewest
- false
-
-
-
+
diff --git a/csharp/src/Microsoft.ML.OnnxRuntime/targets/netstandard/targets.xml b/csharp/src/Microsoft.ML.OnnxRuntime/targets/netstandard/targets.xml
index 637ea7af32d5b..63ea750593cb6 100644
--- a/csharp/src/Microsoft.ML.OnnxRuntime/targets/netstandard/targets.xml
+++ b/csharp/src/Microsoft.ML.OnnxRuntime/targets/netstandard/targets.xml
@@ -1,16 +1,44 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <_OrtArch>x64
+ <_OrtArch Condition="'$(PlatformTarget)' == 'ARM64' OR '$(Platform)' == 'ARM64'">arm64
+
+
+
+ <_OrtNativeFiles Include="$(MSBuildThisFileDirectory)..\..\runtimes\win-$(_OrtArch)\native\*.dll" />
+
+
+
+
+
+
+
diff --git a/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests/runtest.bat b/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests/runtest.bat
index aa90744de2e17..84d591f3835f1 100755
--- a/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests/runtest.bat
+++ b/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests/runtest.bat
@@ -57,16 +57,28 @@ IF "%PACKAGENAME%"=="Microsoft.ML.OnnxRuntime.Gpu" set gpu_package=T
IF "%PACKAGENAME%"=="Microsoft.ML.OnnxRuntime.Gpu.Windows" set gpu_package=T
IF %%gpu_package%%=="T" (
set TESTONGPU=ON
- %dn% test -p:DefineConstants=USE_TENSORRT test\Microsoft.ML.OnnxRuntime.EndToEndTests\Microsoft.ML.OnnxRuntime.EndToEndTests.csproj --no-restore --filter TensorRT
+ %dn% build test\Microsoft.ML.OnnxRuntime.EndToEndTests\Microsoft.ML.OnnxRuntime.EndToEndTests.csproj --no-restore -p:DefineConstants=USE_TENSORRT
+ dir /s /b test\Microsoft.ML.OnnxRuntime.EndToEndTests\bin\onnxruntime.dll
+ IF %ERRORLEVEL% NEQ 0 (
+ @echo "Error: onnxruntime.dll not found in the output directory after build"
+ EXIT 1
+ )
+ %dn% test -p:DefineConstants=USE_TENSORRT test\Microsoft.ML.OnnxRuntime.EndToEndTests\Microsoft.ML.OnnxRuntime.EndToEndTests.csproj --no-restore --no-build --filter TensorRT
IF NOT errorlevel 0 (
@echo "Failed to build or execute the end-to-end test"
EXIT 1
)
- %dn% test -p:DefineConstants=USE_CUDA test\Microsoft.ML.OnnxRuntime.EndToEndTests\Microsoft.ML.OnnxRuntime.EndToEndTests.csproj --no-restore
+ %dn% test -p:DefineConstants=USE_CUDA test\Microsoft.ML.OnnxRuntime.EndToEndTests\Microsoft.ML.OnnxRuntime.EndToEndTests.csproj --no-restore --no-build
) ELSE (
- %dn% test test\Microsoft.ML.OnnxRuntime.EndToEndTests\Microsoft.ML.OnnxRuntime.EndToEndTests.csproj --no-restore
+ %dn% build test\Microsoft.ML.OnnxRuntime.EndToEndTests\Microsoft.ML.OnnxRuntime.EndToEndTests.csproj --no-restore
+ dir /s /b test\Microsoft.ML.OnnxRuntime.EndToEndTests\bin\onnxruntime.dll
+ IF %ERRORLEVEL% NEQ 0 (
+ @echo "Error: onnxruntime.dll not found in the output directory after build"
+ EXIT 1
+ )
+ %dn% test test\Microsoft.ML.OnnxRuntime.EndToEndTests\Microsoft.ML.OnnxRuntime.EndToEndTests.csproj --no-restore --no-build
)
IF NOT errorlevel 0 (
diff --git a/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests/runtest.sh b/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests/runtest.sh
index 91e05e6ba58a2..77047b7bb6572 100755
--- a/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests/runtest.sh
+++ b/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests/runtest.sh
@@ -33,18 +33,31 @@ if [ $RunTestCsharp = "true" ]; then
if [ $PACKAGENAME = "Microsoft.ML.OnnxRuntime.Gpu" ] || [ $PACKAGENAME = "Microsoft.ML.OnnxRuntime.Gpu.Linux" ]; then
export TESTONGPU=ON
- dotnet test -p:DefineConstants=USE_CUDA $BUILD_SOURCESDIRECTORY/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests/Microsoft.ML.OnnxRuntime.EndToEndTests.csproj --no-restore --verbosity detailed
+ dotnet build -p:DefineConstants=USE_CUDA $BUILD_SOURCESDIRECTORY/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests/Microsoft.ML.OnnxRuntime.EndToEndTests.csproj --no-restore
+ native_lib=$(find $BUILD_SOURCESDIRECTORY/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests/bin -name "libonnxruntime.so*" -o -name "libonnxruntime.dylib" | head -1)
+ if [ -z "$native_lib" ]; then
+ echo "Error: libonnxruntime not found in output directory after build"
+ exit 1
+ fi
+ echo "Found native library: $native_lib"
+ dotnet test -p:DefineConstants=USE_CUDA $BUILD_SOURCESDIRECTORY/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests/Microsoft.ML.OnnxRuntime.EndToEndTests.csproj --no-restore --no-build --verbosity detailed
if [ $? -ne 0 ]; then
echo "Failed to build or execute the end-to-end test"
exit 1
fi
dotnet test -p:DefineConstants=USE_TENSORRT $BUILD_SOURCESDIRECTORY/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests/Microsoft.ML.OnnxRuntime.EndToEndTests.csproj --no-restore --verbosity detailed
else
- dotnet test $BUILD_SOURCESDIRECTORY/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests/Microsoft.ML.OnnxRuntime.EndToEndTests.csproj --no-restore --verbosity detailed
+ dotnet build $BUILD_SOURCESDIRECTORY/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests/Microsoft.ML.OnnxRuntime.EndToEndTests.csproj --no-restore
+ native_lib=$(find $BUILD_SOURCESDIRECTORY/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests/bin -name "libonnxruntime.so*" -o -name "libonnxruntime.dylib" | head -1)
+ if [ -z "$native_lib" ]; then
+ echo "Error: libonnxruntime not found in output directory after build"
+ exit 1
+ fi
+ echo "Found native library: $native_lib"
+ dotnet test $BUILD_SOURCESDIRECTORY/csharp/test/Microsoft.ML.OnnxRuntime.EndToEndTests/Microsoft.ML.OnnxRuntime.EndToEndTests.csproj --no-restore --no-build --verbosity detailed
fi
if [ $? -ne 0 ]; then
echo "Failed to build or execute the end-to-end test"
exit 1
fi
fi
-
diff --git a/tools/nuget/generate_nuspec_for_native_nuget.py b/tools/nuget/generate_nuspec_for_native_nuget.py
index 1f882c847c707..42e087da79d6a 100644
--- a/tools/nuget/generate_nuspec_for_native_nuget.py
+++ b/tools/nuget/generate_nuspec_for_native_nuget.py
@@ -983,7 +983,7 @@ def _files_list_append(key: str):
):
# Process props file
if is_qnn_package:
- source_props = os.path.join(
+ source_props_native = os.path.join(
args.sources_path,
"csharp",
"src",
@@ -992,11 +992,25 @@ def _files_list_append(key: str):
"netstandard",
"props_qnn.xml",
)
+ source_props_netstandard = source_props_native
else:
- source_props = os.path.join(
+ source_props_native = os.path.join(
+ args.sources_path, "csharp", "src", "Microsoft.ML.OnnxRuntime", "targets", "native", "props.xml"
+ )
+ source_props_netstandard = os.path.join(
args.sources_path, "csharp", "src", "Microsoft.ML.OnnxRuntime", "targets", "netstandard", "props.xml"
)
- target_props = os.path.join(
+
+ target_props_native = os.path.join(
+ args.sources_path,
+ "csharp",
+ "src",
+ "Microsoft.ML.OnnxRuntime",
+ "targets",
+ "native",
+ args.package_name + ".props",
+ )
+ target_props_netstandard = os.path.join(
args.sources_path,
"csharp",
"src",
@@ -1005,17 +1019,37 @@ def _files_list_append(key: str):
"netstandard",
args.package_name + ".props",
)
- copy_file(source_props, target_props)
- files_list.append("')
+
+ copy_file(source_props_native, target_props_native)
+ copy_file(source_props_netstandard, target_props_netstandard)
+
+ files_list.append("')
if not is_snpe_package and not is_qnn_package:
- files_list.append("')
- files_list.append("')
+ files_list.append(
+ "'
+ )
+ files_list.append(
+ "'
+ )
# Process targets file
- source_targets = os.path.join(
+ source_targets_native = os.path.join(
+ args.sources_path, "csharp", "src", "Microsoft.ML.OnnxRuntime", "targets", "native", "targets.xml"
+ )
+ source_targets_netstandard = os.path.join(
args.sources_path, "csharp", "src", "Microsoft.ML.OnnxRuntime", "targets", "netstandard", "targets.xml"
)
- target_targets = os.path.join(
+
+ target_targets_native = os.path.join(
+ args.sources_path,
+ "csharp",
+ "src",
+ "Microsoft.ML.OnnxRuntime",
+ "targets",
+ "native",
+ args.package_name + ".targets",
+ )
+ target_targets_netstandard = os.path.join(
args.sources_path,
"csharp",
"src",
@@ -1024,11 +1058,18 @@ def _files_list_append(key: str):
"netstandard",
args.package_name + ".targets",
)
- copy_file(source_targets, target_targets)
- files_list.append("')
+
+ copy_file(source_targets_native, target_targets_native)
+ copy_file(source_targets_netstandard, target_targets_netstandard)
+
+ files_list.append("')
if not is_snpe_package and not is_qnn_package:
- files_list.append("')
- files_list.append("')
+ files_list.append(
+ "'
+ )
+ files_list.append(
+ "'
+ )
# Process xamarin targets files
if args.package_name == "Microsoft.ML.OnnxRuntime":