PInvoke CreateDesktop

Grz*_*nio 1 .net c# pinvoke interop

我试图通过传递标志来通过子进程继承桌面的PInvoke CreateDesktop.声明如下:

[DllImport("user32", EntryPoint = "CreateDesktopW", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern IntPtr CreateDesktop(string lpszDesktop, IntPtr lpszDevice, IntPtr pDevmode, int dwFlags,
                                                  int dwDesiredAccess, [MarshalAs(UnmanagedType.LPStruct)] SECURITY_ATTRIBUTES lpsa);

        [StructLayout(LayoutKind.Sequential)]
        public struct SECURITY_ATTRIBUTES
        {
            public int nLength;
            public IntPtr lpSecurityDescriptor;
            public int bInheritHandle;
        }
Run Code Online (Sandbox Code Playgroud)

我用它如下:

Win32.SECURITY_ATTRIBUTES sa = new Win32.SECURITY_ATTRIBUTES();
            sa.nLength = Marshal.SizeOf(sa);
            sa.bInheritHandle = 1;
            testDesktopHandle = Win32.CreateDesktop(name, IntPtr.Zero, IntPtr.Zero, 0, Win32.GENERIC_ALL, sa);
Run Code Online (Sandbox Code Playgroud)

不幸的是,它不起作用,我收到以下错误:

System.Runtime.InteropServices.MarshalDirectiveException: Cannot marshal 'parameter #6': Invalid managed/unmanaged type combination (this value type must be paired with Struct).
Run Code Online (Sandbox Code Playgroud)

我有什么想法我做错了吗?

dtb*_*dtb 5

尝试将参数#6更改为

static extern IntPtr CreateDesktop(..., [In] ref SECURITY_ATTRIBUTES lpsa);
Run Code Online (Sandbox Code Playgroud)

(这会编译并且不会在运行时抛出异常,但我只是使用伪造的参数对其进行了测试.)

CreateDesktop的 C++声明比较:

HDESK WINAPI CreateDesktop(..., __in_opt LPSECURITY_ATTRIBUTES lpsa);
                                  ?      ? ?
                                  [In] ref SECURITY_ATTRIBUTES lpsa
Run Code Online (Sandbox Code Playgroud)

LP代表"长指针",LPSECURITY_ATTRIBUTES即是指向SECURITY_ATTRIBUTES结构的指针.所以在C#中你需要通过引用传递你的struct实例(值类型).