Windows Shell Extension with C#

Windows shell extension with C#

A Raymond's post: Do not write in-process shell extensions in managed code.


A recent follow-up: Now that version 4 of the .NET Framework supports in-process side-by-side runtimes, is it now okay to write shell extensions in managed code?

The bottom line is, no, it is not okay:

The Guidance for implementing in-process extensions has been revised, and it continues the recommendation against writing shell extensions and Internet Explorer extensions (and other types of in-process extensions) in managed code, even if you're using version 4 or higher.

Writing a Windows Shell Extension similiar to the Assembly Cache Viewer

Here's an article that should get you on your way:

  • Create Namespace Extensions for Windows Explorer with the .NET Framework

Extending the Windows shell with namespace extensions allows you to create some custom functionality for Windows Explorer. One common use is to enable Explorer to present a list of items that do not exist in one real folder, but actually reside in a number of places. The view on the folder makes it look like these items are in one place, so managing them becomes easier. This article illustrates the process of creating custom shell namespace extensions using C# and the .NET Framework. [...]

Windows Shell Extension dll and Winform process

The only way to solve this is to create another process.

    void OnVerbDisplayFileName(IntPtr hWnd)
{
string file = (new System.Uri(Assembly.GetExecutingAssembly().CodeBase)).AbsolutePath;
string executableName = file.Substring(0, file.LastIndexOf("/"));
executableName += "/MyApp.exe";

Process gui = new Process();

gui.StartInfo.FileName = executableName;
gui.StartInfo.Arguments = selectedFiles.JoinFileNames(" ");

gui.Start();
}

Cheers!

Installing and registering shell extension Context menu From wix installer

Here is how you can register your extension from wix:

First you need to define (in the product scope) custom actions to register/unregister your extension:

<Product>
<!-- ... -->
<CustomAction Id="InstallShell" FileKey="srm.exe" ExeCommand='install "[INSTALLFOLDER]\MyExtension.dll" -codebase' Execute="deferred" Return="check" Impersonate="no" />
<CustomAction Id="UninstallShell" FileKey="srm.exe" ExeCommand='uninstall "[INSTALLFOLDER]\MyExtension.dll"' Execute="deferred" Return="check" Impersonate="no" />
</Product>

Then you need to customize the install execute sequence to launch these custom actions:

<Product>
<!-- ... -->
<InstallExecuteSequence>
<Custom Action="InstallShell" After="InstallFiles">NOT Installed</Custom>
<Custom Action="UninstallShell" Before="RemoveFiles">(NOT UPGRADINGPRODUCTCODE) AND (REMOVE="ALL")</Custom>
</InstallExecuteSequence>
</Product>

"MyExtension.dll" is the id of your extension dll ressource in your wix project:

<Component Guid="*">
<File Id="MyExtension.dll" KeyPath="yes" Source="bin\$(var.Configuration)\MyExtension.dll" />
</Component>

Same for srm.exe:

<Component Guid="*">
<File Id="srm.exe" Source="packages\SharpShellTools.2.2.0.0\lib\srm.exe" KeyPath="yes" />
</Component>

You need to retrieve srm.exe associated to the version of Sharpshell you use (i recommend you to use the nuget package). You can find information on this here :
http://www.codeproject.com/Articles/653780/NET-Shell-Extensions-Deploying-SharpShell-Servers

Hope it will help you ;)

Windows-like shell extension on Mac & Linux

You're trying to apply a concept specific in Windows environments (contextual menu) in a totally different *NIX Environment. Is a hard task, and very difficult because *NIX doesn't provide a friendly API to modify environment because Desktop/Shells fragmentation (Gnome, KDE, etc). The Windows Shell is explorer.exe and provides shell and desktop experience, explorer.exe shows to you the desktop, the start button bar, and the explorer window (to navigate across files, devices and directories), so in Windows we have a only program to do this, Linux or OSX follow another design, in Linux, we have a Desktop Manager (Gnome, KDE, LXDE), it shows to you the desktop, but for file interaction we have a different program called File Manager (Nautilus, Dolphin, etc). But, I need to say is hard but not imposible.

For accomplish that you need to write an abstraction layer (AL). Your program needs to call this layer only, and you need to port the AL to every platform / desktop manager you have.

Example:

Let's say we have a function called AddContextualItem(...) in our AL, to add a new item to Shell Context Menu, your code needs to call this function, but for Windows environments this function surely calls some WIN32 API's to accomplish the goal, but in OSX Environment or Linux this function AddContextualItem should be replaced by another implementation compatible with unix desktop environment (like Gnome, KDE, etc) or specific file manager (Nautilus, Dolphin, etc).

Ultimately, C# does't seems to be the better language for accomplish task like that, Xamarin are doing a good job with Mono Framework, but isn't sufficient. C or C++ is more powerful language to do this.

How To add right click menu to Nautilus (Gnome) File Manager

Source code of nautilus-actions

How to add right click menu to Dolphin (KDE) File Manager

Apple Official Documentation for Building a service (like right-click item menu) in OS X

How do I create a shell-extension / file container dll like winzip?

http://www.codeproject.com/Articles/8063/The-Mini-Shell-Extension-Framework-Part-I

and

http://www.codeproject.com/Articles/9421/The-Mini-Shell-extension-Framework-Part-II

and

http://www.codeproject.com/Articles/11674/The-Mini-Shell-Extension-Framework-Part-III

Exactly you want, but in c++ ;-)
Doing shell exts in C Sharp is painful.

Cannot add icon in shell extension with C#

Please have a look at the following article, it uses .NET 4.0 it to create Windows Shell Extensions using the SharpShell nuget package.

NET Shell Extensions - Shell Context Menus

Using this library, you can set the image directly while creating the contextmenustrip as shown below

protected override ContextMenuStrip CreateMenu()
{
// Create the menu strip.
var menu = new ContextMenuStrip();

// Create a 'count lines' item.
var itemCountLines = new ToolStripMenuItem
{
Text = "Count Lines...",
Image = Properties.Resources.CountLines
};

// When we click, we'll count the lines.
itemCountLines.Click += (sender, args) => CountLines();

// Add the item to the context menu.
menu.Items.Add(itemCountLines);

// Return the menu.
return menu;
}


Related Topics



Leave a reply



Submit