I want to import some functions from kernel32.dll, but I want to use different names. Example function:
[DllImport("kernel32.dll")] private static extern bool ReadProcessMemoryProc64 (...);
private static bool BetterReadableAndWriteableName (...) {
ReadProcessMemoryProc64(...);
}
Wrapping the function is what I actually don't want, if there is another way.
Use the EntryPoint property of DllImportAttribute.
[DllImport("kernel32.dll", EntryPoint="ReadProcessMemoryProc64")]
private static extern bool BetterReadableAndWriteableName (...);
[DllImport("kernel32.dll", EntryPoint = "ReadProcessMemoryProc64")]
private static extern bool MyName(...);
Related
I need to implement the following C++ code into C#.
PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY signaturePolicy = { };
signaturePolicy.MicrosoftSignedOnly = true;
SetProcessMitigationPolicy(ProcessSignaturePolicy, &signaturePolicy, sizeof(signaturePolicy));
I have already defined the extern and the struct, but i dont know to use the parameters for the function.
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetProcessMitigationPolicy(int policy, PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY lpBuffer, int size);
private struct PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY
{
private uint MicrosoftSignedOnly;
}
public static void Main(string[] args)
{
SetProcessMitigationPolicy(??) // what do do there? how to get the required sizeof?
}
Can anyone explain me how to pass the required parameters in the right way? Thanks.
I am building a Dotnet Core 3.1 Console application where i want to get and set system's mouse double click speed.
I got success to get the speed using
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern int GetDoubleClickTime();
But not able to set desired values for the same.
I have tried following options but did not get success
SetDoubleClickTime
current system values is 550 received from above method
Passing 200 as Arg1 value to modify.
received output of below method as true but value did not change
Implementation:
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
static extern bool SetDoubleClickTime(uint Arg1);
SystemParametersInfo
I have also tried with SystemParametersInfo
received output of below method as true but value did not change
Implementation:
[DllImport("User32.dll")]
static extern bool SystemParametersInfo(int uiAction, int uiParam, IntPtr ipParam, int fWinIni);
var result= SystemParametersInfo(20, 200, IntPtr.Zero, 2);
This one worked for me even for values as low as 100ms. Did you try to GetDoubleClickTime() after setting it to check whether your value was actually set?
using System;
using System.Runtime.InteropServices;
class Program
{
[DllImport("user32.dll")]
public static extern int GetDoubleClickTime();
[DllImport("user32.dll")]
public static extern bool SetDoubleClickTime(uint Arg1);
public static void Main()
{
var time = GetDoubleClickTime();
Console.WriteLine(time);
SetDoubleClickTime(4200);
time = GetDoubleClickTime();
Console.WriteLine(time);
}
}
all!
Please, help me with any advice with my problem: I build GUI WinForms application and now I want to attach console to it. I found this is not as much easy as it seems before. But I found good solution here: How do I show a console output/window in a forms application? Below the code from rag answer.
using System;
using System.Runtime.InteropServices;
namespace SomeProject
{
class GuiRedirect
{
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool AttachConsole(int dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern IntPtr GetStdHandle(StandardHandle nStdHandle);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetStdHandle(StandardHandle nStdHandle, IntPtr handle);
[DllImport("kernel32.dll", SetLastError = true)]
private static extern FileType GetFileType(IntPtr handle);
private enum StandardHandle : uint
{
Input = unchecked((uint)-10),
Output = unchecked((uint)-11),
Error = unchecked((uint)-12)
}
private enum FileType : uint
{
Unknown = 0x0000,
Disk = 0x0001,
Char = 0x0002,
Pipe = 0x0003
}
private static bool IsRedirected(IntPtr handle)
{
FileType fileType = GetFileType(handle);
return (fileType == FileType.Disk) || (fileType == FileType.Pipe);
}
public static void Redirect()
{
if (IsRedirected(GetStdHandle(StandardHandle.Output)))
{
var initialiseOut = Console.Out;
}
bool errorRedirected = IsRedirected(GetStdHandle(StandardHandle.Error));
if (errorRedirected)
{
var initialiseError = Console.Error;
}
AttachConsole(-1);
if (!errorRedirected)
SetStdHandle(StandardHandle.Error, GetStdHandle(StandardHandle.Output));
}
}
This code works as charm except one downside: non-latin letters outputs to console in strange encoding (but if redirected to file, they are in right encoding). I need to redirect both StdOut and StdErr, and if I change any part of the code it stops redirecting.
Thanks to all who share their wisdom with me in comments!
SetConsoleOutputCP was the answer.
Don't forget put this to other definitions of the class.
[DllImport("kernel32.dll")]
static extern bool SetConsoleOutputCP(uint wCodePageID);
And than add call of the SetConsoleOutputCP(desired codepage); to Redirect() method.
I'm trying to use late binding on CreateProcess function in kernel32.dll, however, it returns a null value unlike any other function.
Here's the code I'm using for the late binding
public abstract class LateBinding
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, BestFitMapping = false, SetLastError = true), SuppressUnmanagedCodeSecurity()]
private static extern LBHandle LoadLibrary(string fileName);
[DllImport("kernel32.dll"), SuppressUnmanagedCodeSecurity()]
private static extern IntPtr GetProcAddress(LBHandle hModule, string procname);
private Delegate Result = default(Delegate);
public Delegate Call(string library, string method, Type type)
{
LBHandle Lib = LoadLibrary(library);
if (!Lib.IsInvalid && !Lib.IsClosed)
{
Result = Marshal.GetDelegateForFunctionPointer(GetProcAddress(Lib, method), type);
Lib.Close();
}
return Result;
}
}
[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
public sealed class LBHandle : SafeHandleZeroOrMinusOneIsInvalid
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool FreeLibrary(IntPtr hModule);
private LBHandle() : base(true) { }
protected override bool ReleaseHandle()
{
return FreeLibrary(handle);
}
}
and this how I invoke the function
private delegate bool dCreateProcess(string applicationName, string commandLine, IntPtr processAttributes, IntPtr threadAttributes, bool inheritHandles, uint creationFlags, IntPtr environment, string currentDirectory, ref STARTUP_INFORMATION startupInfo, ref PROCESS_INFORMATION processInformation);
dCreateProcess CreateProcess = Call("kernel32.dll", "CreateProcess", typeof(dCreateProcess)) as dCreateProcess;
There is no function named CreateProcess in kernel32. It exists in two versions CreateProcessA (ANSI) and CreateProcessW (Unicode). You can see that at the button the documentation for CreateProcess on MSDN.
This is not unique to CreateProcess almost every Win32 API function that takes a string will have an A and a W version.
The following is what you want:
dCreateProcess CreateProcess = Call("kernel32.dll", "CreateProcessW", typeof(dCreateProcess)) as dCreateProcess;
See also What is the difference between CreateProcess and CreateProcessA?
kernel32.dll does not actually export a function entry point with the name CreateProcess - it's either CreateProcessA or in your case CreateProcessW for unicode (Wide) arguments.
Is there a way to call "IsWow64Process" function from kernel32 capitalized? Like "ISWOW64PROCESS"? Or completely lowered like "iswow64process"?
And if no, are there any hack-arrounds to achieve this task? Thanks!
C# is a case sensitive language, but you can define the pinvoke call any way you like, you just need to be consistent. You can map the EntryPoint in your PInvoke call and define the function to be all uppercase like this:
[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi, EntryPoint = "IsWow64Process")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ISWOW64PROCESS([In] IntPtr processHandle,
[Out, MarshalAs(UnmanagedType.Bool)] out bool wow64Process);
private void button1_Click_2(object sender, EventArgs e)
{
bool is64;
ISWOW64PROCESS(Process.GetCurrentProcess().Handle, out is64);
MessageBox.Show(is64.ToString());
}
The DllImportAttribute.EntryPoint field allows you to specify the real name of the imported function.
Directly from the example at that link are two lines that show how you can rename the MessageBox function:
[DllImport("user32.dll", CharSet = CharSet.Unicode, EntryPoint = "MessageBox")]
public static extern int MyNewMessageBoxMethod(IntPtr hWnd, String text, String caption, uint type);