Skip to content

Fix DllImport library names for case-sensitive filesystems#26415

Merged
snnn merged 3 commits intomainfrom
copilot/fix-case-sensitive-filesystem-issue
Nov 4, 2025
Merged

Fix DllImport library names for case-sensitive filesystems#26415
snnn merged 3 commits intomainfrom
copilot/fix-case-sensitive-filesystem-issue

Conversation

Copy link
Contributor

Copilot AI commented Oct 27, 2025

On case-sensitive filesystems (Windows with WSL, developer mode, or per-directory case sensitivity), DllImport fails to load native libraries due to relying on .NET's automatic platform-specific extension/prefix addition, which can produce incorrect casing.

Changes

  • NativeMethods.shared.cs: Changed desktop platform library names from "onnxruntime" to "onnxruntime.dll" and "ortextensions" to "ortextensions.dll"
  • Explicitly specifying extensions ensures consistent behavior across case-sensitive and case-insensitive filesystems
  • Android/iOS platform-specific names unchanged

Impact

Windows: No changes required - libraries already named onnxruntime.dll

Linux/macOS: Native packaging may need updates to provide onnxruntime.dll in runtime folders (either as actual filename or symlink to libonnxruntime.so/libonnxruntime.dylib)

// Before (relied on automatic extension addition)
internal const string DllName = "onnxruntime";

// After (explicit extension for consistency)
internal const string DllName = "onnxruntime.dll";

Fixes #23509

Original prompt

This section details on the original issue you should resolve

<issue_title>Does not work on case-sensitive filesystems</issue_title>
<issue_description>### Describe the issue

Library does not work on case-sensitive filesystems. We get:

Unhandled exception. System.TypeInitializationException: The type initializer for 'Microsoft.ML.OnnxRuntime.NativeMethods' threw an exception.
 ---> System.EntryPointNotFoundException: Unable to find an entry point named 'OrtGetApiBase' in DLL 'onnxruntime'.
   at Microsoft.ML.OnnxRuntime.NativeMethods.OrtGetApiBase()
   at Microsoft.ML.OnnxRuntime.NativeMethods..cctor()
   --- End of inner exception stack trace ---
   at Microsoft.ML.OnnxRuntime.SessionOptions..ctor()
   at Microsoft.ML.OnnxRuntime.InferenceSession..ctor(String modelPath)
   at Program.<Main>$(String[] args) in Z:\temp\onnxtest\Program.cs:line 1

Probably due to a mistyped filename somewhere.

To reproduce

Create new C# project, use this Program.cs:

new Microsoft.ML.OnnxRuntime.InferenceSession("");

Urgency

No response

Platform

Windows

OS Version

Microsoft Windows [Version 10.0.19045.6332]

ONNX Runtime Installation

Released Package

ONNX Runtime Version or Commit ID

1.22.1

ONNX Runtime API

Other / Unknown

Architecture

X64

Execution Provider

Other / Unknown

Execution Provider Library Version

No response</issue_description>

Comments on the Issue (you are @copilot in this section)

@snnn I checked the code, still do not have much clue. We didn't specify the extension name. Maybe it was added by the .net runtime.

https://github.com/microsoft/onnxruntime/blob/main/csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.shared.cs#L831</comment_new>
<comment_new>@snnn

Maybe we should just specify explicit extensions then in DllImport

That might be the easiest fix. Would like to submit a PR?</comment_new>
<comment_new>@snnn
Don't close it.</comment_new>


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Fix library compatibility with case-sensitive filesystems Fix DllImport library names for case-sensitive filesystems Oct 27, 2025
Copilot AI requested a review from snnn October 27, 2025 17:19
@snnn snnn marked this pull request as ready for review October 31, 2025 23:08
@snnn snnn merged commit 1fb03cc into main Nov 4, 2025
93 of 94 checks passed
@snnn snnn deleted the copilot/fix-case-sensitive-filesystem-issue branch November 4, 2025 21:22
Rohanjames1997 pushed a commit to Rohanjames1997/onnxruntime that referenced this pull request Dec 4, 2025
…#26415)

On case-sensitive filesystems (Windows with WSL, developer mode, or
per-directory case sensitivity), DllImport fails to load native
libraries due to relying on .NET's automatic platform-specific
extension/prefix addition, which can produce incorrect casing.

## Changes

- **NativeMethods.shared.cs**: Changed desktop platform library names
from `"onnxruntime"` to `"onnxruntime.dll"` and `"ortextensions"` to
`"ortextensions.dll"`
- Explicitly specifying extensions ensures consistent behavior across
case-sensitive and case-insensitive filesystems
- Android/iOS platform-specific names unchanged

## Impact

**Windows**: No changes required - libraries already named
`onnxruntime.dll`

**Linux/macOS**: Native packaging may need updates to provide
`onnxruntime.dll` in runtime folders (either as actual filename or
symlink to `libonnxruntime.so`/`libonnxruntime.dylib`)

```csharp
// Before (relied on automatic extension addition)
internal const string DllName = "onnxruntime";

// After (explicit extension for consistency)
internal const string DllName = "onnxruntime.dll";
```

Fixes microsoft#23509

<!-- START COPILOT CODING AGENT SUFFIX -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>Does not work on case-sensitive filesystems</issue_title>
> <issue_description>### Describe the issue
> 
> Library does not work on case-sensitive filesystems. We get:
> 
> ```
> Unhandled exception. System.TypeInitializationException: The type
initializer for 'Microsoft.ML.OnnxRuntime.NativeMethods' threw an
exception.
> ---> System.EntryPointNotFoundException: Unable to find an entry point
named 'OrtGetApiBase' in DLL 'onnxruntime'.
>    at Microsoft.ML.OnnxRuntime.NativeMethods.OrtGetApiBase()
>    at Microsoft.ML.OnnxRuntime.NativeMethods..cctor()
>    --- End of inner exception stack trace ---
>    at Microsoft.ML.OnnxRuntime.SessionOptions..ctor()
> at Microsoft.ML.OnnxRuntime.InferenceSession..ctor(String modelPath)
> at Program.<Main>$(String[] args) in Z:\temp\onnxtest\Program.cs:line
1
> ```
> 
> Probably due to a mistyped filename somewhere.
> 
> ### To reproduce
> 
> Create new C# project, use this Program.cs:
> 
> ```
> new Microsoft.ML.OnnxRuntime.InferenceSession("");
> ```
> 
> 
> ### Urgency
> 
> _No response_
> 
> ### Platform
> 
> Windows
> 
> ### OS Version
> 
> Microsoft Windows [Version 10.0.19045.6332]
> 
> ### ONNX Runtime Installation
> 
> Released Package
> 
> ### ONNX Runtime Version or Commit ID
> 
> 1.22.1
> 
> ### ONNX Runtime API
> 
> Other / Unknown
> 
> ### Architecture
> 
> X64
> 
> ### Execution Provider
> 
> Other / Unknown
> 
> ### Execution Provider Library Version
> 
> _No response_</issue_description>
> 
> ## Comments on the Issue (you are @copilot in this section)
> 
> <comments>
> <comment_new><author>@snnn</author><body>
> I checked the code, still do not have much clue. We didn't specify the
extension name. Maybe it was added by the .net runtime.
> 
>
https://github.com/microsoft/onnxruntime/blob/main/csharp/src/Microsoft.ML.OnnxRuntime/NativeMethods.shared.cs#L831</body></comment_new>
> <comment_new><author>@snnn</author><body>
> > Maybe we should just specify explicit extensions then in DllImport
> 
> That might be the easiest fix. Would like to submit a
PR?</body></comment_new>
> <comment_new><author>@snnn</author><body>
> Don't close it.</body></comment_new>
> </comments>
> 


</details>

- Fixes microsoft#26129

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: snnn <[email protected]>
Co-authored-by: Changming Sun <[email protected]>
@AndiRudi
Copy link

AndiRudi commented Feb 9, 2026

Weird changes... its breaking code all over the place and the best an AI has to offer is to downgrade until this is fixed. See this output...

After reviewing the PR, this confirms the root cause of your issue:

What happened:
PR #26415 (merged Nov 4, 2025) changed the library loading from "onnxruntime" to "onnxruntime.dll" to fix issues on case-sensitive filesystems. However, the impact section notes that "Linux/macOS: Native packaging may need updates to provide onnxruntime.dll in runtime folders (either as actual filename or symlink to libonnxruntime.so / libonnxruntime.dylib)"

The problem:
• Version 1.24.1 now explicitly looks for onnxruntime.dll
• But on macOS, the actual file is libonnxruntime.dylib
• Microsoft didn't update the macOS native packaging to include the expected filename or symlink

Your solution (reverting to 1.23.2) is correct because:
• Version 1.23.2 predates this breaking change
• It uses the old library loading mechanism that works with libonnxruntime.dylib
• You should stay on 1.23.2 until Microsoft releases a fix that properly packages the native libraries for macOS

Would you like me to commit the ONNX Runtime version revert now?

tianleiwu added a commit that referenced this pull request Feb 12, 2026
## Summary

This PR addresses persistent native library loading issues in the ONNX
Runtime NuGet package, specifically on macOS and Linux, by implementing
a robust DllImportResolver. It also includes necessary pipeline and
packaging adjustments to ensure required macOS artifacts are correctly
located and validated during CI.

## Problem
#27263 reports that
`Unable to load shared library 'onnxruntime.dll' or one of its
dependencies`. It was caused by
#26415 since the commit
hard-coded onnxruntime.dll even for Linux and MacOS (The correct
filename shall be libonnxruntime.so for Linux, and libonnxruntime.dylib
for MacOS).

The Nuget test pipeline has been broken for a while, so we also need fix
the pipeline to test our change. It has the following issues:
* MacOS nuget is for arm64, but the vmImage `macOS-15` is x64. 
* MacOS nuget test need libcustom_op_library.dylib, but it is not copied
from artifacts to test environment.
* MacOS artifact contains libonnxruntime.dylib and
libonnxruntime.1.24.1.dylib, where libonnxruntime.dylib is symlink. It
causes issue since the later is excluded by nuspec.
* MacOS nuget test use models from onnx repo. However, latest onnx has
some models with data types like float8 that are not supported by C#, so
those model test failed.
* Linux nuget test uses a docker Dockerfile.package_ubuntu_2404_gpu, but
docker build failed due to libnvinfer-headers-python-plugin-dev and
libnvinfer-win-builder-resource10 version.

## Changes

### 1. Robust C# DLL Resolution

The DllImportResolver has been enhanced to handle various deployment
scenarios where standard .NET resolution might fail:

- **Platform-Specific Naming**: Maps extension-less library names
(`onnxruntime`, `ortextensions`) to appropriate filenames
(`onnxruntime.dll`, `libonnxruntime.so`, `libonnxruntime.dylib`) based
on the OS.
- **Multi-Stage Probing**:
1. **Default Loading**: Attempts `NativeLibrary.TryLoad` with the mapped
name.
2. **NuGet `runtimes` Probing**: If the above fails, it probes the
`runtimes/{rid}/native/` subdirectories relative to the assembly
location, covering common RIDs (`win-x64`, `linux-arm64`, `osx-arm64`,
etc.).
3. **Base Directory Fallback**: As a final attempt, it looks in
`AppContext.BaseDirectory`.
- **Case-Sensitivity Handling**: Ensures lowercase extensions are used
on Windows to prevent lookup failures on case-sensitive filesystems.

### 2. macOS CI/Packaging Improvements

- **Templates (test_macos.yml)**:
    - Updated to extract artifacts from TGZ files.
- Ensures `libcustom_op_library.dylib` is placed in the expected
location (`testdata/testdata`) for end-to-end tests.
    - Initializes the ONNX submodule to provide required test data.
- **Node.js**:
- Restored the Node.js macOS test stage in
c-api-noopenmp-test-pipelines.yml, configured to run on the ARM64 pool
(`AcesShared`).
- Updated test_macos.yml template to support custom agent pools (similar
to the NuGet template).
- **Pipeline Config**: Adjusted agent pool selection and demands for
macOS jobs to ensure stable execution.
- **Binary Robustness**: The `copy_strip_binary.sh` script now ensures
`libonnxruntime.dylib` is a real file rather than a symlink, improving
NuGet packaging reliability.

### 3. Test Refinements

- **Inference Tests**: Skips a specific set of pretrained-model test
cases on macOS that are currently known to be flaky or unsupported in
that environment, preventing noise in the CI results.

## Verification

### Pipelines
- [x] Verified in `NuGet_Test_MacOS`.
- [x] Verified in `NuGet_Test_Linux`.
- [x] Verified in Windows test pipelines.

### Net Effect
The C# bindings are now significantly more resilient to different
deployment environments. The CI process for macOS is also more robust,
correctly handling the artifacts required for comprehensive NuGet
validation.
tianleiwu added a commit that referenced this pull request Feb 12, 2026
## Summary

This PR addresses persistent native library loading issues in the ONNX
Runtime NuGet package, specifically on macOS and Linux, by implementing
a robust DllImportResolver. It also includes necessary pipeline and
packaging adjustments to ensure required macOS artifacts are correctly
located and validated during CI.

## Problem
#27263 reports that
`Unable to load shared library 'onnxruntime.dll' or one of its
dependencies`. It was caused by
#26415 since the commit
hard-coded onnxruntime.dll even for Linux and MacOS (The correct
filename shall be libonnxruntime.so for Linux, and libonnxruntime.dylib
for MacOS).

The Nuget test pipeline has been broken for a while, so we also need fix
the pipeline to test our change. It has the following issues:
* MacOS nuget is for arm64, but the vmImage `macOS-15` is x64. 
* MacOS nuget test need libcustom_op_library.dylib, but it is not copied
from artifacts to test environment.
* MacOS artifact contains libonnxruntime.dylib and
libonnxruntime.1.24.1.dylib, where libonnxruntime.dylib is symlink. It
causes issue since the later is excluded by nuspec.
* MacOS nuget test use models from onnx repo. However, latest onnx has
some models with data types like float8 that are not supported by C#, so
those model test failed.
* Linux nuget test uses a docker Dockerfile.package_ubuntu_2404_gpu, but
docker build failed due to libnvinfer-headers-python-plugin-dev and
libnvinfer-win-builder-resource10 version.

## Changes

### 1. Robust C# DLL Resolution

The DllImportResolver has been enhanced to handle various deployment
scenarios where standard .NET resolution might fail:

- **Platform-Specific Naming**: Maps extension-less library names
(`onnxruntime`, `ortextensions`) to appropriate filenames
(`onnxruntime.dll`, `libonnxruntime.so`, `libonnxruntime.dylib`) based
on the OS.
- **Multi-Stage Probing**:
1. **Default Loading**: Attempts `NativeLibrary.TryLoad` with the mapped
name.
2. **NuGet `runtimes` Probing**: If the above fails, it probes the
`runtimes/{rid}/native/` subdirectories relative to the assembly
location, covering common RIDs (`win-x64`, `linux-arm64`, `osx-arm64`,
etc.).
3. **Base Directory Fallback**: As a final attempt, it looks in
`AppContext.BaseDirectory`.
- **Case-Sensitivity Handling**: Ensures lowercase extensions are used
on Windows to prevent lookup failures on case-sensitive filesystems.

### 2. macOS CI/Packaging Improvements

- **Templates (test_macos.yml)**:
    - Updated to extract artifacts from TGZ files.
- Ensures `libcustom_op_library.dylib` is placed in the expected
location (`testdata/testdata`) for end-to-end tests.
    - Initializes the ONNX submodule to provide required test data.
- **Node.js**:
- Restored the Node.js macOS test stage in
c-api-noopenmp-test-pipelines.yml, configured to run on the ARM64 pool
(`AcesShared`).
- Updated test_macos.yml template to support custom agent pools (similar
to the NuGet template).
- **Pipeline Config**: Adjusted agent pool selection and demands for
macOS jobs to ensure stable execution.
- **Binary Robustness**: The `copy_strip_binary.sh` script now ensures
`libonnxruntime.dylib` is a real file rather than a symlink, improving
NuGet packaging reliability.

### 3. Test Refinements

- **Inference Tests**: Skips a specific set of pretrained-model test
cases on macOS that are currently known to be flaky or unsupported in
that environment, preventing noise in the CI results.

## Verification

### Pipelines
- [x] Verified in `NuGet_Test_MacOS`.
- [x] Verified in `NuGet_Test_Linux`.
- [x] Verified in Windows test pipelines.

### Net Effect
The C# bindings are now significantly more resilient to different
deployment environments. The CI process for macOS is also more robust,
correctly handling the artifacts required for comprehensive NuGet
validation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Does not work on case-sensitive filesystems

4 participants