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

これはうまく機能し、後で OS アイコンのビットマップを取得するために使用します。私の質問は:

リソースを解放する必要がありますか? 方法を教えてもらえますか?

前もって感謝します。

4

1 に答える 1

4

IShellItemはCOMインターフェイスです。[ComImport]属性を使用して宣言すると、CLRがそのラッパーであるRCW(Runtime Callable Wrapper)を確実に作成します。これは、ネイティブインターフェイスのマネージラッパーです。RCWは通常の.NETクラスと同じように動作し、ガベージコレクターによって管理されます。まったく同じルールで、遅かれ早かれ、ガベージコレクターは、プログラムにRCWへの参照がなくなったことを認識します。そして、ファイナライザーキューに入れます。RCWのファイナライザーはIUnknown::Release()メソッドを呼び出し、ネイティブCOMオブジェクトを破棄します。

つまり、.NETオブジェクトと同じように自動です。

技術的には、Marshal.ReleaseComObject()を呼び出すことで急ぐことができます。これは、IDisposable.Dispose()とほぼ同等です。これは、COMインターフェイスポインターで間接参照を確認することが非常に難しいため、RCWが実装しないメソッドです。ただし、これを使用することは足を撃つための良い方法です。参照を見逃し、「基になるRCWから分離されたCOMオブジェクトは使用できません」とプログラムをクラッシュさせるため、その間のどこかでの誤動作はまったく効果がありません。単純なシェルアイテムの参照には必要ありません。特に、すばやく消費する場合は必要ありません。

于 2012-02-09T12:59:42.270 に答える