Retrieving Associated File Icon in .NET Core on Win, Linux & Mac



One of the major challenges of writing a desktop applications on .Net Core would be accessing the OS specific details. One such detail would be accessing the icon associated with a specific file type. On Windows this is pretty straightforward. 

On Windows OS

Here's an example C# code to extract the icon associated with a file on Windows OS using .NET Core:


  
using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

namespace FileIconExtractor
{
    class Program
    {
        static void Main(string[] args)
        {
            string filePath = @"C:\path\to\file"; // Replace with the path to the file you want to extract the icon from

            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Console.WriteLine("This code only works on Windows.");
                return;
            }

            // Get the icon associated with the file
            Icon fileIcon = Icon.ExtractAssociatedIcon(filePath);

            if (fileIcon == null)
            {
                Console.WriteLine("Could not find icon for file.");
                return;
            }

            // Convert the icon to a bitmap
            Bitmap fileBitmap = fileIcon.ToBitmap();

            // Save the bitmap to a file (optional)
            fileBitmap.Save("icon.png");
        }
    }
}
  
  
  


This code uses the Icon.ExtractAssociatedIcon() method to retrieve the icon associated with a given file and then converts the icon to a bitmap. Note that the code assumes that the file path is a valid path on the Windows file system.

Overall, extracting file icons on Windows OS using .NET Core is relatively straightforward since the Icon.ExtractAssociatedIcon() method is available in the System.Drawing namespace, which is part of the .NET Core framework.

On Linux OS

On Linux we can use a slightly different approach. We could use gio command-line tool to retrieve the icon name for a given file and then loads the corresponding icon file into a bitmap. Note that the icon file path is constructed based on the icon name and assumes that the icon file is located at /usr/share/icons/{iconName}/places/64/folder.png.



using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;

namespace FileIconExtractor
{
    class Program
    {
        static void Main(string[] args)
        {
            string filePath = "/path/to/file"; // Replace with the path to the file you want to extract the icon from

            if (!RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                Console.WriteLine("This code only works on Linux.");
                return;
            }

            string iconName = GetIconNameForFile(filePath);

            if (iconName == null)
            {
                Console.WriteLine("Could not find icon for file.");
                return;
            }

            // Build the path to the icon file
            string iconPath = Path.Combine("/usr/share/icons", iconName, "places/64/folder.png");

            if (!File.Exists(iconPath))
            {
                Console.WriteLine("Could not find icon file at path: " + iconPath);
                return;
            }

            // Load the icon file into a bitmap
            var iconBitmap = new System.Drawing.Bitmap(iconPath);

            // Save the bitmap to a file (optional)
            iconBitmap.Save("icon.png");
        }

        static string GetIconNameForFile(string filePath)
        {
            // Use the "gio" command-line tool to get the icon name for the file
            var processStartInfo = new ProcessStartInfo("gio", "info " + filePath)
            {
                RedirectStandardOutput = true
            };

            var process = Process.Start(processStartInfo);
            process.WaitForExit();

            string output = process.StandardOutput.ReadToEnd().Trim();

            // Parse the icon name from the output
            string prefix = "standard::icon:";
            int prefixIndex = output.IndexOf(prefix);

            if (prefixIndex == -1)
            {
                return null;
            }

            string suffix = ", ";
            int suffixIndex = output.IndexOf(suffix, prefixIndex + prefix.Length);

            if (suffixIndex == -1)
            {
                suffix = "\n";
                suffixIndex = output.IndexOf(suffix, prefixIndex + prefix.Length);
            }

            if (suffixIndex == -1)
            {
                return null;
            }

            return output.Substring(prefixIndex + prefix.Length, suffixIndex - prefixIndex - prefix.Length);
        }
    }
}



Note that the gio command-line tool is part of the GIO (GNOME Input/Output) library, which may not be installed on all Linux systems. In addition, the path to the icon file assumes that the system is using the GNOME desktop environment and that the icon theme is set to the default GNOME icon theme. If the system is using a different desktop environment or icon theme, the icon file path may need to be modified.

Overall, achieving seamless extraction of file icons on Linux OS using .NET Core can be challenging due to the variety of desktop environments and icon themes available on Linux systems, as well as the need to use platform-specific tools and APIs to retrieve the icon for a given file.

On Mac OS

One of the major challenges in achieving seamless extraction of file icons on Mac OS using .NET Core is the platform-specific nature of the operation. Mac OS uses a different system for managing file icons compared to other operating systems, which means that platform-specific APIs and frameworks must be used to retrieve the icon for a given file.

Another challenge is ensuring that the necessary dependencies are available on the target system. For example, the CoreServices framework used in the example code is a native macOS framework, which means that it is not available on other operating systems. This means that you would need to ensure that the necessary dependencies are installed on the target system before running the code.

Overall, achieving seamless extraction of file icons on Mac OS using .NET Core requires a good understanding of the platform-specific APIs (which most of us Windows app developers lack) and frameworks involved, as well as careful consideration of the dependencies required to run the code on the target system.

In the example code I provided below, I used the CoreServices framework to retrieve the UTI and associated icon for a given file. However, using platform-specific APIs and frameworks means that the code will only work on Mac OS and will need to be modified if you want to run it on another operating system.


using System;
using System.Drawing;
using System.IO;

namespace FileIconExtractor
{
    class Program
    {
        static void Main(string[] args)
        {
            string filePath = "/path/to/file"; // Replace with the path to the file you want to extract the icon from

            // Create a stream for the file
            using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                // Get the file's UTI (Uniform Type Identifier) using the CoreServices framework
                var uti = CoreServices.LSCopyKindStringForURL(new Uri(filePath), out _);

                // Get the icon for the UTI using the CoreServices framework
                var iconHandle = CoreServices.IconServicesGetIconRefFromTypeInfo(uti, out _);

                // Convert the icon to a bitmap
                var iconBitmap = Icon.FromHandle(iconHandle).ToBitmap();

                // Save the bitmap to a file (optional)
                iconBitmap.Save("icon.png");
            }
        }
    }
}

// Helper class to interact with the CoreServices framework
static class CoreServices
{
    [System.Runtime.InteropServices.DllImport("/System/Library/Frameworks/CoreServices.framework/CoreServices")]
    static extern IntPtr UTTypeCreatePreferredIdentifierForTag(IntPtr inTagClass, IntPtr inTag, IntPtr inConformingToUTI);

    [System.Runtime.InteropServices.DllImport("/System/Library/Frameworks/CoreServices.framework/CoreServices")]
    static extern IntPtr LSCopyKindStringForURL(IntPtr inURL, out IntPtr outError);

    [System.Runtime.InteropServices.DllImport("/System/Library/Frameworks/CoreServices.framework/CoreServices")]
    static extern int IconServicesGetIconRefFromTypeInfo(IntPtr inTypeInfo, out IntPtr outIconRef);

    public static string UTTypeCreatePreferredIdentifierForTag(string tagClass, string tag, string conformingToUTI = null)
    {
        var tagClassHandle = new IntPtr(tagClass.Length == 4 ? BitConverter.ToInt32(new[] { tagClass[0], tagClass[1], tagClass[2], tagClass[3] }, 0) : 0);
        var tagHandle = new IntPtr(tag.Length == 4 ? BitConverter.ToInt32(new[] { tag[0], tag[1], tag[2], tag[3] }, 0) : 0);
        var conformingToUTIHandle = string.IsNullOrEmpty(conformingToUTI) ? IntPtr.Zero : new IntPtr(conformingToUTI.Length == 4 ? BitConverter.ToInt32(new[] { conformingToUTI[0], conformingToUTI[1], conformingToUTI[2], conformingToUTI[3] }, 0) : 0);

        var utiHandle = UTTypeCreatePreferredIdentifierForTag(tagClassHandle, tagHandle, conformingToUTIHandle);

        return Marshal.PtrToStringAnsi(utiHandle);
    }
}


This code uses the CoreServices framework to retrieve the UTI (Uniform Type Identifier) and associated icon for the specified file path. It then converts the icon to a bitmap and optionally saves it to a file. Note that this code requires the System.Drawing.Common package to be installed in your .NET Core project.

Disclaimer

Unfortunately I could only test sinppets in my VM and not on the actual system. Try to improve the core to suit your specific need. But at the least, unlike how I started with a lot of struggle, now you have gross level code snippet that you can improvise and save some time.

COMMENTS

Name

Code,1,Free Stuff,2,History,1,Management & Leadership,2,Security,2,
ltr
item
ManageMag: Retrieving Associated File Icon in .NET Core on Win, Linux & Mac
Retrieving Associated File Icon in .NET Core on Win, Linux & Mac
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZhTGcikb7yr0lZirSyHibKYc2croFMjL0t5kHgX9ck0q9E9qiGHZ62pvnQ2cBonAuDuhNk4heCuj758SZIA41UQWUdk_kghFqCOqi8iWbNNg3O4RlhF7g7k2gvVWRlyEFDkO791mt212lbAYwqurgmawGYNdPNt69kPgjQMQa0dyqXv-fYMG1YDmy/w640-h360/suru-icon-set.jpg
https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZhTGcikb7yr0lZirSyHibKYc2croFMjL0t5kHgX9ck0q9E9qiGHZ62pvnQ2cBonAuDuhNk4heCuj758SZIA41UQWUdk_kghFqCOqi8iWbNNg3O4RlhF7g7k2gvVWRlyEFDkO791mt212lbAYwqurgmawGYNdPNt69kPgjQMQa0dyqXv-fYMG1YDmy/s72-w640-c-h360/suru-icon-set.jpg
ManageMag
http://www.managemag.com/2023/04/one-of-major-challenges-of-writing.html
http://www.managemag.com/
http://www.managemag.com/
http://www.managemag.com/2023/04/one-of-major-challenges-of-writing.html
false
3228987248158602567
UTF-8
Loaded All Posts Not found any posts VIEW ALL Readmore Reply Cancel reply Delete By Home PAGES POSTS View All RECOMMENDED FOR YOU LABEL ARCHIVE SEARCH ALL POSTS Not found any post match with your request Back Home Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sun Mon Tue Wed Thu Fri Sat January February March April May June July August September October November December Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec just now 1 minute ago $$1$$ minutes ago 1 hour ago $$1$$ hours ago Yesterday $$1$$ days ago $$1$$ weeks ago more than 5 weeks ago Followers Follow THIS PREMIUM CONTENT IS LOCKED STEP 1: Share to a social network STEP 2: Click the link on your social network Copy All Code Select All Code All codes were copied to your clipboard Can not copy the codes / texts, please press [CTRL]+[C] (or CMD+C with Mac) to copy