2

我有以下代码

[DllImport("shell32.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
static extern void SHCreateItemFromParsingName(
[In][MarshalAs(UnmanagedType.LPWStr)] string pszPath,
[In] IntPtr pbc,
[In][MarshalAs(UnmanagedType.LPStruct)] Guid iIdIShellItem,
[Out][MarshalAs(UnmanagedType.Interface, IidParameterIndex = 2)] out IShellItem iShellItem);


[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe")]
interface IShellItem
{
}

要使用此功能:

IShellItem iShellItem = null;
Guid iIdIShellItem = new Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe");
SHCreateItemFromParsingName(sourceFile, IntPtr.Zero, iIdIShellItem, out iShellItem);

它工作得很好,我以后用它来获取操作系统图标位图。我的问题是:

我需要释放任何资源吗?有人能告诉我怎么做吗?

提前致谢。

4

1 回答 1

4

IShellItem 是一个COM 接口。您使用 [ComImport] 属性对其进行声明可确保 CLR 为其创建包装器,即 RCW(运行时可调用包装器)。这是一个围绕本机接口的托管包装器。RCW 的行为就像常规的 .NET 类一样,它们由垃圾收集器管理。使用完全相同的规则,垃圾收集器迟早会看到您的程序不再引用 RCW。并放入终结器队列。RCW 的终结器调用 IUnknown::Release() 方法并销毁本机 COM 对象。

换句话说,它是自动的,就像 .NET 对象一样。

从技术上讲,您可以通过调用 Marshal.ReleaseComObject() 来加快速度。它大致相当于 IDisposable.Dispose(),这是 RCW 不实现的方法,因为很难看到对 COM 接口指针的间接引用。使用它是一个很好的方法来射击你的脚,在它之间的某个地方的不当行为根本没有任何影响,因为你错过了一个引用并且你的程序崩溃了“不能使用已经与其底层 RCW 分离的 COM 对象”。只是不需要简单的外壳项目引用,尤其是当您快速使用它时。

于 2012-02-09T12:59:42.270 回答