从托管代码调用SHCreateItemFromParsingName时是否需要释放资源

本文关键字:释放资源 是否 托管代码 调用 SHCreateItemFromParsingName | 更新日期: 2023-09-27 18:23:49

我有以下代码:

[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);

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

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

提前谢谢。

从托管代码调用SHCreateItemFromParsingName时是否需要释放资源

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

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

从技术上讲,你可以通过调用Marshal.ReleaseComObject()来加快速度。它大致相当于IDisposable.Dispose(),一个RCW不实现的方法,因为很难在COM接口指针上看到间接引用。不过,使用它是一个很好的方法,介于两者之间的不当行为根本没有影响,因为你错过了一个引用,并用"与底层RCW分离的COM对象无法使用"破坏了你的程序。只是不需要一个简单的shell项引用,尤其是当您快速使用它时。