Esatto.Win32.NetInjector 3.0.16

dotnet add package Esatto.Win32.NetInjector --version 3.0.16
NuGet\Install-Package Esatto.Win32.NetInjector -Version 3.0.16
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="Esatto.Win32.NetInjector" Version="3.0.16" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Esatto.Win32.NetInjector --version 3.0.16
#r "nuget: Esatto.Win32.NetInjector, 3.0.16"
#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.
// Install Esatto.Win32.NetInjector as a Cake Addin
#addin nuget:?package=Esatto.Win32.NetInjector&version=3.0.16

// Install Esatto.Win32.NetInjector as a Cake Tool
#tool nuget:?package=Esatto.Win32.NetInjector&version=3.0.16

Esatto Win32 NetInjector

Wrapper for Esatto.Win32.NetInjector.NetFx or Esatto.Win32.NetInjector.NetCore to invoke a static method in a remote process.

Requirements

  • Injecting process must be same bitness as target process
  • Target must pump window messages on target hWnd
  • The specified runtime must already be loaded in the target process
  • The injecting process must have permission to write to the target process
  • Type load will occur from the target process, so the injected method must not rely upon assembly resolution of the source process.
  • If you specify RuntimeVersions.LoadedNetCore, the target process must have already loaded the .NET Core loaded before injection.

Compatibility

The injector must be the same bitness as the target process:

Injector \ Target x86 x64
x86
x64

The injector and target may use different versions of .NET:

Injector \ Target .NET Core .NET Framework None (native)
.NET Core
.NET Framework

Note: Starting a second version of .NET Core in a target process will fail. This is due to a limitation in the .NET Core runtime. You can work around this by specifying RuntimeVersions.LoadedNetCore which always uses the existing version.

Note: Starting a version of .NET Core in a .NET Framework process will succeed but is not supported. See dotnet/runtime#53729.

Example use

Add nuget reference to Esatto.Win32.NetInjector, find a target hWnd, and call Injector.Inject.

var process = Process.GetProcessesByName("FrameworkLTC").Single();
// Alternatively: new EntryPointReference(@"c:\path\to\demohook.dll", "Namespace.DemoHook", "Inject");
var ep = new EntryPointReference(typeof(DemoHook), nameof(DemoHook.Inject));
Injetor.Inject(process.MainWindowHandle, ep, "Hello world!", RuntimeVersions.NetFxAny);

public class DemoHook
{
    public static int Inject(string arg)
    {
        MessageBox.Show(arg);
        return 0 /* S_OK */;
    }
}

Full examples for .NET Framework and .NET Core.

.NET Runtime Version

The injector and the target process do not need to run the same .NET Runtime. Use the optional runtimeVersion parameter of Inject to specify the target runtime.

Values for runtimeVersion may be:

  • RuntimeVersions.NetFxAny<br>Use the loaded version of .NET Framework or start the latest available version
  • RuntimeVersions.NetFx4<br>Use or start the latest version of .NET 4 installed on the machine
  • "v4.0.30319" or similar<br>Use or start the specified version of .NET 4
  • RuntimeVersions.NetCoreAny<br>Use or start the latest installed version of .NET Core
  • @"C:\foo\bar\baz.runtimeconfig.json"<br>Use the version of .NET Core specified in the runtimeconfig.json path provided. If a different incompatible runtime is already loaded in the target process, an error will be returned. Only later versions of .NET are supported in this manner. You can create *.runtimeconfig.json using <EnableDynamicLoading>true</EnableDynamicLoading> property in the hook csproj.
  • RuntimeVersions.LoadedNetCore<br>Use the .NET Core runtime already loaded in the target process will be used. This is compatible with older versions of .NET Core through at least .NET 8, but there are plans to remove this support from future versions of the runtime.
  • null<br>Use heuristics to determine the best runtime to use

The default runtime (runtimeVersion == null) is:

  1. If <AssemblyName>.runtimeconfig.json exists, use it
  2. If <AssemblyName>.deps.json exists, use RuntimeVersions.LoadedNetCore
  3. Use RuntimeVersions.NetFxAny

Notes

  • You may need to install an assembly resolution hook in the target process. Be sure to install the resolver before calling any method which references a type in an unloadable assembly.
  • You may need to specify the assembly path, type name, and method name explicitly if the hook type is not already loaded in the injecting process.
  • To inject a 64-bit process from a 32-bit process (or 32- from 64-), make an thunk with a matching bitness
  • The entrypoint must return before the call to Injector.Inject will return
  • The entrypoint should not throw. It may return an HRESULT, but they don't seem to reliably get returned to the injecting process.
  • Check debug output on the target process if hooks fail, typically this is the result of a required dependency assembly not being locatable by the target CLR.

Redistribution

Include the Esatto.Win32.NetInjector.dll and Esatto.Win32.NetInjector.NetFx.dll in your setup installer. If you are using RuntimeVersions.NetCoreAny or passing a runtimeconfig.json file, you must also include nethost.dll. nethost.dll is not needed for RuntimeVersions.LoadedNetCore.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • 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
3.0.16 76 4/29/2024
3.0.15 68 4/28/2024
3.0.14 108 4/12/2024
3.0.11 89 3/26/2024