访问不存在的缩略图

2024-03-16

我制作了一个应用程序,可以向您显示计算机中的文件列表。每当您单击列表中的任何项目时,它旁边的小图片框都会显示相应文件的缩略图。我在 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;

但是,如果缩略图尚不存在,我会遇到异常:

当前 ShellObject 没有有效的缩略图处理程序或 提取此特定的缩略图时出现问题 外壳对象。 ---> System.Runtime.InteropServices.COMException:类 未注册(HRESULT 异常:0x80040154 (REGDB_E_CLASSNOTREG))

See 如何在 Windows 资源管理器中刷新文件的缩略图? https://stackoverflow.com/questions/3555799/how-do-i-refresh-a-files-thumbnail-in-windows-explorer问题和代码snippet http://pastebin.com/7VnfiKX6寻找潜在的线索。


下面是一段提取缩略图位图的代码(仅使用 Windows Vista 或更高版本)。它是基于酷IShellItemImageFactory 接口 http://msdn.microsoft.com/en-us/library/windows/desktop/bb761084.aspx:

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

补充笔记:

  • The GetImage方法有各种有趣的标志(SIIGBF)你可以玩。
  • 出于性能原因,您可以缓存工厂。例如,.PDF 文件需要整个 Adob​​e Reader .exe 在后台加载。
  • 与 shell(Windows 资源管理器)对话时,您需要确保您的进程以相同的速度运行用户访问控制级别与 shell 相比,否则出于安全原因,某些操作将会失败。例如,如果您在 Visual Studio 中通过 F5 或 CTRL+F5 运行进程,并且您的 Visual Studio 以管理员身份运行,则您的进程可能无法检索缩略图,但在双击 .exe 运行时它将起作用。来自探险家。这REGDB_E_CLASSNOTREG是在这些情况下您可能会遇到的一种典型错误。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

访问不存在的缩略图 的相关文章

随机推荐

  • TFS2012 - 无法上传大于 5MB 的文件

    我正在虚拟机 Windows Azure 内 上运行 TFS 2012 安装 一切工作正常 除了无法签入大于 5MB 的文件 在客户端 它显示 请求已中止 请求已取消 在服务器端 事件日志包含一条错误消息
  • 更改两级 DropdownButtonFormField :应该只有一项具有 [DropdownButton] 的值

    尽管这里有多个条目似乎有类似的问题 但我无法让它真正发挥作用 我有两个依赖的 DropdownButtonFormFields 的设置 其中第二个在第一个列表更改后更改为另一个列表 我能够将问题分解为第二个选择的选定值的持续剩余 我预计它会
  • 如果我使用 APNs 身份验证密钥,是否需要 APNs 证书?

    我正在使用 Flutter 和 Firebase 编写一个跨平台应用程序 我一直致力于发送通知 它在 Android 上完美运行 我通过 firebase 管理功能 sdk 发送消息 没有任何问题 该请求如下所示 const payload
  • 'UITableView' 没有 @interface 声明选择器 'initWithStyle:reuseIdentifiers

    我是 iOS 开发新手 正在寻求有关 UITableView 问题的帮助 好吧 我正在研究有关 UITableView 代码的所有内容 并且在开发过程中 当我尝试重用标识符时 如果界面上没有要创建的单元格 XCode 会显示以下消息 UIT
  • gnuplot:图例隐藏在数据后面

    我是 gnuplot 的新手 在绘制堆积直方图时 我发现图例隐藏在数据后面 有没有办法将图例放在数据上方 非常感谢你的帮助 编辑 我目前正在使用设置键外部底部将图例放置在外部 但这不是我想要的最佳解决方案 最近的版本允许将图例的背景设为白色
  • Unity3D 中 Update() 循环方法内的执行顺序

    我正在尝试找到合适的词语来描述我遇到的问题 希望这能解释问题 我有两个Update 两个不同类中的方法 并且一个类中的某些功能依赖于另一个类中的数据 代码 A 依赖于代码 B 的数据 使用调试日志 我发现代码B的Update 在代码 A 之
  • 如何从 HttpPost Create 操作方法中了解选定的复选框?

    我之间有多对多关系Student and Course 链接实体集是Enrollment 为了简单起见 它们都定义如下 Models public class Course public int Id get set public stri
  • 共享指针递归删除递归数据结构导致堆栈溢出

    我有许多长链接列表 它们最多有 20 000 个项目 它们有不同的起点 但最终可以从某个节点开始指向同一个节点 我决定让这样的链表一起成长并共享它们之间的记忆 这就是为什么我决定使用共享指针实现链表 include
  • Google 或其他搜索引擎执行 JavaScript 吗?

    我只是想知道 Google 或其他搜索引擎是否在您的网页上执行 JavaScript 例如 如果您使用 JavaScript 设置标题标签 Google 搜索引擎会看到它吗 出于 SEO 目的进行的一些实验表明 至少大公司 例如 Googl
  • 将 IDENTITY 转换为数据类型 int 时出现算术溢出错误 [已关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 通过 vb 代码运行时 将 IDENTITY 转换为数据类型 int 时发生算术溢出错误 但是当我执行存储过程时 数据会
  • AngularJS - 获取字段的标签文本

    Question 我想知道 AngularJS 获取字段标签的 最佳实践 方法是什么 使用 jQuery 您只需使用 label for 查询进行查询 然后提取文本 虽然用 AngularJS 可以做到这一点 但总感觉有些不对劲 假设您的
  • 使用 Python 将带有内嵌图像的电子邮件发送到 Gmail

    我的目标是使用 Python 向具有内嵌图像的 Gmail 用户发送电子邮件 无法在线托管此图像 然后通过href 由于图像的敏感性 来自我的工作的数据 我尝试过编码base64版本变成HTML然后发送的是HTML 但众所周知这是行不通的
  • 错误:GooglePlayServicesUtil:发生内部错误。请参阅日志以获取详细信息。我该如何解决?

    我花了无数的时间试图弄清楚这个 google Drive android api 并且我一直在试图弄清楚如何使用它 这让我自己感到非常沮丧 我正在使用入门链接 https developers google com drive androi
  • 无法使用 selenium 和 read_html 从宏观趋势检索数据来创建数据框?

    我想将宏观趋势数据导入 pandas 数据框架 从网站的页面源来看 数据似乎位于 jqxgrid 中 我尝试使用 pandas beautiful soup 和 read html 函数 但没有找到表 我目前正在尝试使用硒来提取数据 我希望
  • 如何解析/编码二进制消息格式?

    我需要用 Java 解析和编码为旧的二进制消息格式 我开始使用 DataOutputStream 来读取 写入基元类型 但我遇到的问题是消息格式与字节偏移量不能很好地对齐并且包含位标志 例如我必须处理这样的消息 uint32 b b uin
  • 如果 setUpClass 抛出异常,如何使 python 单元测试失败

    我在使用 python setUpClass 时遇到了一些问题 例如考虑以下情况 class MyTest unittest case TestCase classmethod def setUpClass cls print Test s
  • 定义一个不平凡的 Scala 案例类是否合适?

    我今天正在定义一个 Scala 类 我想 我需要一个equals方法和一个hashCode方法 和一个copy方法也会很方便 我将把它变成一个案例类 我的类已经有一堆其他代码 而且绝不是微不足道的 很好 一切都有效 但是当教科书处理案例类时
  • 获取Makefile中的源代码结构

    我正在开发一个 C 项目 我决定将源代码及其对象放在不同的目录中 根目录有类似这样的内容 SmartC tree L 1 built doc Makefile README md src tests trash 因此 在 src 和buil
  • Type.GetFields() - 只返回“public const”字段

    我想调用 Type GetFields 并且只返回声明为 public const 的字段 到目前为止我有这个 type GetFields BindingFlags Static BindingFlags Public 但这还包括 公共静
  • 访问不存在的缩略图

    我制作了一个应用程序 可以向您显示计算机中的文件列表 每当您单击列表中的任何项目时 它旁边的小图片框都会显示相应文件的缩略图 我在 Windows 7 上使用 C 为了获取缩略图 我重复使用了另一个问题中发布的方法 首先 我参考了 Wind