Reputation: 115
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
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
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