1

I have never created a P/Invoke wrapper method in C# because there's a way to do it "the managed way" using .NET Framework classes.

However, I have the need to invoke Win32 API function and I discovered that it's not as easy as I thought.

The function in IsWowProcess2, and the code to call it from C++ is illustrated here.

http://www.rudyhuyn.com/blog/2017/12/13/how-to-detect-that-your-x86-application-runs-on-windows-on-arm/

I've created a silly program to test it, but of course, it doesn't work:

class Program
{
    static void Main(string[] args)
    {
        var result = IsWowProcess2();
    }

    [DllImport("kernel32.dll", CharSet = CharSet.Unicode, ExactSpelling = false, PreserveSig = true)]
    private static extern MyStruct IsWowProcess2();
}

internal class MyStruct
{
    public ushort One { get; set; }
    public ushort Two { get; set; }
}

What's the correct way to create the wrapper method and how to invoke it?

SuperJMN
  • 13,110
  • 16
  • 86
  • 185
  • 1
    If you're on a recent version of the framework (specifically, 4.7.1 or later, or .NET Core) there's likely no need for this and what you want can be obtained via [`RuntimeInformation`](https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.runtimeinformation). – Jeroen Mostert Feb 06 '19 at 12:05

1 Answers1

6

Start by reading the documentation. This gives the signature as:

BOOL IsWow64Process2(
  HANDLE hProcess,
  USHORT *pProcessMachine,
  USHORT *pNativeMachine
);

As a pinvoke that is:

[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool IsWow64Process2(
    IntPtr process, 
    out ushort processMachine, 
    out ushort nativeMachine
);

I've no idea where your attempt came from but it looks nothing like the correct declaration, and in fact even the name of the function is wrong. Interop programming is all about detail and matching one binary interface to another. You don't get to invent the interface. Details like the parameters to be passed, the name of the function, etc. all need to match.

You can call it like this:

ushort processMachine;
ushort nativeMachine;
if (!IsWow64Process2(GetCurrentProcess(), out processMachine, out nativeMachine))
    throw new Win32Exception();

You also need a declaration for GetCurrentProcess. You can use this:

[DllImport("kernel32.dll")]
private static extern IntPtr GetCurrentProcess();
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490