user2827024
user2827024

Reputation:

Creating new key in HKCR works, but doesn't

I have the following code, which returns "Success", but searching the registry with two different tools with the search string "{3BDAAC43-E734-11D5-93AF-00105A990292}" yields no results.

 RegistryKey RK = Registry.ClassesRoot.CreateSubKey("CLSID\\{3BDAAC43-E734-11D5-93AF-00105A990292}");
 if ( RK != null ) 
     {
         MessageBox.Show("Success", "Success");
     }
 else 
     {
        MessageBox.Show("Failure", "Failure");

}

[Edit] I hate problems that I solve without knowing how, but I'm past this issue.

I'm now able to create a subkey, but I can't set any value pairs. I've found several examples how it should be done, but can't see how my code is different than them.

This is my new code. The subkey appears, but never has anything in it.

     Registry.ClassesRoot.DeleteSubKey(clsid.EntryGuid, false);

                RK.CreateSubKey(clsid.EntryGuid);
                RK.OpenSubKey(clsid.EntryGuid, true);
                RK.SetValue("(Default", clsid.RootObjectName);
                RK.CreateSubKey("InprocServer32", true);
                RK.SetValue("(Default", clsid.InprocServer32);
                RK.SetValue("(Default", clsid.ThreadingModel);
                RK.CreateSubKey("ProgID", true);
                RK.SetValue("(Default", clsid.ProgID);
                RK.CreateSubKey("TypeLib", true);
                RK.SetValue("(Default", clsid.TypeLib);
                RK.CreateSubKey("Version", true);
                RK.SetValue("(Default", clsid.Version);
                RK.Close(); 


 if ( RK != null ) 
     {
         MessageBox.Show("Success", "Success");
     }
 else 
     {
        MessageBox.Show("Failure", "Failure");

     }

In the above code, clsid is an object of class, clsRegistryCLSID, which is a part of my project:

    public clsRegistryCLSID(int ID, string hive, string rootObjectName, string ThreadingModel, string InprocServer32, string ProgID, string TypeLib, string Version, string EntryGuid)
    {

    public int ID { get; set; } 
    public string hive { get; set; }    
    public string RootObjectName { get; set; }
    public string ThreadingModel { get; set; }
    public string InprocServer32 { get; set; }  
    public string ProgID { get; set; }
    public string TypeLib { get; set; }
    public string Version { get; set; }
    public string EntryGuid { get; set; }   

Upvotes: 0

Views: 168

Answers (1)

It all makes cents
It all makes cents

Reputation: 4993

The following shows how to add subkeys to HKEY_CLASSES_ROOT\CLSID, as well as, values and data. I searched the (Win10) registry, found subkeys with similar names, and followed the structure of existing subkeys.

The structure of the subkey that is created in the code below is:

enter image description here


Create a new Windows Forms App (.NET Framework) project (name: RegistryCreateSubkeyAndValues)

Add an Application Manifest to your project

Note: This is used to prompt the user to execute the program as Administrator.

  • In VS menu, click Project
  • Select Add New Item...
  • Select Application Manifest File (Windows Only) (name: app.manifest)
  • Click Add

In app.manifest, replace

<requestedExecutionLevel level="asInvoker" uiAccess="false" />

with

<requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />

As can be seen in the image above, the subkeys are nested. To be in harmony with this concept, I'll create a variety of nested classes to hold the necessary information.

I'll name the top-level class RegClsid which will be created last to avoid errors showing in Visual Studio. To keep the class names organized, I've chosen to prepend each class name with its parent's name.

Create a class (name: RegClsidInprocServer32.cs) - name is RegClsid + InprocServer32 => RegClsidInprocServer32

public class RegClsidInprocServer32
{
    public string Default { get; set; }
    public string ThreadingModel { get; set; }
}

Create a class (name: RegClsidProgId.cs) - name is RegClsid + ProgId => RegClsidProgId

public class RegClsidProgId
{
    public string Default { get; set; }
}

Create a class (name: RegClsIdTypeLib.cs) - name is RegClsid + TypeLib => RegClsidTypeLib

public class RegClsIdTypeLib
{
    public string Default { get; set; }
}

Create a class (name: RegClsIdVersion.cs) - name is RegClsid + Version => RegClsidVersion

public class RegClsIdVersion
{
    public string Default { get; set; }
}

Create a class (name: RegClsid.cs)

public class RegClsid
{
    public string EntryGuid { get; set; }
    public RegClsidInprocServer32 InprocServer32 { get; set; } = new RegClsidInprocServer32();
    public RegClsidProgId ProgId { get; set; } = new RegClsidProgId();
    public RegClsIdTypeLib TypeLib { get; set; } = new RegClsIdTypeLib();
    public RegClsIdVersion Version { get; set; } = new RegClsIdVersion();
}

Add the following using directives:

  • using Microsoft.Win32;

The following shows how to add/update a registry subkey in HKEY_CLASSES_ROOT\CLSID. using statements are used to ensure that each RegistryKey is properly disposed.

Here's an illustration of the code below. Notice the nesting of the using statements and how the return value is used in each of the nested using statements.

enter image description here

AddUpdateRegClsid:

private bool AddUpdateRegClsid(RegClsid clsid, RegistryView regView = RegistryView.Registry64)
{
    //open HKCR hive using the specified view
    using (RegistryKey localKey = RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, regView))
    {
        if (localKey != null)
        {
            //open subkey with write permissions
            using (RegistryKey clsidKey = localKey.OpenSubKey(@"CLSID", true))
            {
                if (clsidKey != null)
                {
                    //create or open subkey with write permissions
                    using (RegistryKey guidKey = clsidKey.CreateSubKey(clsid.EntryGuid, true))
                    {
                        if (guidKey != null)
                        {
                            //create or open subkey 'InprocServer32' with write permissions
                            //HKCR\Clsid\<entryGuid>\InprocServer32
                            using (RegistryKey inprocServer32Key = guidKey.CreateSubKey("InprocServer32", true))
                            {
                                if (inprocServer32Key != null)
                                {
                                    //default
                                    inprocServer32Key.SetValue("", clsid.InprocServer32.Default, RegistryValueKind.String);
                                    
                                    //ThreadingModel
                                    inprocServer32Key.SetValue("ThreadingModel", clsid.InprocServer32.ThreadingModel, RegistryValueKind.String);
                                }
                            }

                            //create or open subkey 'ProgID' with write permissions
                            //HKCR\Clsid\<entryGuid>\ProgID
                            using (RegistryKey progidKey = guidKey.CreateSubKey("ProgID", true))
                            {
                                if (progidKey != null)
                                {
                                    //default
                                    progidKey.SetValue("", clsid.ProgId.Default, RegistryValueKind.String);
                                }
                            }

                            //create or open subkey 'TypeLib' with write permissions
                            //HKCR\Clsid\<entryGuid>\TypeLib
                            using (RegistryKey typeLibKey = guidKey.CreateSubKey("TypeLib", true))
                            {
                                if (typeLibKey != null)
                                {
                                    //default
                                    typeLibKey.SetValue("", clsid.TypeLib.Default, RegistryValueKind.String);
                                }
                            }

                            //create or open subkey 'Version' with write permissions
                            //HKCR\Clsid\<entryGuid>\Version
                            using (RegistryKey versionKey = guidKey.CreateSubKey("Version", true))
                            {
                                if (versionKey != null)
                                {
                                    //default
                                    versionKey.SetValue("", clsid.Version.Default, RegistryValueKind.String);
                                }
                            }

                            return true;
                        }
                    }
                }
            }
        }
    }

    return false;
}

Usage 1:

//ToDo: replace values below with desired values
//create new instance and set values
RegClsid clsid = new RegClsid()
{
    EntryGuid = "{3BDAAC43-E734-11D5-93AF-00105A990292}",
    InprocServer32 = new RegClsidInprocServer32() 
    { 
        Default = "My InprocServer32 default",
        ThreadingModel = "Both"
    },
    ProgId = new RegClsidProgId()
    {
        Default = "My ProgID default"
    },
    TypeLib = new RegClsIdTypeLib()
    {
        Default = "My TypeLib default"
    },
    Version = new RegClsIdVersion()
    {
        Default = "My Version default"
    }
};

//add CLSID entry to registry
bool result = AddUpdateRegClsid(clsid);

if (result)
    MessageBox.Show($@"'HKEY_Classes_Root\CLSID\{clsid.EntryGuid}' successfully added/updated.");
else
    MessageBox.Show($@"Error: Failed to add/update 'HKEY_Classes_Root\CLSID\{clsid.EntryGuid}'.");

Usage 2:

//ToDo: replace values below with desired values

//InprocServer32 - create new instance and set value(s)
RegClsidInprocServer32 inprocServer32 = new RegClsidInprocServer32()
{
    Default = "My InprocServer32 default",
    ThreadingModel = "Both"
};

//ProgID - create new instance and set values
RegClsidProgId progId = new RegClsidProgId()
{
    Default = "My ProgID default"
};

//TypeLib - create new instance and set value(s)
RegClsIdTypeLib typeLib = new RegClsIdTypeLib()
{
    Default = "My TypeLib default"
};

//Version - create new instance and set value(s)
RegClsIdVersion version = new RegClsIdVersion()
{
    Default = "My Version default"
};

//Clsid - create new instance and set values
RegClsid clsid = new RegClsid()
{
    EntryGuid = "{3BDAAC43-E734-11D5-93AF-00105A990292}",
    InprocServer32 = inprocServer32,
    ProgId = progId,
    TypeLib = typeLib,
    Version = version
};


//add CLSID entry to registry
bool result = AddUpdateRegClsid(clsid);

if (result)
    MessageBox.Show($@"'HKEY_Classes_Root\CLSID\{clsid.EntryGuid}' successfully added/updated.");
else
    MessageBox.Show($@"Error: Failed to add/update 'HKEY_Classes_Root\CLSID\{clsid.EntryGuid}'.");

Usage 3:

//ToDo: replace values below with desired values

//InprocServer32 - create new instance and set value(s)
RegClsidInprocServer32 inprocServer32 = new RegClsidInprocServer32();
inprocServer32.Default = "My InprocServer32 default";
inprocServer32.ThreadingModel = "Both";

//ProgID - create new instance and set value(s)
RegClsidProgId progId = new RegClsidProgId();
progId.Default = "My ProgID default";

//TypeLib - create new instance and set value(s)
RegClsIdTypeLib typeLib = new RegClsIdTypeLib(); 
typeLib.Default = "My TypeLib default";

//Version - create new instance and set value(s)
RegClsIdVersion version = new RegClsIdVersion();
version.Default = "My Version default";

//Clsid - create new instance and set values
RegClsid clsid = new RegClsid();
clsid.EntryGuid = "{3BDAAC43-E734-11D5-93AF-00105A990292}";
clsid.InprocServer32 = inprocServer32;
clsid.ProgId= progId;
clsid.TypeLib = typeLib;
clsid.Version = version;

//add CLSID entry to registry
bool result = AddUpdateRegClsid(clsid);

if (result)
    MessageBox.Show($@"'HKEY_Classes_Root\CLSID\{clsid.EntryGuid}' successfully added/updated.");
else
    MessageBox.Show($@"Error: Failed to add/update 'HKEY_Classes_Root\CLSID\{clsid.EntryGuid}'.");

Here's the result of executing the code above:

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here


The following shows how to delete the registry subkey and child subkeys from HKEY_CLASSES_ROOT\CLSID.

DeleteRegClsid:

private bool DeleteRegClsid(string entryClsid, RegistryView regView = RegistryView.Registry64)
{
    //open HKCR hive using the specified view
    using (RegistryKey localKey = RegistryKey.OpenBaseKey(RegistryHive.ClassesRoot, regView))
    {
        if (localKey != null)
        {
            //open subkey with write permissions
            using (RegistryKey clsidKey = localKey.OpenSubKey(@"CLSID", true))
            {
                if (clsidKey != null)
                {
                    //delete subkey and all child subkeys
                    clsidKey.DeleteSubKeyTree(entryClsid);

                    return true;
                }
            }
        }
    }

    return false;
}

Usage:

string entryGuid = "{3BDAAC43-E734-11D5-93AF-00105A990292}";
bool result = DeleteRegClsid(entryGuid);

if (result)
    MessageBox.Show($@"'HKEY_Classes_Root\CLSID\{entryGuid}' successfully deleted.");
else
    MessageBox.Show($@"Error: Failed to delete 'HKEY_Classes_Root\CLSID\{entryGuid}'.");

Resources:

Upvotes: 0

Related Questions