【问题标题】:SHCreateItemFromParsingName and System.AccessViolationExceptionSHCreateItemFromParsingName 和 System.AccessViolationException
【发布时间】:2023-03-26 15:38:01
【问题描述】:

我在 COM 中迈出了第一步,但我不断收到 System.AccessViolationException,这是其中一个异常,它不会告诉你任何有价值的东西。我正在尝试使用 SHCreateItemFromParsingName 创建一个 IShellItem。我从另一个项目中复制了接口的定义,所以我知道它没有任何问题,问题很可能出在我的函数定义/调用中,这是我自己编写的,用于学习目的。

我想调用非托管函数而不返回 IShellItem 接口,而是将它的引用传递给调用中的最后一个参数。

函数声明:

[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
internal static extern uint SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string pszPath, IBindCtx pbc, Guid riid, out IShellItem ppv);

函数调用:

IShellItem file;

SHCreateItemFromParsingName(@"C:\file.txt", null, typeof(IShellItem).GUID, out file);

我发现 IDL 相当神秘,但我的理由是:

  • HRESULT = uint
  • [输入] PCWSTR = [MarshalAs(UnmanagedType.LPWStr)] 字符串
  • [输入,可选] IBindCtx = IBindCtx
  • [输入] REFIID = Guid
  • [out] void = out IShellItem

SHCreateItemFromParsingName function

【问题讨论】:

    标签: c# com com-interop access-violation


    【解决方案1】:

    问题来自 REFIID 类型参数。它不是一个 GUID(一个 16 字节的结构),而是一个 GUID 引用 (REFIID),一个指针(因此 4 或 8 个字节取决于进程位数)。

    因此,您可以使用ref 关键字定义这样的方法(因此结构将通过引用传递,作为指针):

    internal static extern uint SHCreateItemFromParsingName(
        [MarshalAs(UnmanagedType.LPWStr)] string pszPath,
        IBindCtx pbc,
        ref Guid riid,
        out IShellItem ppv);
    

    但我推荐这种更易于使用且避免到处创建/复制 GUID 的方式(您将使用与您相同的方式调用它):

    internal static extern uint SHCreateItemFromParsingName(
        [MarshalAs(UnmanagedType.LPWStr)] string pszPath,
        IBindCtx pbc,
        [MarshalAs(UnmanagedType.LPStruct)] Guid riid,
        out IShellItem ppv);
    

    【讨论】:

    • 你似乎知道你在说什么。你会推荐什么书或参考资料?我没有从我引用的 MSDN 页面中得到这个。
    • 好吧,如果你了解 C/C++ 那么 IDL 就非常接近它了。事实上,Windows SDK 中的大多数 .IDL 都有一个伴随的 .H 文件,该文件 C/C++ 。如果您查看 REFIID,它被定义为 IID* msdn.microsoft.com/en-us/library/cc237816.aspx 对于 .NET p/invoke,Adam Nathan 的“.NET 和 COM:完整的互操作性指南”可能是一个不错的起点,尽管自本书以来有些事情已经发展了很多写好了。
    猜你喜欢
    • 2013-12-22
    • 1970-01-01
    • 1970-01-01
    • 2012-04-27
    • 1970-01-01
    • 2015-01-13
    • 1970-01-01
    • 2023-04-10
    相关资源
    最近更新 更多