Click here to Skip to main content
14,328,676 members

.NET Shell Extensions - Shell Context Menus

Rate this:
4.93 (128 votes)
Please Sign up or sign in to vote.
4.93 (128 votes)
29 Jun 2019CPOL
Rapidly create Shell Context Menu Extensions using .NET

Introduction

Until .NET 4.0, it was impossible to reliably create Windows Shell Extensions using .NET code. With improvements to the framework, it is now possible to use .NET to create these extensions. In this article, I'll show you how to quickly create Shell Context Menus as a C# class library.

Image 1

Above: A screenshot of an example Shell Context Menu Extension - the 'Count Lines...' item is a custom shell extension that this article demonstrates how to create.

The Series

This article is part of the series '.NET Shell Extensions', which includes:

  1. .NET Shell Extensions - Shell Context Menus
  2. .NET Shell Extensions - Shell Icon Handlers
  3. .NET Shell Extensions - Shell Info Tip Handlers
  4. .NET Shell Extensions - Shell Drop Handlers
  5. .NET Shell Extensions - Shell Preview Handlers
  6. .NET Shell Extensions - Shell Icon Overlay Handlers
  7. .NET Shell Extensions - Shell Thumbnail Handlers
  8. .NET Shell Extensions - Shell Property Sheets
  9. .NET Shell Extensions - Deploying SharpShell Servers

What are Shell Context Menus?

Shell Context Menus are COM servers that are registered in the system that allow the context menus of shell objects to be extended. This could be the context menu for a specific file type, such as *.txt files, file classes such as 'text files', drives, folders and more. The context menus can be used to provide advanced functionality that can be accessed quickly through Windows Explorer.

Getting Started

There's a lot of work involved in setting up Shell Extensions. Specific COM interfaces have to be implemented, servers must be built, the registry must be updated in a variety of ways. We're going to use a library I have developed called 'SharpShell' to do all of the hard work - leaving us with the task of creating a lightweight class library that contains our extension class.

Our Goal

The code below creates a Shell Extension that allows you to count the lines in any text file by right clicking on it and choosing 'Count Lines'. For the rest of the article, I'll show you how to create a library like this. The code is shown first because I want to highlight how straightforward writing these libraries is when using SharpShell.

/// <summary>
/// The CountLinesExtensions is an example shell context menu extension,
/// implemented with SharpShell. It adds the command 'Count Lines' to text
/// files.
/// </summary>
[ComVisible(true)]
[COMServerAssociation(AssociationType.ClassOfExtension, ".txt")]
public class CountLinesExtension : SharpContextMenu
{
    /// <summary>
    /// Determines whether this instance can a shell
    /// context show menu, given the specified selected file list
    /// </summary>
    /// <returns>
    /// <c>true</c> if this instance should show a shell context
    /// menu for the specified file list; otherwise, <c>false</c>
    /// </returns>
    protected override bool CanShowMenu()
    {
        //  We always show the menu
        return true;
    }
 
    /// <summary>
    /// Creates the context menu. This can be a single menu item or a tree of them.
    /// </summary>
    /// <returns>
    /// The context menu for the shell context menu.
    /// </returns>
    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;
    }
 
    /// <summary>
    /// Counts the lines in the selected files
    /// </summary>
    private void CountLines()
    {
        //  Builder for the output
        var builder = new StringBuilder();
 
        //  Go through each file.
        foreach (var filePath in SelectedItemPaths)
        {
            //  Count the lines
            builder.AppendLine(string.Format("{0} - {1} Lines", 
              Path.GetFileName(filePath), File.ReadAllLines(filePath).Length));
        }
 
        //  Show the output
        MessageBox.Show(builder.ToString());
    }
} 

That's pretty clean and simple - now let's look in detail about how to create this Shell Context Menu with SharpShell.

Step 1: Creating the Project

First, create a new C# Class Library project.

Tip: You can use Visual Basic rather than C# - in this article, the source code is C# but the method for creating a Visual Basic Shell Extension is just the same.

In this example, we'll call the project 'CountLinesExtension'.

Now add the following references:

  1. System.Windows.Forms
  2. System.Drawing

System.Windows.Forms is needed because we're going to use the WinForms ContextMenuStrip to define the context menu. System.Drawing is needed as we're going to want to use Icons.

Rename the 'Class1.cs' file to 'CountLinesExtension.cs'. We should now have a project structure that looks like this:

Image 2

Step 2: Referencing SharpShell

We now need to add a reference to the core SharpShell library. You can do that in a few different ways.

Add Reference

Download the 'SharpShell Library' zip file at the top of the article and add a reference to the downloaded SharpShell.dll file.

Tip: The download on this article is correct at the time of writing - if you need the latest version, use Nuget (as described below) or get the library from sharpshell.codeplex.com.

Use Nuget

If you have Nuget installed, just do a quick search for SharpShell and install it directly - or get the package details at https://www.nuget.org/packages/SharpShell.

Image 3

Use CodePlex

Rather than getting the library from this page, which may not be the latest version, you can always get the very latest version of the library from CodePlex - on the SharpShell home page which is https://sharpshell.codeplex.com. Nuget will always have the latest stable version - CodePlex may have betas available, and the CodeProject articles will have the version that was available at the time of writing.

Step 3: Deriving from SharpContextMenu

Now things get interesting. Derive your CountLinesExtension class from SharpContextMenu:

/// <summary>
/// The Count Lines Context Menu Extension
/// </summary>
public class CountLinesExtension : SharpContextMenu
{
}

Now we must implement the abstract members of the class. Right click on the SharpContextMenu part of the line and choose 'Implement Abstract Class':

Image 4

This'll create implementations of the two functions needed - CanShowMenu and CreateMenu:

/// <summary>
/// The Count Lines Context Menu Extension
/// </summary>
public class CountLinesExtension : SharpContextMenu
{
    protected override bool CanShowMenu()
    {
        throw new NotImplementedException();
    }
 
    protected override ContextMenuStrip CreateMenu()
    {
        throw new NotImplementedException();
    }
}

By implementing these two functions, we can provide all of the functionality needed. Here's what they do:

CanShowMenu

This function is called to determine whether we should show the Context Menu Extension for a given set of files. The files the user has selected are in the property SelectedItemPaths. We can check these file paths to see whether we actually want to show the menu. If the menu should be shown, return true. If not, return false.

CreateMenu

This function is called to actually create the Context Menu. A standard WinForms ContextMenuStrip is all we need to return.

Here's how we'll implement the two functions:

protected override bool CanShowMenu()
{
    //  We will always show the menu
    return true;
}
 
protected override ContextMenuStrip CreateMenu()
{
    //  Create the menu strip
    var menu = new ContextMenuStrip();
 
    //  Create a 'count lines' item
    var itemCountLines = new ToolStripMenuItem
    {
        Text = "Count Lines"
    };
 
    //  When we click, we'll call the 'CountLines' function
    itemCountLines.Click += (sender, args) => CountLines();
 
    //  Add the item to the context menu
    menu.Items.Add(itemCountLines);
 
    //  Return the menu
    return menu;
}
 
private void CountLines()
{
    //  Builder for the output
    var builder = new StringBuilder();
 
    //  Go through each file
    foreach (var filePath in SelectedItemPaths)
    {
        //  Count the lines
        builder.AppendLine(string.Format("{0} - {1} Lines", 
          Path.GetFileName(filePath), File.ReadAllLines(filePath).Length));
    }
 
    //  Show the output
    MessageBox.Show(builder.ToString());
} 

For CanShowMenu, we return true always - shortly, we'll see why we don't need to validate that we have text files. For CreateMenu, we build a context menu strip with one item only, that has the caption 'Count Lines' and calls the CountLines function.

The CountLines function goes through the SelectedItemPaths and counts the lines in each file - then displays a message box with the summary.

Step 4: Handling the COM Registration

There are just a few things left to do. First, we must add the COMVisible attribute to our class.

[ComVisible(true)]
public class CountLinesExtension : SharpContextMenu

Why? Well, even though our class doesn't really look like it, it is in fact a COM server. If you were to look at the base class, you'd see that we're implementing COM interfaces such as IShellExtInit, IContextMenu, and ISharpShellServer. We don't need to worry about what they do, but for the system to be able to create our extension, it must have this attribute.

Next, we must give the assembly a strong name. There are ways around this requirement, but generally this is the best approach to take. To do this, right click on the project and choose 'Properties'. Then go to 'Signing'. Choose 'Sign the Assembly', specify 'New' for the key and choose a key name. You can password protect the key if you want to, but it is not required:

Image 5

The final step - we now need to associate our extension with some file types. We can do that with the COMServerAssociation attribute (provided by SharpShell):

[ComVisible(true)]
[COMServerAssociation(AssociationType.ClassOfExtension, ".txt")]
public class CountLinesExtension : SharpContextMenu

So what have we done here? We've told SharpShell that when registering the server, we want it to be associated with the class of *.txt files. This means that we won't just have it available for anything that ends in *.txt, but anything that is the same class. In basic terms, that's most things that share the same icon as the *.txt files.

You can do some pretty funky things with the COMServerAssociation attribute - you can associate with folders, drives, unknown files, specific extensions and so on. The full documentation for this feature is at COM Server Associations on the SharpShell CodePlex site.

And that's it! Building the project creates the CountLinesExtension assembly, which can be registered as a COM server to add the context menu to the system. Registering the COM server is a debugging and deployment task, so we'll talk about this in detail in the next section.

Debugging the Shell Extension

The Shell Extension is going to be hosted in Windows Explorer - due to the roundabout way that .NET COM Servers are loaded, it's damn near impossible to get a debugger into the process and step through the managed code. However, there is a way to debug your extension quickly. SharpShell comes with some tools that make working with SharpShell COM servers a bit easier, and one of them is the Server Manager. We can use this tool to debug our extension.

Open the Server Manager tool and use File > Load Server to load the built server file (the DLL). You can also drag the server into the main window. Selecting the server will show you some details on it.

Image 6

The Server Manager is very useful - it will tell you whether the server is installed (32 or 64 bit mode) and some more details.

If you load the SharpContextMenu server, then select it, you can go to the 'Tools' menu and choose 'Test Context Menu'.

Image 7

When you use 'Test Context Menu', you'll get a Test Shell Window. This is a basic implementation of the Windows Explorer application. You can right click on any item to test the Shell Context Menu.

Tip: Regardless of the COMServerAssocations you've set, the Test Shell will always attempt to create the context menu for the items created.

Attaching a debugger to the ServerManager.exe process will allow you to debug into your Context Menu and test its functionality, without having to register the server in Windows. Here's what the Test Shell will look like when running the Count Line Context menu extension.

Image 8

Installing and Registering the Shell Extension

There are a number of ways to install and register SharpShell Shell Extensions. In this section, I'll detail them all.

The regasm Tool

You can use the tool 'regasm' to install and register a shell extension. When using regasm, the shell extension will be installed into the registry (i.e., the Class ID of the COM Server will be put in the COM Server Classes section and associated with the path to the actual server file), it will also register the associations.

The Server Manager Tool

The Server Manager Tool is my preferred approach for installing/uninstalling and registering/unregistering, at least during development, because it lets you install and register as separate steps. It will also let you specify whether you're installing/uninstalling etc in 32 bit or 64 bit mode.

Manual Registry Manipulation

Generally a bad approach, but if you absolutely have to then the MSDN documentation for Shell Extensions describes the changes that must be made to the registry to manually register a COM server, or a Managed COM Server. The documentation is listed in the 'Useful Resources' section.

Useful Resources

What's Next?

SharpShell will over time provide a mechanism to create all of the available Shell Extensions using .NET. Currently, Icon Handlers are implemented (I'm working on the documentation) and Property Sheet Handlers are implemented (with a few bugs to iron out). Each extension type will have an article.

I hope you've found this article useful - for feature requests, bugs or comments, you can use the comments section below or the CodePlex site.

History

  • 27th November, 2014: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Dave Kerr
Software Developer
United Kingdom United Kingdom
Follow my blog at www.dwmkerr.com and find out about my charity at www.childrenshomesnepal.org.

Comments and Discussions

 
AnswerRe: Directory Association only works when a directory is right clicked but not inside it. Pin
Dave Kerr5-Jan-15 2:14
mvaDave Kerr5-Jan-15 2:14 
QuestionAdding menu on right click without any file or directory selected. Pin
Member 1116004816-Dec-14 18:23
memberMember 1116004816-Dec-14 18:23 
AnswerRe: Adding menu on right click without any file or directory selected. Pin
Dave Kerr18-Dec-14 23:02
mvaDave Kerr18-Dec-14 23:02 
GeneralRe: Adding menu on right click without any file or directory selected. Pin
Member 111600484-Jan-15 18:36
memberMember 111600484-Jan-15 18:36 
GeneralRe: Adding menu on right click without any file or directory selected. Pin
Dave Kerr5-Jan-15 2:35
mvaDave Kerr5-Jan-15 2:35 
QuestionThanks for this! Pin
Zeshan Bilal28-Nov-14 4:06
groupZeshan Bilal28-Nov-14 4:06 
AnswerRe: Thanks for this! Pin
Dave Kerr29-Nov-14 2:45
mvaDave Kerr29-Nov-14 2:45 
Suggestion[EXAMPLE] This is an usage example for VB.Net users - How to create a Contextmenu Pin
ElektroStudios27-Nov-14 16:26
memberElektroStudios27-Nov-14 16:26 
I would like to share this usage example written in VB.Net.

It creates a contextmenu with two sub items using this structure:

· Title
       · Run
       · Open files...


The focus of this example is to send multiple files as an argument to the specified application, in for example a third party application that accepts multiple files separated by an space in a single line.

Feel free to share, modify or improve this snippet, I'm new using SharpShell and maybe something could be simplified, for example reading a registry value instead of specifying the static path in the code.

#Region " Option Statements "
 
Option Strict On
Option Explicit On
Option Infer Off

#End Region

#Region " Imports "
 
Imports SharpShell.Attributes
Imports SharpShell.SharpContextMenu
Imports System.IO
Imports System.Runtime.InteropServices
Imports System.Text
Imports System.Windows.Forms
Imports System.ComponentModel

#End Region

#Region " MyAppContextMenu "
 
''' <summary>
''' The Application Context Menu Extension.
''' </summary>
<ComVisible(True)>
<COMServerAssociation(AssociationType.ClassOfExtension, ".ext")>
Public Class MyAppContextMenu : Inherits SharpContextMenu

#Region " Objects "
 
    ''' <summary>
    ''' Contains the application information.
    ''' </summary>
    Private ReadOnly application As New AppInfo With
            {
                .Title = "My Menu Title",
                .Filename = "Assembly Filename",
                .Directory = My.Application.Info.DirectoryPath
            }

#End Region

#Region " Types "
 
    ''' <summary>
    ''' Contains information about an application.
    ''' This class cannot be inherited.
    ''' </summary>
    Protected NotInheritable Class AppInfo

        ''' <summary>
        ''' Gets or sets the application title.
        ''' </summary>
        ''' <value>The application title.</value>
        Protected Friend Property Title As String

        ''' <summary>
        ''' Gets or sets the application filename.
        ''' Without the file extension.
        ''' </summary>
        ''' <value>The application filename.</value>
        Protected Friend Property Filename As String

        ''' <summary>
        ''' Gets or sets the application working directory.
        ''' </summary>
        ''' <value>The application working directory.</value>
        Protected Friend Property Directory As String

        ''' <summary>
        ''' Gets the full qualified application path.
        ''' </summary>
        ''' <value>The full qualified application path.</value>
        Protected Friend ReadOnly Property FullPath As String
            Get
                Return Path.Combine(Me.Directory, Me.Filename, ".exe")
            End Get
        End Property

    End Class

#End Region

#Region " SharpShell Methods "
 
    ''' <summary>
    ''' Determines whether this instance can a shell context show menu, given the specified selected file list.
    ''' </summary>
    ''' <returns>
    ''' <c>true</c> if this instance should show a shell context menu for the specified file list; otherwise, <c>false</c>.
    ''' </returns>
    Protected Overrides Function CanShowMenu() As Boolean

        Return True

    End Function

    ''' <summary>
    ''' Creates the context menu.
    ''' </summary>
    ''' <returns>The context menu for the shell context menu.</returns>
    Protected Overrides Function CreateMenu() As ContextMenuStrip

        ' Create the menu strip.
        Dim menu As New ContextMenuStrip()

        ' Create the main item, this is used to show our application title.
        Dim itemTitle As New ToolStripMenuItem() With
            {
                .Text = Me.application.Title,
                .Image = My.Resources.ApplicationIcon
            }

        ' Create a 'Run' item.
        Dim itemRun As New ToolStripMenuItem() With
            {
                .Text = "Run",
                .Image = My.Resources.RunIcon
            }

        ' Create a 'Open file' item.
        Dim itemOpenFile As New ToolStripMenuItem() With
            {
                .Text = "Open file...",
                .Image = My.Resources.OpenFileIcon
            }

        ' Create a 'Open files' item.
        Dim itemOpenFiles As New ToolStripMenuItem() With
            {
                .Text = "Open files...",
                .Image = My.Resources.OpenFilesIcon
            }

        ' Add the main item into the context menu.
        menu.Items.Add(itemTitle)

        ' Add the 'Run' sub-item into the 'itemTitle' item.
        itemTitle.DropDownItems.Add(itemRun)

        ' Add the 'Open file' or 'Open files' sub-item into the 'itemTitle' item.
        ' Depending on the amount of selected files.
        itemTitle.DropDownItems.Add(If(Me.SelectedItemPaths.Count = 1, itemOpenFile, itemOpenFiles))

        ' Suscribe to events.
        AddHandler itemRun.Click, AddressOf ItemRun_Click
        AddHandler itemOpenFile.Click, AddressOf ItemOpenFile_Click
        AddHandler itemOpenFiles.Click, AddressOf ItemOpenFiles_Click

        ' Return the menu.
        Return menu

    End Function

#End Region

#Region " Application Methods "
 
    ''' <summary>
    ''' Runs the specified application.
    ''' </summary>
    ''' <param name="fileName">The name of an application file to run in the process.</param>
    ''' <param name="arguments">Command-line arguments to pass when starting the process.</param>
    Private Sub RunApp(ByVal fileName As String,
                       Optional ByVal arguments As String = "")

        Try
            Process.Start(fileName, arguments)

        Catch ex As FileNotFoundException
            ' Do something.

        Catch ex As InvalidOperationException
            ' Do something.

        Catch ex As Win32Exception
            ' Dim errorCode As Integer = Marshal.GetLastWin32Error()
            ' Do something.

        Catch ex As Exception
            ' Do something.

        End Try

    End Sub

    ''' <summary>
    ''' Opens the given file in the specified application.
    ''' </summary>
    ''' <param name="appPath">The application filepath to run.</param>
    ''' <param name="filepath">The filepath to send to the application arguments.</param>
    ''' <param name="stringFormat">The string format used to format the filepath.</param>
    Private Sub OpenFile(ByVal appPath As String,
                         ByVal filepath As String,
                         Optional ByVal stringFormat As String = """{0}""")

        Me.RunApp(appPath, String.Format(stringFormat, filepath))

    End Sub

    ''' <summary>
    ''' Opens the given files in the specified application.
    ''' </summary>
    ''' <param name="appPath">The application filepath to run.</param>
    ''' <param name="filepaths">The filepaths to send to the application arguments.</param>
    ''' <param name="stringFormat">The string format used to join the filepaths.</param>
    Private Sub OpenFiles(ByVal appPath As String,
                          ByVal filepaths As IEnumerable(Of String),
                          Optional ByVal stringFormat As String = """{0}"" ")

        Me.RunApp(fileName:=appPath,
                  arguments:=Me.JoinFilePaths(filepaths, stringFormat))

    End Sub

    ''' <summary>
    ''' Joins the selected filepaths in a single line, filepaths are closed with double-quotes and separated by a space.
    ''' eg: "File1" "File2" "File3"
    ''' </summary>
    ''' <param name="filepaths">The filepaths to join.</param>
    ''' <param name="joinFormat">The string format used to join the filepaths.</param>
    ''' <returns>The joined and formatted filepaths.</returns>
    Private Function JoinFilePaths(ByVal filepaths As IEnumerable(Of String),
                                   ByVal joinFormat As String) As String

        Dim sb As New StringBuilder()

        For Each filePath As String In filepaths
            sb.Append(String.Format(joinFormat, filePath))
        Next filePath

        Return sb.ToString

    End Function

#End Region

#Region " Event Handlers "
 
    ''' <summary>
    ''' Handles the Click event of the ItemRun menu item.
    ''' </summary>
    ''' <param name="sender">The source of the event.</param>
    ''' <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
    Private Sub ItemRun_Click(ByVal sender As Object, ByVal e As EventArgs)

        Me.RunApp(fileName:=Me.Application.FullPath)

    End Sub

    ''' <summary>
    ''' Handles the Click event of the ItemOpenFile menu item.
    ''' </summary>
    ''' <param name="sender">The source of the event.</param>
    ''' <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
    Private Sub ItemOpenFile_Click(ByVal sender As Object, ByVal e As EventArgs)

        Me.OpenFile(appPath:=Me.Application.FullPath,
                    filepath:=Me.SelectedItemPaths.First,
                    stringFormat:=<a><![CDATA["{0}"]]></a>.Value)

    End Sub

    ''' <summary>
    ''' Handles the Click event of the ItemOpenFiles menu item.
    ''' </summary>
    ''' <param name="sender">The source of the event.</param>
    ''' <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
    Private Sub ItemOpenFiles_Click(ByVal sender As Object, ByVal e As EventArgs)

        Me.OpenFiles(appPath:=Me.application.FullPath,
                     filepaths:=Me.SelectedItemPaths,
                     stringFormat:=<a><![CDATA[ "{0}" ]]></a>.Value)

    End Sub

#End Region

End Class

#End Region


modified 27-Nov-14 23:24pm.

QuestionWhat happens with the transparency of the images? Pin
ElektroStudios23-Nov-14 20:03
memberElektroStudios23-Nov-14 20:03 
AnswerRe: What happens with the transparency of the images? Pin
Dave Kerr27-Nov-14 5:26
mvaDave Kerr27-Nov-14 5:26 
GeneralRe: What happens with the transparency of the images? Pin
ElektroStudios27-Nov-14 13:49
memberElektroStudios27-Nov-14 13:49 
GeneralRe: What happens with the transparency of the images? Pin
Dave Kerr27-Nov-14 20:09
mvaDave Kerr27-Nov-14 20:09 
QuestionReal life examples are needed, please. Pin
ElektroStudios23-Nov-14 3:21
memberElektroStudios23-Nov-14 3:21 
AnswerRe: Real life examples are needed, please. Pin
Dave Kerr27-Nov-14 5:21
mvaDave Kerr27-Nov-14 5:21 
GeneralRe: Real life examples are needed, please. Pin
ElektroStudios27-Nov-14 15:59
memberElektroStudios27-Nov-14 15:59 
GeneralRe: Real life examples are needed, please. Pin
Dave Kerr29-Nov-14 2:35
mvaDave Kerr29-Nov-14 2:35 
QuestionImprove Server Manager Tool to install/register via commandline? Pin
ElektroStudios23-Nov-14 3:02
memberElektroStudios23-Nov-14 3:02 
AnswerRe: Improve Server Manager Tool to install/register via commandline? Pin
Dave Kerr27-Nov-14 4:50
mvaDave Kerr27-Nov-14 4:50 
QuestionMultiple file selection is not working on the server manager tool Pin
ElektroStudios23-Nov-14 2:32
memberElektroStudios23-Nov-14 2:32 
AnswerRe: Multiple file selection is not working on the server manager tool Pin
Dave Kerr27-Nov-14 4:47
mvaDave Kerr27-Nov-14 4:47 
QuestionHow to set the contextmenu position? Pin
ElektroStudios23-Nov-14 2:28
memberElektroStudios23-Nov-14 2:28 
AnswerRe: How to set the contextmenu position? Pin
Dave Kerr27-Nov-14 4:45
mvaDave Kerr27-Nov-14 4:45 
QuestionExecution on WinXp fails despite proper registration Pin
pchinery5-Nov-14 6:10
memberpchinery5-Nov-14 6:10 
AnswerRe: Execution on WinXp fails despite proper registration Pin
Dave Kerr10-Nov-14 17:44
mvaDave Kerr10-Nov-14 17:44 
QuestionCAN the dll created by Sharpshell be used with java native library? Pin
Member 1111920829-Sep-14 19:51
memberMember 1111920829-Sep-14 19:51 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Article
Posted 5 Jan 2013

Stats

567.8K views
19.1K downloads
387 bookmarked