Нужно ли освобождать ресурсы при вызове SHCreateItemFromParsingName из управляемого кода? - PullRequest
2 голосов
/ 09 февраля 2012

У меня есть следующий код :

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

Она прекрасно работает, и я использую ее, чтобы получить значок ОСрастровые изображения позже.Мой вопрос:

Нужно ли освобождать какой-либо ресурс?Кто-нибудь может сказать мне, как?

Заранее спасибо.

1 Ответ

4 голосов
/ 09 февраля 2012

IShellItem - это интерфейс COM.Ваша декларация об этом с атрибутом [ComImport] гарантирует, что CLR создаст для него оболочку, RCW (Runtime Callable Wrapper).Который является управляемой оболочкой для родного интерфейса.RCW ведут себя так же, как обычные классы .NET, ими управляет сборщик мусора.С точно такими же правилами, рано или поздно сборщик мусора увидит, что ваша программа больше не имеет ссылки на RCW.И добавляет в очередь финализатора.Финализатор RCW вызывает метод IUnknown :: Release (), который уничтожает собственный COM-объект.

Другими словами, он автоматический, как и объекты .NET.

Технически вы можете поторопитьсяэто вместе с вызовом Marshal.ReleaseComObject ().Это примерно эквивалентно IDisposable.Dispose (), метод, который RCW не реализует, потому что очень трудно увидеть косвенные ссылки на указатели интерфейса COM.Использование этого метода - хороший способ выстрелить вам в ногу, хотя неправильное поведение где-то между ними вообще не имеет никакого эффекта, потому что вы пропустили ссылку, и сбой вашей программы с «COM-объектом, который был отделен от базового RCW, не может быть использован».Просто не требуется для простой ссылки на элемент оболочки, особенно если вы быстро его потребляете.

...