Click here to Skip to main content
15,890,557 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi All,

I have a COM DLL which has to be registered at run time when my application starts.

I have used the below code...


C++
Assembly asm = Assembly.LoadFile (@"D:Test\TestCOM.dll");
RegistrationServices regAsm = new RegistrationServices();
bool bResult = regAsm.RegisterAssembly(asm, AssemblyRegistrationFlags.SetCodeBase);



The problem is, It is getting registered when the user is a power user or administrator. Its not getting register in registry when the user have a normal user previlege.


Any other way to register the COM DLL with the normal user previlege in runtime through c#?


Thanks in advance..
Mydeen.
Posted

You could try to run regsvr32, but I suspect you'll find you'll have the same issue. Given that a non admin is often limited in access to the registry, I suspect you will find you need your user to log in as admin to install your program because you used COM. There is no reason to use COM for your C# dlls, unless you need them to work with other languages.
 
Share this answer
 
A service started by user SYSTEM
could perform such tasks for its "non SYSTEM" clients... :)
 
Share this answer
 
My simple solution works with some restrictions. Do not calls methods marked by [ComRegisterFunction]. Also works only for "Any CPU" assemlies.
C#
Assembly assembly = Assembly.LoadFile("drive:\\my.dll");
Type[] Types = assembly.GetExportedTypes();

foreach (Type type in Types)
{
    ComVisibleAttribute[] attributes = (ComVisibleAttribute[])type.GetCustomAttributes(typeof(ComVisibleAttribute), false);

    if (attributes.Length > 0 && attributes[0].Value)
    {
        Register(type);
    }

}

C#
static void Register(Type type)
{
    string ProgID = type.FullName;
    string Version = type.Assembly.GetName().Version.ToString();
    string GUIDstr = "{" + type.GUID.ToString() + "}";
    string keyPath = @"Software\Classes\";


    RegistryKey regularx86View = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry32);

    RegistryKey regularx64View = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64);
 
    RegistryKey[] keys = {regularx86View.OpenSubKey(keyPath, RegistryKeyPermissionCheck.ReadWriteSubTree, System.Security.AccessControl.RegistryRights.FullControl),
                    regularx64View.OpenSubKey(keyPath, RegistryKeyPermissionCheck.ReadWriteSubTree, System.Security.AccessControl.RegistryRights.FullControl)};

            
    ProgIdAttribute[] attributes = (ProgIdAttribute[])type.GetCustomAttributes(typeof(ProgIdAttribute), false);

    if (attributes.Length > 0)
        ProgID = attributes[0].Value;

    foreach(RegistryKey RootKey in keys)
    {
        //[HKEY_CURRENT_USER\Software\Classes\Prog.ID]
        //@="Namespace.Class"
                
        RegistryKey keyProgID = RootKey.CreateSubKey(ProgID);
        keyProgID.SetValue(null, type.FullName);

        //[HKEY_CURRENT_USER\Software\Classes\Prog.ID\CLSID]
        //@="{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
        keyProgID.CreateSubKey(@"CLSID").SetValue(null, GUIDstr);


        //[HKEY_CURRENT_USER\Software\Classes\CLSID\{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}]
        //@="Namespace.Class
        //
        RegistryKey keyCLSID = RootKey.OpenSubKey(@"CLSID", RegistryKeyPermissionCheck.ReadWriteSubTree, System.Security.AccessControl.RegistryRights.FullControl).CreateSubKey(GUIDstr);
        keyCLSID.SetValue(null, type.FullName);


        //[HKEY_CURRENT_USER\Software\Classes\CLSID\{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}\ProgId]
        //@="Prog.ID"
        keyCLSID.CreateSubKey("ProgId").SetValue(null, ProgID);


        //[HKEY_CURRENT_USER\Software\Classes\CLSID\{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}\InprocServer32]
        //@="mscoree.dll"
        //"ThreadingModel"="Both"
        //"Class"="Namespace.Class"
        //"Assembly"="AssemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=71c72075855a359a"
        //"RuntimeVersion"="v4.0.30319"
        //"CodeBase"="file:///Drive:/Full/Image/Path/file.dll"
        RegistryKey InprocServer32 = keyCLSID.CreateSubKey("InprocServer32");
        SetInprocServer(InprocServer32, type, false);

        //[HKEY_CURRENT_USER\Software\Classes\CLSID\{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}\InprocServer32\1.0.0.0]
        //"Class"="Namespace.Class"
        //"Assembly"="AssemblyName, Version=1.0.0.0, Culture=neutral, PublicKeyToken=71c72075855a359a"
        //"RuntimeVersion"="v4.0.30319"
        //"CodeBase"="file:///Drive:/Full/Image/Path/file.dll"
        SetInprocServer(InprocServer32.CreateSubKey("Version"), type, true);

        //[HKEY_CURRENT_USER\Software\Classes\CLSID\{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}]
        keyCLSID.CreateSubKey(@"Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}");

        keyCLSID.Close();
    }

}

C#
static void SetInprocServer(RegistryKey key, Type type, bool versionNode)
{

    if (!versionNode)
    {
        key.SetValue(null, "mscoree.dll");
        key.SetValue("ThreadingModel", "Both");
    }

    key.SetValue("Class", type.FullName);
    key.SetValue("Assembly", type.Assembly.FullName);
    key.SetValue("RuntimeVersion", type.Assembly.ImageRuntimeVersion);
    key.SetValue("CodeBase", type.Assembly.CodeBase);
}
 
Share this answer
 
Comments
anemos_78 3-Dec-20 18:38pm    
Solution-3 must register Interface Id's.

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900