Есть задача получить эскизы фотографий из системного кэша (thumbnails).
Код на C# WPF. COM-Интерфейс IThumbnailCache возвращает хитрый ISharedBitmap, который имеет непонятное мне время жизни. Вот код:
public System.Windows.Media.ImageSource GetThumbnail(string imagePath)
{
IShellItem shItem;
Guid iIdIShellItem = new Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe");
var hr = SHCreateItemFromParsingName(imagePath, IntPtr.Zero, iIdIShellItem, out shItem);
if (hr == 0)
{
Guid IID_IUnknown = new Guid("00000000-0000-0000-C000-000000000046");
Guid CLSID_LocalThumbnailCache = new Guid("50EF4544-AC9F-4A8E-B21B-8A26180DB13F");
var type = Type.GetTypeFromCLSID(CLSID_LocalThumbnailCache);
var tbCache = (IThumbnailCache)Activator.CreateInstance(type);
ISharedBitmap bmp = null;
WTS_CACHEFLAGS cFlags;
WTS_THUMBNAILID bmpId;
hr = (int)tbCache.GetThumbnail(shItem, 128, WTS_FLAGS.WTS_EXTRACT, out bmp, out cFlags, out bmpId);
if (hr == 0)
{
var bmpPtr = IntPtr.Zero;
if (bmp.GetSharedBitmap(out bmpPtr) == 0)
{
SIZE size;
bmp.GetSize(out size);
var iSrc = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
bmpPtr, IntPtr.Zero, Int32Rect.Empty,
System.Windows.Media.Imaging.BitmapSizeOptions.FromWidthAndHeight(size.cx, size.cy));
}
else
{
return null;
}
}
else
{
return null;
}
}
return null;
вызов CreateBitmapSourceFromHBitmap падает с HRESULT: 0x88982F94.
Я сделал обертку на C++/CLI и возвращал в C# HBITMAP, полученный методом ISharedBitmap::GetSharedBitmap().
Опытным путем выяснил, что данный HRESULT: 0x88982F94 выдается, если на стороне С++ вызван ISharedBitmap->Release(). То есть, если битмап освобожден, то WPF выдаст данное исключение. Однако, в приведенном коде нет освобождения для ISharedBitmap. Почему он как-будто освобожден к моменту вызова CreateBitmapSourceFromHBitmap?
Как вообще регулируется время жизни COM-объектов, подключенных через P/Invoke?