NativeDllMain 1.0.0

dotnet add package NativeDllMain --version 1.0.0
                    
NuGet\Install-Package NativeDllMain -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="NativeDllMain" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="NativeDllMain" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="NativeDllMain" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add NativeDllMain --version 1.0.0
                    
#r "nuget: NativeDllMain, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package NativeDllMain@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=NativeDllMain&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=NativeDllMain&version=1.0.0
                    
Install as a Cake Tool

NativeDllMain NuGet

A static library for NativeAOT projects, providing a native DllMain implementation that safely invokes a managed entrypoint after the Windows loader lock is released.

This library is necessary because the dotnet runtime initialization code does not meet the restrictions imposed by the Windows loader lock, making it impossible to implement DllMain directly in managed code.

NOTE: This functionality is only enabled when targeting win-x64 or win-x86.

Usage

  1. Reference the NativeDllMain NuGet package in your project.
  2. Add the following method to your project:
[UnmanagedCallersOnly(EntryPoint = "DllProcessAttach")]
public static void Main(nint hModule) // can be named anything you want as long as the unmanaged symbol is set to be "DllProcessAttach"
{
    /*
        Your entrypoint code here
    */
}

Now, when your DLL is loaded, CreateThread is used to spawn a new thread for your managed entrypoint, which will be suspended until after the loader lock is released.

QueueUserAPC

If an application queues an APC before the thread begins running, the thread begins by calling the APC function.

For a DLL that is loaded via the Import Address Table (IAT), such as a proxy DLL, DllMain is called before the main thread begins execution. Therefore it's recommended to use QueueUserAPC to call your managed entrypoint, instead of CreateThread, which prevents a race condition between the main thread and your managed entrypoint.

To enable this behaviour, add the following to a <PropertyGroup> in your csproj:

<DllMainUseQueueUserApc>true</DllMainUseQueueUserApc>

NOTE: If your DLL is loaded via LoadLibrary or similar, you should continue to use CreateThread (the default behaviour), otherwise your managed entrypoint may never be called.

Building

Essentially just replicate the CI instructions.

License

This project is subject to the terms of the Mozilla Public License, v. 2.0.

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 218 11/8/2025