I am new to C# and I am trying to use the NtDelayExecution and ZwSetTimerResolution functions from ntdll.dll in order to create a custom sleep timer. (Thread.sleep is not precise enough for my application). I have tried many different ways, but i'm not sure how to import ntdll.dll in order to use these two functions. The two static NTSTATUS lines are partial c that I am trying to convert to C#. What I have tried so far:
public unsafe static void GoSleep(float ms, float resolution = 0.5f)
{
if (resolution < 0.5) resolution = 0.5f;
if (ms < resolution) ms = resolution;
nuint res = (nuint)(resolution * 10000);
nuint actualRes = 0;
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
[DllImport("kernel32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
public static extern IntPtr GetModuleHandle([MarshalAs(UnmanagedType.LPWStr)] in string lpModuleName);
static NTSTATUS(__stdcall* NtDelayExecution)(bool Alertable, PLARGE_INTEGER DelayInterval) = (NTSTATUS(__stdcall*)(bool, PLARGE_INTEGER)) GetProcAddress(GetModuleHandle(X("ntdll.dll")), X("NtDelayExecution"));
static NTSTATUS(__stdcall* ZwSetTimerResolution)(IN nuint RequestedResolution, IN bool Set, OUT pnuint ActualResolution) = (NTSTATUS(__stdcall*)(ULONG, BOOLEAN, PULONG)) GetProcAddress(GetModuleHandle(X("ntdll.dll")), X("ZwSetTimerResolution"));
ZwSetTimerResolution(res, true, &actualRes);
long LargeInteger = -1 * (long)(ms * 10000.0f);
NtDelayExecution(false, &LargeInteger);
ZwSetTimerResolution(res, false, &actualRes);
}
CodePudding user response:
The easiest way to import it is to use nuget.
- Right click on nuget manager
- Enter ntdll.dll, then select install