首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PInvoke CreateDesktop

PInvoke CreateDesktop
EN

Stack Overflow用户
提问于 2009-09-16 17:24:08
回答 2查看 3.6K关注 0票数 1

我正在尝试以一种传递标志的方式来PInvoke CreateDesktop,以便由子进程继承桌面。声明如下:

代码语言:javascript
复制
[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;
        }

我的用法如下:

代码语言:javascript
复制
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);

不幸的是,它不能工作,我得到了以下错误:

代码语言:javascript
复制
System.Runtime.InteropServices.MarshalDirectiveException: Cannot marshal 'parameter #6': Invalid managed/unmanaged type combination (this value type must be paired with Struct).

你知道我做错了什么吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-09-16 17:35:21

尝试将参数#6更改为

代码语言:javascript
复制
static extern IntPtr CreateDesktop(..., [In] ref SECURITY_ATTRIBUTES lpsa);

(这将进行编译,并且不会在运行时抛出异常,但我仅使用伪参数对其进行了测试。)

CreateDesktop的C++声明进行比较

代码语言:javascript
复制
HDESK WINAPI CreateDesktop(..., __in_opt LPSECURITY_ATTRIBUTES lpsa);
                                  ↑      ↑ ↑
                                  [In] ref SECURITY_ATTRIBUTES lpsa

LP代表“长指针”,即LPSECURITY_ATTRIBUTES是指向SECURITY_ATTRIBUTES结构的指针。因此,在C#中,您需要通过引用传递结构实例(值类型)。

票数 5
EN

Stack Overflow用户

发布于 2009-09-16 17:35:54

请考虑使用以下原型:

代码语言:javascript
复制
    [DllImport("user32", EntryPoint = "CreateDesktopW", CharSet = CharSet.Unicode, SetLastError = true)]
    public static extern IntPtr CreateDesktop(string lpszDesktop, IntPtr lpszDevice, IntPtr pDevmode, int dwFlags,
                                              int dwDesiredAccess, IntPtr lpsa);

然后,要调用它,只需创建一个固定的句柄:

代码语言:javascript
复制
        GCHandle handle = GCHandle.Alloc(myStruct);
        try {
            IntPtr pinnedAddress = handle.AddrOfPinnedObject();
        }
        finally {
            handle.Free();
        }

这对于使用结构调用PInvoke的方法非常有效。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1434363

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档