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

标签 c# .net shell native shell32

我有以下code :

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

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

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

提前致谢。

最佳答案

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

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

从技术上讲,您可以通过调用 Marshal.ReleaseComObject() 来加快速度。它大致相当于 IDisposable.Dispose(),这是 RCW 不实现的方法,因为很难看到 COM 接口(interface)指针上的间接引用。不过,使用它是一个很好的方法,中间的不当行为根本没有任何影响,因为你错过了一个引用,并导致你的程序崩溃,“COM 对象已与其底层 RCW 分离,无法使用”。只是简单的 shell 元素引用不需要,特别是当您快速消耗它时。

关于c# - 从托管代码调用 SHCreateItemFromParsingName 时是否需要释放资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9210723/

相关文章:

c# - 泛型的继承

java - JNA 将 Java String 映射到 PCWSTR

c# - 使用 IPAddress.Any 获取客户端的 IP

c# - 抽象自动映射器预测

c# - 现有项目的 AWS CDK Init

linux - 如何从 shell 脚本中的命令行参数中检索值

linux - 将变量拆分为多个变量

c# - 如何将 HTTP header 添加到 Web 服务调用?

c# - 如何序列化此 .NET 集合项?

C#, Foreach 中的项目