Zameer
Zameer

Reputation: 115

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

I'm working on a VSIX project which requires to display the selected file's (in Solution explorer), file type icon in a Custom Tool-window. Could anyone please advise me on how to obtain the File type Icon used by Visual studio IDE programmatically?

e.g. Obtain following Image Icon (as highlighted) for PNG files enter image description here

Icon.ExtractAssociatedIcon(*path*) solution mentioned in many stackoverflow threads doesn't work for me since it provides the Shell icons.

Thank you.

Upvotes: 0

Views: 289

Answers (1)

Simon Mourier
Simon Mourier

Reputation: 138811

You're supposed to use the Visual Studio Image Service and Catalog. However this document doesn't explain how to get the image for a given file.

You'll have to use the IVsImageService2.GetImageMonikerForFile Method. As described in the document, you can get GDI/Winforms, Win32 or WPF images. Here is a sample code that does it for WPF's 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;
}

Here is how you can use it for example at package initialization:

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

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

   // etc...
}

Upvotes: 2

Related Questions