none
change system folder icon, C# RRS feed

  • Question

  • so I need to change the folder icon to a check mark. This change will occur when a user is done altering the file from a windows form app.

     

    the app rundown

    1. user runs app

    2. openfiledialog to find the folder needed.

    3. user uploads 5 images from file to sql server

    4.***successful upload, message appears, and folder that has been modified changes icon to "check mark"***

    The folder has a unique name, in case that was going to be brought up.

    From my research so far, I understand that a desktop.ini file is needed to change icons. Why? And is it possible to change the icon like this? Can someone point me in the right direction?

     

    Thanks

    Tuesday, September 21, 2010 12:20 AM

Answers

  • Hi knudmt26,

     

    I had reference the code form cchitsiang and my reply to make this demo. But sometimes it also cannot change immediately.

     

    using System;

    using System.IO;

    using Microsoft.Win32;

    using System.Runtime.InteropServices;

     

    namespace ConsoleApplication2

    {

        class Program

        {

            static void Main(string[] args)

            {

                Console.WriteLine("begin");

                FileInfo fileInfo = new FileInfo(@"D:\New folder\desktop.ini");

                FileAttributes fa = fileInfo.Attributes;

                FileStream fs = fileInfo.OpenWrite();

                StreamWriter sw = new StreamWriter(fs);

                sw.WriteLine("[.ShellClassInfo]");

                sw.WriteLine(@"IconResource=C:\Windows\system32\SHELL32.dll,48");

                sw.Flush();

                sw.Close();

                fs.Close();

                fileInfo.Attributes = FileAttributes.Hidden | FileAttributes.Archive | FileAttributes.System;

                RefreshIconCache();

                Console.WriteLine("end");

            }

     

            [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]

            static extern IntPtr SendMessageTimeout(

                int windowHandle,

                int Msg,

                int wParam,

                String lParam,

                SendMessageTimeoutFlags flags,

                int timeout,

                out int result);

            [Flags]

            enum SendMessageTimeoutFlags : uint

            {

                SMTO_NORMAL = 0x0,

                SMTO_BLOCK = 0x1,

                SMTO_ABORTIFHUNG = 0x2,

                SMTO_NOTIMEOUTIFNOTHUNG = 0x8

            }

     

            static void RefreshIconCache()

            {

     

                // get the the original Shell Icon Size registry string value

                RegistryKey k = Registry.CurrentUser.OpenSubKey("Control Panel").OpenSubKey("Desktop").OpenSubKey("WindowMetrics", true);

                Object OriginalIconSize = k.GetValue("Shell Icon Size");

     

                // set the Shell Icon Size registry string value

                k.SetValue("Shell Icon Size", (Convert.ToInt32(OriginalIconSize) + 1).ToString());

                k.Flush(); k.Close();

     

                // broadcast WM_SETTINGCHANGE to all window handles

                int res = 0;

                SendMessageTimeout(0xffff, 0x001A, 0, "", SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 5000, out res);

                //SendMessageTimeout(HWD_BROADCAST,WM_SETTINGCHANGE,0,"",SMTO_ABORTIFHUNG,5 seconds, return result to res)

     

                // set the Shell Icon Size registry string value to original value

                k = Registry.CurrentUser.OpenSubKey("Control Panel").OpenSubKey("Desktop").OpenSubKey("WindowMetrics", true);

                k.SetValue("Shell Icon Size", OriginalIconSize);

                k.Flush(); k.Close();

     

                SendMessageTimeout(0xffff, 0x001A, 0, "", SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 5000, out res);

     

            }

        }

    }

     

    Hope this can be helpful to your request.

     

    Best wishes,

    Mike

    -------------------------------------------------------------------

    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to the others community members reading the thread.

    Thursday, September 23, 2010 6:26 PM
    Moderator
  • Wednesday, January 11, 2012 1:40 PM
    Moderator

All replies

  • Hi knudmt26,

     

    Basically, the process of changing folder icon is..

    1. Create a desktop.ini inside the folder that setting icon of folder.

    2. Set the folder attributes to System Folder <- If not, the folder will not show any custom icon.

     

    For example for this two action, you may take a look at  

    http://www.codeproject.com/KB/files/foldericonsincsharp.aspx

     

     

    Best regards

    cchitsiang

    Tuesday, September 21, 2010 2:38 AM
  • Hi cchitsiang,

     

    Thanks for the reply. forgive me I am a novice. its actually a removable hard drive that will have the folders icons that need to be altered. the link looks good. I shall give it a try tm and post any problems. Again thanks for the reply!

    Tuesday, September 21, 2010 2:55 AM
  • Hi knudmt26

     

    You are so welcome. For you information, you may try to use relative path for icon in desktop.ini instead of absolute path for icon because you are using removable hard drive and the drive letter may will be changed next time you plugged in.

    Just anything, you may feel free to ask me :)

     

    Best regards

    cchitsiang

    Tuesday, September 21, 2010 7:50 AM
  • So, thought I would try this stuff out. I cant seem to get a folder on my system to change to a checkmark with the .ini file. I must be doing something wrong.

    .ini file

    [.shellClassInfo]

    ConfirmFileOp=0

    NoSharing

    IconFile=@%SystemRoot%\system32\shell32.dll\, -253

    IconIndex=0

    InfoTip=SomeToolTip


    maybe some help from the gurus for a novice??

    Tuesday, September 21, 2010 5:59 PM
  • nevermind that little mistake. worked from within the folder using this:

     

    [.ShellClassInfo]

    IconResource=C:\Windows\System32\SHELL32.dll, -253

    [viewState]

    mode=

    vid=

    FolderType=Generic

     

    Next question: Is there a way to make the change visible WITHOUT logging off and logging on?

    Tuesday, September 21, 2010 6:57 PM
  • Hi

     

    Think you need to rebuild the icon cache

     

    static void RefreshIconCache()
        {
    
         // get the the original Shell Icon Size registry string value
          RegistryKey k = Registry.CurrentUser.OpenSubKey("Control Panel").OpenSubKey("Desktop").OpenSubKey("WindowMetrics", true);
          Object OriginalIconSize = k.GetValue("Shell Icon Size");
    
         // set the Shell Icon Size registry string value
          k.SetValue("Shell Icon Size", (Convert.ToInt32(OriginalIconSize) + 1).ToString());
          k.Flush(); k.Close();
          
         // broadcast WM_SETTINGCHANGE to all window handles
          int res = 0;
          SendMessageTimeout(0xffff, 0x001A, 0, "", 0x0002, 5000, out res);
          //SendMessageTimeout(HWD_BROADCAST,WM_SETTINGCHANGE,0,"",SMTO_ABORTIFHUNG,5 seconds, return result to res)
    
         // set the Shell Icon Size registry string value to original value
          k = Registry.CurrentUser.OpenSubKey("Control Panel").OpenSubKey("Desktop").OpenSubKey("WindowMetrics", true);
          k.SetValue("Shell Icon Size", OriginalIconSize);
          k.Flush(); k.Close();
    
          SendMessageTimeout(0xffff, 0x001A, 0, "", 0x0002, 5000, out res);
    
        }
    

    Sorry for late reply and hope this helps.

     

    Regards

    cchitsiang

    Wednesday, September 22, 2010 10:57 AM
  • Hi knudmt26,

     

    Welcome to MSDN Forums!

     

                Console.WriteLine("begin");
                FileInfo fileInfo = new FileInfo(@"D:\New folder\desktop.ini");
                FileAttributes fa = fileInfo.Attributes;
                FileStream fs = fileInfo.OpenWrite();
                StreamWriter sw = new StreamWriter(fs);
                sw.WriteLine("[.ShellClassInfo]");
                sw.WriteLine(@"IconResource=C:\Windows\system32\SHELL32.dll,45");
                sw.Flush();
                sw.Close();
                fs.Close();
                fileInfo.Attributes = FileAttributes.Hidden|FileAttributes.Archive|FileAttributes.System;
                Console.WriteLine("end");

     

    You can use the code above to modify the icon of folder dynamically.

     

    There’s an issue with this code.

    Sometimes the folder would not display the new icon as soon as possible after we run over this code. But sometimes it will display the new one as soon as possible. I think this is the issue of the icon cache be flushed.

     

    If there’s anything unclear, please feel free to let me know.

    Have a nice day!

    Mike

    -------------------------------------------------------------------

    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to the others community members reading the thread.

    Wednesday, September 22, 2010 11:22 AM
    Moderator
  • You guys are super smart!!! Thanks to both of you for replying quickly. You both have been a great deal of help! I have learned a great deal!!!
    Wednesday, September 22, 2010 1:23 PM
  • I see that flushing the icon cache would def be the issue. However I am struggling to understand the SendMessageTimeout(). Do I have to import the win32.dll? I do not know how to utilize this snippet.
    Thursday, September 23, 2010 4:43 PM
  • Hi knudmt26,

     

    I had reference the code form cchitsiang and my reply to make this demo. But sometimes it also cannot change immediately.

     

    using System;

    using System.IO;

    using Microsoft.Win32;

    using System.Runtime.InteropServices;

     

    namespace ConsoleApplication2

    {

        class Program

        {

            static void Main(string[] args)

            {

                Console.WriteLine("begin");

                FileInfo fileInfo = new FileInfo(@"D:\New folder\desktop.ini");

                FileAttributes fa = fileInfo.Attributes;

                FileStream fs = fileInfo.OpenWrite();

                StreamWriter sw = new StreamWriter(fs);

                sw.WriteLine("[.ShellClassInfo]");

                sw.WriteLine(@"IconResource=C:\Windows\system32\SHELL32.dll,48");

                sw.Flush();

                sw.Close();

                fs.Close();

                fileInfo.Attributes = FileAttributes.Hidden | FileAttributes.Archive | FileAttributes.System;

                RefreshIconCache();

                Console.WriteLine("end");

            }

     

            [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]

            static extern IntPtr SendMessageTimeout(

                int windowHandle,

                int Msg,

                int wParam,

                String lParam,

                SendMessageTimeoutFlags flags,

                int timeout,

                out int result);

            [Flags]

            enum SendMessageTimeoutFlags : uint

            {

                SMTO_NORMAL = 0x0,

                SMTO_BLOCK = 0x1,

                SMTO_ABORTIFHUNG = 0x2,

                SMTO_NOTIMEOUTIFNOTHUNG = 0x8

            }

     

            static void RefreshIconCache()

            {

     

                // get the the original Shell Icon Size registry string value

                RegistryKey k = Registry.CurrentUser.OpenSubKey("Control Panel").OpenSubKey("Desktop").OpenSubKey("WindowMetrics", true);

                Object OriginalIconSize = k.GetValue("Shell Icon Size");

     

                // set the Shell Icon Size registry string value

                k.SetValue("Shell Icon Size", (Convert.ToInt32(OriginalIconSize) + 1).ToString());

                k.Flush(); k.Close();

     

                // broadcast WM_SETTINGCHANGE to all window handles

                int res = 0;

                SendMessageTimeout(0xffff, 0x001A, 0, "", SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 5000, out res);

                //SendMessageTimeout(HWD_BROADCAST,WM_SETTINGCHANGE,0,"",SMTO_ABORTIFHUNG,5 seconds, return result to res)

     

                // set the Shell Icon Size registry string value to original value

                k = Registry.CurrentUser.OpenSubKey("Control Panel").OpenSubKey("Desktop").OpenSubKey("WindowMetrics", true);

                k.SetValue("Shell Icon Size", OriginalIconSize);

                k.Flush(); k.Close();

     

                SendMessageTimeout(0xffff, 0x001A, 0, "", SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 5000, out res);

     

            }

        }

    }

     

    Hope this can be helpful to your request.

     

    Best wishes,

    Mike

    -------------------------------------------------------------------

    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to the others community members reading the thread.

    Thursday, September 23, 2010 6:26 PM
    Moderator
  • I really have a ton to learn. Thanks for the reply. I will take some time to review this code and understand prior to implementation.

    Thanks!

    Thursday, September 23, 2010 6:31 PM
  • Hi man,

    You’re welcome!

    If there’s anything unclear, please feel free to let me know.

     

    Best wishes,

    Mike

    Thursday, September 23, 2010 7:07 PM
    Moderator
  • Wednesday, January 11, 2012 1:40 PM
    Moderator