Mombu the Programming Forum

Go Back   Mombu the Programming Forum > Programming > C# | Shell Extension Handler (Icon Overlay Handler)
User Name
Password
REGISTER NOW! Mark Forums Read




Reply
1 11th April 14:45
jan willem zondag
External User
 
Posts: 1
Default C# | Shell Extension Handler (Icon Overlay Handler)



I am trying to implement an Icon Overlay Handler in C#.
So far I have come up with the following code.
After registering the dll with regasm I get icon overlays all over the place
just as requested.
The problem is that a different icon is displayed as overlay than the
iconFile I
pass in te GetOverlayInfo methode.
Running the whole thing through the debugger I can see that on entering the
GetOverlayInfo methode the iconFileBuffer
is already filled and although I change it the "older" iconFile is used.
This leads me to the conclusion that I dealing with a string marshalling
problem. Switching to StringBuilder doesn't correct it.
Anyone?

using System;
using System.Runtime.InteropServices;
using Microsoft.Win32;

namespace ShellExtension
{

public sealed class ShellInterop
{

private ShellInterop()
{
}

/*
* void SHChangeNotify(
* LONG wEventId,
* UINT uFlags,
* LPCVOID dwItem1,
* LPCVOID dwItem2);
*/
[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(
[MarshalAs(UnmanagedType.LPWStr)] string 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 everything with icon overlay
return 0; // S_OK
}

public int GetOverlayInfo(string iconFileBuffer, int
iconFileBufferSize, out int iconIndex, out uint flags)
{
iconFileBuffer = @"c:\overlay.ico";
iconIndex = 0;
flags = 1; // ISIOI_ICONFILE
return 0; // S_OK
}

public int GetPriority(out int priority)
{
priority = 0; // 0-100 (0 is highest priority)
return 0; // S_OK
}

#endregion

#region Registry

[ComRegisterFunction]
public static void Register(Type t)
{
RegistryKey rk =
Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Micr osoft\Windows\CurrentVersi
on\Explorer\ShellIconOverlayIdentifiers\_" + t.Name);
rk.SetValue(string.Empty, t.GUID.ToString("B").ToUpper());
rk.Close();
ShellInterop.SHChangeNotify(0x08000000, 0, IntPtr.Zero,
IntPtr.Zero);
}

public static void Unregister(Type t)
{

Registry.LocalMachine.DeleteSubKeyTree(@"SOFTWARE\ Microsoft\Windows\CurrentV
ersion\Explorer\ShellIconOverlayIdentifiers\_" + t.Name);
ShellInterop.SHChangeNotify(0x08000000, 0, IntPtr.Zero,
IntPtr.Zero);
}

#endregion

}

}
  Reply With Quote


 


2 12th April 23:28
v-yiy
External User
 
Posts: 1
Default C# | Shell Extension Handler (Icon Overlay Handler)



Hi Jan,

I'm not sure if the default marshaler will copy the modified string back to
the unmanaged memory area. In this situation I suggest you defining this
method as

[PreserveSig] int GetOverlayInfo(
IntPtr iconFileBuffer,
int iconFileBufferSize,
out int iconIndex,
out uint flags);

and doing marshalling by yourself.
public int GetOverlayInfo( IntPtr iconFileBuffer, int iconFileBufferSize,
out int iconIndex, out uint flags)
{

System.Diagnostics.Debug.WriteLine(string.Format(" GetOverlayInfo::{0}",iconF
ileBuffer));

System.Diagnostics.Debug.WriteLine(string.Format(" GetOverlayInfo::{0}",iconF
ileBufferSize));
string fname = @"c:\overlay.ico";

int bytesCount = System.Text.Encoding.Unicode.GetByteCount(fname);


System.Diagnostics.Debug.WriteLine(string.Format(" GetOverlayInfo::{0}",bytes
Count));

byte[] bytes = System.Text.Encoding.Unicode.GetBytes(fname);

if (bytes.Length + 2 < iconFileBufferSize)
{
for(int i = 0; i < bytes.Length; i++)
{
Marshal.WriteByte(iconFileBuffer,i,bytes[i]);
}
//write the "\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
}

Does it resolve your problem?
If you have any problem on this issue, please feel free to reply this
thread.
Thanks!

Best regards,

Ying-Shen Yu [MSFT]
Microsoft Community Support
Get Secure! - www.microsoft.com/security

This posting is provided "AS IS" with no warranties and confers no rights.
This mail should not be replied directly, please remove the word "online"
before sending mail.
  Reply With Quote
3 12th April 23:29
jan willem zondag
External User
 
Posts: 1
Default C# | Shell Extension Handler (Icon Overlay Handler)


Hi Ying-Shen,

Problem resolved, thanks!

Thought it had to do with marshalling, had tried several options:

- marschalling with [String]
- marshalling with [StringBuilder]
- IntPtr iconFileBuffer = Marshal.StringToCoTaskMemUni("string")
- IntPtr iconFileBuffer = Marshal.StringToHGlobalUni("string")

forgot to use your solution: write to unmanaged memory area directly

Regards,
Jan
  Reply With Quote
4 19th September 10:37
erickbp
programming
Mombu User
 
Join Date: Sep 2008
Location: Cuba
Posts: 1
erickbp is on a distinguished road
Question Re: C# | Shell Extension Handler (Icon Overlay Handler)


Hi,

I have been tried the code you both have posted but It doesn’t work.
I built a Windows Library project with your code and then I built a Console Application project that I’m including below:

class Program
{
static void Main(string[] args)
{
BoxDesktopIconOverlay.Register(typeof(BoxDesktopIc onOverlay));
}
}

When I run this project I can see, using regedit, that I have new entry in the Windows Register in the right place but my implementation of the IShellIconOverlayIdentifier interface is never used. Any method of my implementation is called.

Please, could you tell me what I’m missing or just post an entire sample solution ( .sln )?

Thank you in advanced,

Erick
erickbp is offline   Reply With Quote


 


Reply


Thread Tools
Display Modes




666