c# - Shell Icon Overlay Interop Example? -
i trying set custom icon on top of files/directories in windows explorer. after researching on topic, found can achieved either creating desktop.ini files (directories only) or using windows api's shell icon overlay (both files , directories). i've seen c++ atl libraries on codeproject, tortoiseoverlay, , c# wrappers, working c# sample cannot found anywhere.
i've found following code sample:
public sealed class shellinterop { private shellinterop() { } [dllimport("shell32.dll")] public static extern void shchangenotify(int eventid, uint flags, intptr item1, intptr item2); } [comvisible(false)] [comimport] [guid("0c6c4200-c589-11d0-999a-00c04fd655e1")] [interfacetype(cominterfacetype.interfaceisiunknown)] public interface ishelliconoverlayidentifier { [preservesig] int ismemberof([marshalas(unmanagedtype.lpwstr)]string path, uint attributes); [preservesig] int getoverlayinfo( intptr iconfilebuffer, int iconfilebuffersize, out int iconindex, out uint flags); [preservesig] int getpriority(out int priority); } [comvisible(true)] [guid("b8fa9e43-38e6-4654-8a13-ff905ad22ce5")] public class myiconoverlay : ishelliconoverlayidentifier { #region ishelliconoverlayidentifier members public int ismemberof(string path, uint attributes) { //show icon overlay return 0; // s_ok } public int getoverlayinfo(intptr iconfilebuffer, int iconfilebuffersize, out int iconindex, out uint flags) { system.diagnostics.debug.writeline(string.format("getoverlayinfo::{0}", iconfilebuffer)); system.diagnostics.debug.writeline(string.format("getoverlayinfo::{0}", iconfilebuffersize)); string fname = @"c:\normalicon.ico"; int bytescount = system.text.encoding.unicode.getbytecount(fname); system.diagnostics.debug.writeline(string.format("getoverlayinfo::{0}", bytescount)); byte[] bytes = system.text.encoding.unicode.getbytes(fname); if (bytes.length + 2 < iconfilebuffersize) { (int = 0; < bytes.length; i++) { marshal.writebyte(iconfilebuffer, i, bytes[i]); } //write "\0\0" marshal.writebyte(iconfilebuffer, bytes.length, 0); marshal.writebyte(iconfilebuffer, bytes.length + 1, 0); } iconindex = 0; flags = 1; // isioi_iconfile return 0; // s_ok } public int getpriority(out int priority) { priority = 0; // 0-100 (0 highest priority) return 0; // s_ok } #endregion #region registry [comregisterfunction] public static void register(type t) { registrykey rk = registry.localmachine.createsubkey(@"software\microsoft\windows\currentversion\explorer\shelliconoverlayidentifiers\_" + t.name); rk.setvalue(string.empty, t.guid.tostring("b").toupper()); rk.close(); shellinterop.shchangenotify(0x08000000, 0, intptr.zero, intptr.zero); } [comunregisterfunction] public static void unregister(type t) { registry.localmachine.deletesubkeytree(@"software\microsoft\windows\currentversion\explorer\shelliconoverlayidentifiers\_" + t.name); shellinterop.shchangenotify(0x08000000, 0, intptr.zero, intptr.zero); } #endregion } from understand, function "register" needs called first register app windows explorer, type parameter expects?
can explain in order need call these functions set icon "c:\overlay.ico" on top of "c:\test.txt"?
if provide example, appreciate it. let's assume console application main function entry point.
edit:
i got work in c++ atl. xearinox pointed out, shell extension code had in dll. after dll compiled has registered running regsvr32.exe command under administrator privileges. mistake thought ismemberof , getoverlayinfo functions had called main program - in fact called windows explorer. here link project on codeplex contains readme file explaining in more details - hope has same problem.
Comments
Post a Comment