views:

202

answers:

4

I'm looking at writing a shell extension so when a file is clicked an action can be performed against it. (Like any other context menu :))

What is the minimum i need to insert a new Menu Item in the Context menu and perform an action against one or more files. A comparative example would be that i selected 10 files and Send to Zip.

I read that writing some unmanaged code is required but my knowledge of c++ unmanaged code is about zero so i want to do as little as possible to get the Menu item in the Windows Context Menu (File > Right Click). After that i want to call a C# console app to do the main processing, so is it possible to call a c# console app from unmanaged code?

Also, what type of visual studio project would i need to create the Windows Shell program? Which project type do i choose from:

  • Win32 Console App
  • MFC Application
  • Win32 Project
  • ATL Project
  • MFC DLL
  • CLR Console App
  • Class Library
  • Makefile Project
  • MFC ActiveX Control
  • Windows Forms Control Library

Cheers

+3  A: 

This MSDN article will get you started.

Your approach of spawning a process (written in managed code) to do the actual work of the shell extension should be fine. I'd suggest just passing the selected files as command line parameters via CreateProcess.

As to the project type, you'll be wanting to generate a Win32 dynamic link library (DLL). Under 2005, there actually is a Win32 Dll project type. With 2008 (which I infer you're using) you should create a Win32 project, then select DLL as the application type in the resulting wizard.

Kevin Montrose
Thanks! The links did not give any advise on using VS. Are you able to tell what vs project type i would use to create the umanaged c++ program? Please see my edited question.
@Wololo - See my updated answer.
Kevin Montrose
A: 

Here is one example of how you can use unmanaged client with .NET: http://groups.google.com/group/codefactory/web/wcf-service-and-unmanaged-c-client

Yes, you will have to write unmanaged code (C++) to interact with the Shell. Some Shell Extension are written in C# but it is not recommended even by Microsoft as it loads the runtime in Explorer's process space. You can find a lot of articles on codeproject on writing ContextMenu extension. It involves writing a COM dll that implements the IContextMenu interface and registering it appropriately in registry.

A9S6
Are you able to tell what vs project type i would use to create the unmanaged c++ program? Please see my edited question.
Use ATL COM DLL - It comes preloaded with registration and unregistration entries.
A9S6
A: 

If you have no C++ experience with Windows and COM, a shell extension is probably not the easiest project to undertake.

Are you sure you actually need to write a shell extension?

You can easily add a new menu option through the registry (This for an example) and set the 'command' of that option to your C# executable.

EDIT: You can pass the selected file to the process, by using the %1 command in the path.

A sample registry entry for all files would be:

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\*\shell\SomeCmd] @="Do Some Cmd"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\*\shell\SomeCmd\command] @="Path to your app\YourApp.exe "%1"

Notice the "%1" at the end - it will be the name of the file. The limitation is that you will actually be instantiated once for every file - which will also happen to an extension. Once the registry entry is set, it will be there until you remove it.

S.Skov
Is this process a bit limited? I need to pass parameters to the c# console app, say a list of all the selected files. How Would this technique work in this scenario? Would i need to re-write to the registry each time?
Updated the post with a registry sample.
S.Skov
Thanks. This would work for very simple commands. In addition, i also need the menu item to have sub items. I don't think it's possible through the registry setting...
A: 

While it's not impossible to write a shell extension entirely in managed code (i've done it) it is not recommended for a variety of reasons, but the biggest is shell extensions are in-process extensions, which means explorer has to load the entire CLR into it's own address space, and god help you if you have two extensions written to different versions of the CLR.

On top of all that, it's a lot of overhead for such a small function. So it's best to write it in C++, as there's plenty of tools available to do this, including the Active Template Library (ATL).

Mystere Man