gpt4 book ai didi

c# - 访问不存在的缩略图

转载 作者:可可西里 更新时间:2023-11-01 08:49:26 27 4
gpt4 key购买 nike

我制作了一个应用程序,可以向您显示计算机中的文件列表。每当您单击列表中的任何项目时,它旁边的一个小 PictureBox 应该会显示相应文件的缩略图。我在 Windows 7 上使用 C#。

为了获取缩略图,我重复了另一个问题中发布的方法。首先,我引用了 Windows API 代码包。然后,我使用以下代码:

ShellFile shellFile = ShellFile.FromFilePath(fullPathToFile);
myPictureBox.Image = shellFile.Thumbnail.LargeBitmap;

这并不总是有效。有时,显示的缩略图仅仅是“默认应用程序”图标。我发现真正的缩略图只有在 Windows 之前为该文件生成缩略图并将其存储在缩略图缓存中时才会显示。这意味着我必须手动打开一个文件夹,等待 Windows 为每个文件生成缩略图,然后我的应用程序才能看到这些缩略图。

我的程序如何强制 Windows 7 在使用它们之前生成真实的缩略图?

更新(来自 Li0liQ)

可以通过添加 FormatOption 来强制获取缩略图:

ShellFile shellFile = ShellFile.FromFilePath(fullPathToFile);
shellFile.Thumbnail.FormatOption = ShellThumbnailFormatOption.ThumbnailOnly;
myPictureBox.Image = shellFile.Thumbnail.LargeBitmap;

但是,如果缩略图还不存在,我会得到一个异常(exception):

The current ShellObject does not have a valid thumbnail handler or there was a problem in extracting the thumbnail for this specific shell object. ---> System.Runtime.InteropServices.COMException: Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))

参见 How do I refresh a file's thumbnail in Windows Explorer?问题和代码 snippet寻找潜在的线索。

最佳答案

这是一段提取缩略图位图的代码(仅使用 Windows Vista 或更高版本)。它基于很酷的 IShellItemImageFactory interface :

    static void Main(string[] args)
{
// you can use any type of file supported by your windows installation.
string path = @"c:\temp\whatever.pdf";
using (Bitmap bmp = ExtractThumbnail(path, new Size(1024, 1024), SIIGBF.SIIGBF_RESIZETOFIT))
{
bmp.Save("whatever.png", ImageFormat.Png);
}
}

public static Bitmap ExtractThumbnail(string filePath, Size size, SIIGBF flags)
{
if (filePath == null)
throw new ArgumentNullException("filePath");

// TODO: you might want to cache the factory for different types of files
// as this simple call may trigger some heavy-load underground operations
IShellItemImageFactory factory;
int hr = SHCreateItemFromParsingName(filePath, IntPtr.Zero, typeof(IShellItemImageFactory).GUID, out factory);
if (hr != 0)
throw new Win32Exception(hr);

IntPtr bmp;
hr = factory.GetImage(size, flags, out bmp);
if (hr != 0)
throw new Win32Exception(hr);

return Bitmap.FromHbitmap(bmp);
}

[Flags]
public enum SIIGBF
{
SIIGBF_RESIZETOFIT = 0x00000000,
SIIGBF_BIGGERSIZEOK = 0x00000001,
SIIGBF_MEMORYONLY = 0x00000002,
SIIGBF_ICONONLY = 0x00000004,
SIIGBF_THUMBNAILONLY = 0x00000008,
SIIGBF_INCACHEONLY = 0x00000010,
SIIGBF_CROPTOSQUARE = 0x00000020,
SIIGBF_WIDETHUMBNAILS = 0x00000040,
SIIGBF_ICONBACKGROUND = 0x00000080,
SIIGBF_SCALEUP = 0x00000100,
}

[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
private static extern int SHCreateItemFromParsingName(string path, IntPtr pbc, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IShellItemImageFactory factory);

[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("bcc18b79-ba16-442f-80c4-8a59c30c463b")]
private interface IShellItemImageFactory
{
[PreserveSig]
int GetImage(Size size, SIIGBF flags, out IntPtr phbm);
}

补充说明:

  • GetImage 方法有各种有趣的标志 (SIGBF),您可以使用。
  • 出于性能原因,您可以缓存工厂。例如,.PDF 文件需要在后台加载整个 Adob​​e Reader .exe。
  • 在与 shell(Windows 资源管理器)对话时,您要确保您的进程运行在与 shell 相同的UAC 级别,否则,出于安全原因,某些操作将失败。因此,例如,如果您在 Visual Studio 中通过 F5 或 CTRL+F5 运行您的进程,并且您的 Visual Studio 以管理员身份运行,您的进程可能无法检索缩略图,而当双击 .exe 运行时它会工作来自探险家。 REGDB_E_CLASSNOTREG 是您在这些情况下可能遇到的一种典型错误。

关于c# - 访问不存在的缩略图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12654835/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com