views:

815

answers:

7

Problem

Language: C# 2.0 or later


I would like to register context handlers to create menues when the user right clicks certain files (in my case *.eic). What is the procedure to register, unregister (clean up) and handle events (clicks) from these menues?

I have a clue it's something to do with the windows registry, but considering how much stuff there is in .net, I wouldn't be surprised if there are handy methods to do this clean and easy.

Code snippets, website references, comments are all good. Please toss them at me.

Update


Obviously there is a slight problem creating context menues in managed languages, as several users have commented. Is there any other preferred way of achieving the same behaviour, or should I spend time looking into these workarounds? I don't mind doing that at all, I'm glad people have put effort into making this possible - but I still want to know if there is a "proper/clean" way of achieving this.

+4  A: 

Resist writing Shell Extensions in managed languages - there are a multitude of things that could go bang if you pursue this route.

Have a browse through this thread for more details. It contains links to do it if really want, and sagely advice of why it can be done, but shouldn't.

http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/1428326d-7950-42b4-ad94-8e962124043e/

You're back to unmanaged C/C++ as your only real tools here.

stephbu
As of CLR 4.0, the pain that is managed shell-extensions seems to be lifting...http://channel9.msdn.com/shows/Going+Deep/CLR-4-Side-by-Side-In-Process-What-How-Why/
stephbu
+2  A: 

This is not a good idea because of potential dependency issues between different versions of the .NET Framework. Your shell extension could be expecting one version, while a different version may have already been loaded by the application that's currently running.

This thread contains a good summary of the situation.

+2  A: 

I've done them before in C#. It ends up being a hell of a lot harder than it should be. Once you get the boilerplate code down, though, it is easy to roll out new items. I followed this link:

Link To Info

tyshock
+1  A: 

As the prior comments mention, it isn't the best idea to write shell extensions in managed languages, but I thought I'd share an Open Source project that is doing just that :)

ShellGlue is a managed shell extension that is actually quite helpful. The source also might be helpful to you if you're interested in pursuing writing a shell extension in C/C++.

David Mohundro
+2  A: 

While others already mentioned that writing shell extensions in pure .NET is a bad idea due to framework conflicts, you should still note that:

  1. There are 3rd party drivers out there (see Eldos or LogicNP) that do the unmanaged side for you, allowing you to write managed code that talks to the native driver, thus preventing shell-related CLR version conflicts.

  2. A recent MSDN article mentioned that Microsoft has solved this problem for the CoreCLR, as used by Silverlight. They've accomplished this by allowing multiple versions of the CLR to run in the same process, thus fixing the problem. The author further stated that this fix in Silverlight will be rolled into future versions of the full CLR. (Meaning, in the future, it will be quite feasible to write shell extensions in managed code.)

Judah Himango
+1  A: 

Aside from the caveats that have been mentioned concerning the implementation of shell extensions in managed code, what you'd basically need to do is the following:

First, create a COM component in C# that implements the IShellExtInit IContextMenu interfaces. How to create COM components in C# is described here. How to implement the necessary interfaces is described in this article. While the description is for a C++ implementation, you can apply that knowledge to you C# version.

Your COM component will have GUID called the Class-ID or CLSID. You need to register that ID with your file type as a context-menu shell extension:

HKEY_CLASSES_ROOT\.eic\ShellEx\ContextMenuHandlers\MyShellExt
    (Default) -> {YOUR-COMPONENTS-CLSID}

Also make sure that you registered your component correctly as described in the C# COM tutorial. You should find it in the registry under

HKEY_CLASSES_ROOT\CLSID\{YOUR-COMPONENTS-CLSID}
    InprocServer32
        (Default) -> C:\WINDOWS\system32\mscoree.dll
        Class -> YourImplClass
        assembly -> YourAssembly, version=..., Culture=neutral, PublicKey=...
        ...

Good luck...

VoidPointer
+1  A: 

As others have pointed out, shell extensions are not practical in windows development currently.

I asked a similar question recently which was answered with a link to a guide to do exactly what I wanted to do

prestomation