如何以编程方式获取 Visual Studio 使用的内置文件类型图标

How to get the built in File type icon used by Visual Studio programmatically

我正在开发一个 VSIX 项目,该项目需要在自定义工具中显示所选文件的(在解决方案资源管理器中)文件类型图标 -window。谁能告诉我如何以编程方式获取 Visual studio IDE 使用的文件类型图标?

例如为 PNG 文件获取以下图像图标(突出显示)

Icon.ExtractAssociatedIcon(*path*)很多Whosebug中提到的解决方法 threads 对我不起作用,因为它提供了 Shell 图标。

谢谢。

你应该使用 Visual Studio Image Service and Catalog。但是本文档没有解释如何获取给定文件的图像。

您将不得不使用 IVsImageService2.GetImageMonikerForFile Method。如文档中所述,您可以获得 GDI/Winforms、Win32 或 WPF 图像。这是为 WPF 的 BitmapSource 执行此操作的示例代码:

public static async Task<BitmapSource> GetWpfImageForFileAsync(AsyncPackage package, string filename, int width, int height)
{
    if (package == null)
        throw new ArgumentNullException(nameof(package));

    var svc = (IVsImageService2)await package.GetServiceAsync(typeof(SVsImageService));
    if (svc == null)
        return null;

    var mk = svc.GetImageMonikerForFile(filename);
    var atts = new ImageAttributes
    {
        StructSize = Marshal.SizeOf(typeof(ImageAttributes)),
        Format = (uint)_UIDataFormat.DF_WPF,
        LogicalHeight = width,
        LogicalWidth = height,
        Flags = (uint)_ImageAttributesFlags.IAF_RequiredFlags,
        ImageType = (uint)_UIImageType.IT_Bitmap
    };

    var obj = svc.GetImage(mk, atts);
    if (obj == null)
        return null;

    obj.get_Data(out object data);
    return (BitmapSource)data;
}

以下是您如何在包初始化时使用它的示例:

public static async Task InitializeAsync(AsyncPackage package)
{
    ThreadHelper.ThrowIfNotOnUIThread();

    // note a valid extension is sufficient
    _pngBitmap = await GetWpfImageForFileAsync(package, "whatever.png", 32, 32);

   // etc...
}