views:

400

answers:

1

Good morning all,

After a day of googling, I’m at a loss. I decided to come here and ask the community. I am in the process of making a namespace extension for vista in C#. Now I understand that MS says not to do this, but I am simply doing it as a proof of concept.

The Problem: I am lacking the knowledge and understanding to figure out how to register my .NET namespace extension within the windows registry.

From my reading I believe this post ([]http://stackoverflow.com/questions/279336/how-to-host-a-rooted-namespace-extension-in-windows-explorer) explains where the key belongs, but do sub-keys and/or values need created inside?

I understand that regsvr32 and/or regasm.exe needs to be used to register my dll (not sure which, I have found conflicting advice).

I also understand that my dll needs to have a method similar to the following:

(This code mostly comes from []http://msdn.microsoft.com/en-us/magazine/cc188741.aspx, minor changes to add to the correct registry location)

[ComRegisterFunctionAttribute]
public static void RegisterFunction(Type t)
{

try 
{
    // add the correct things to the CLSID so the thing works as an extension
    RegistryKey CLSID = Registry.ClassesRoot.OpenSubKey("CLSID");

    RegistryKey kClass = null;

    kClass = CLSID.OpenSubKey( "{" + t.GUID.ToString() + "}", true );

    RegistryKey ProgId = kClass.OpenSubKey("ProgId");

    kClass.SetValue( null, (string) ProgId.GetValue(null) );

    ProgId.Close();

    RegistryKey ShellFolder = kClass.CreateSubKey("ShellFolder");

    ShellFolder.SetValue( "Attributes", 0x78000040 );
    ShellFolder.SetValue( "WantsFORPARSING", "" );

    ShellFolder.Close();
    kClass.Close();
    CLSID.Close();

    // add it to the approved list of extensions
          RegistryKey MyComputer = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MyComputer\\NameSpace", true);

          MyComputer.SetValue("{" + t.GUID.ToString() + "}", t.FullName);
          MyComputer.Close();
}
catch( Exception e ) 
{
    MessageBox.Show( e.Message );
    return;
}
}

Resources for people in this situation in the future that find this by searching: []http://msdn.microsoft.com/en-us/magazine/cc188741.aspx

[]http://msdn.microsoft.com/en-us/library/bb762774(VS.85).aspx

[]http://stackoverflow.com/questions/279336/how-to-host-a-rooted-namespace-extension-in-windows-explorer

--- Update from 3/10/10 ---

I have attempted to do some work with it, but still no success. Therefore, I ripped out everything I had in order to investigate how the regasm actually works with the registry.

My Code:

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

namespace Test2
{
[ProgId("Test2")]
[Guid("1149E580-186E-4f8c-AB6A-E55D6F0F171E")]
[ComVisible(true)]
public class Class1
{
    [ComRegisterFunctionAttribute()]
    public static void RegisterFunction(Type t)
    {
        // add the correct things to the CLSID so the thing works as an extension

        System.IO.FileStream fs = new System.IO.FileStream(@"C:\Users\Lucas\Documents\Visual Studio 2010\Projects\Test2\Test2\bin\Release\Test2.txt",
            System.IO.FileMode.Create, System.IO.FileAccess.ReadWrite, System.IO.FileShare.None);

        fs.Write(System.Text.Encoding.ASCII.GetBytes("Running RegisterFunction"), 0, 0);
        fs.Close();

        RegistryKey CLSID = Registry.ClassesRoot.OpenSubKey("CLSID");

        RegistryKey kClass = CLSID.CreateSubKey("{" + t.GUID.ToString() + "}");

        kClass.SetValue("Test", "HelloRegistry", RegistryValueKind.String);

        kClass.Close();
        CLSID.Close();
    }

    [ComUnregisterFunctionAttribute()]
    public static void UnregisterFunction(Type t)
    {
    }
}
}

I build a dll, then run regasm /regfile[:pathtofile] [pathtodll] and the registry file generated is as follows:

REGEDIT4

[HKEY_CLASSES_ROOT\Test2]
@="Test2.Class1"

[HKEY_CLASSES_ROOT\Test2\CLSID]
@="{1149E580-186E-4F8C-AB6A-E55D6F0F171E}"

[HKEY_CLASSES_ROOT\CLSID\{1149E580-186E-4F8C-AB6A-E55D6F0F171E}]
@="Test2.Class1"

[HKEY_CLASSES_ROOT\CLSID\{1149E580-186E-4F8C-AB6A-E55D6F0F171E}\InprocServer32]
@="mscoree.dll"
"ThreadingModel"="Both"
"Class"="Test2.Class1"
"Assembly"="Test2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
"RuntimeVersion"="v4.0.21006"

[HKEY_CLASSES_ROOT\CLSID\{1149E580-186E-4F8C-AB6A-E55D6F0F171E}\InprocServer32\1.0.0.0]
"Class"="Test2.Class1"
"Assembly"="Test2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
"RuntimeVersion"="v4.0.21006"

[HKEY_CLASSES_ROOT\CLSID\{1149E580-186E-4F8C-AB6A-E55D6F0F171E}\ProgId]
@="Test2"

[HKEY_CLASSES_ROOT\CLSID\{1149E580-186E-4F8C-AB6A-E55D6F0F171E}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}]

Note, nothing about my custom key and the txt document is never created. So this is leading me to believe that regasm is never calling my custom registration method. If anyone has any ideas, I'll be more than happy to try them!

+1  A: 
  1. You need to run regasm.exe, not regsvr32.exe
  2. You need to make sure that you register while running as Admin.
  3. Finally, you also need to create following registry key HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\Namespace\{CLSID of your root class} and set the default value to the display name of your namespace extension. This assumes you are registering under 'My Computer'.
  4. Add it to approved extensions to following registry key: HKLM\Software\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved. To this key, create a new value having name equal to the CLSID of your namespace extension and value equal to the display name of your namespace extension.
logicnp
Logicnp, thanks for the steps. I'll give it a go tonight once I get home. Do you know if it requires a full windows restart or simply killing explorer and restarting?
Lucas
Killing explorer will suffice.
logicnp
Well, sadly for me, I have been unable to get my custom registration function to work, any ideas there logicnp (I edited my original post)
Lucas
Hope your class has ComVisible attribute and a Guid attribute?
logicnp
yes indeed. namespace Test2 { [ProgId("Test2")] [Guid("1149E580-186E-4f8c-AB6A-E55D6F0F171E")] [ComVisible(true)] public class Class1 {
Lucas