Esatto.Win32.NetInjector
3.0.16
See the version list below for details.
dotnet add package Esatto.Win32.NetInjector --version 3.0.16
NuGet\Install-Package Esatto.Win32.NetInjector -Version 3.0.16
<PackageReference Include="Esatto.Win32.NetInjector" Version="3.0.16" />
paket add Esatto.Win32.NetInjector --version 3.0.16
#r "nuget: Esatto.Win32.NetInjector, 3.0.16"
// 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 versionRuntimeVersions.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 4RuntimeVersions.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:
- If
<AssemblyName>.runtimeconfig.json
exists, use it - If
<AssemblyName>.deps.json
exists, useRuntimeVersions.LoadedNetCore
- 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 | Versions 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. |
-
.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.