none
64 Bit ActiveX component in C# RRS feed

  • Question

  • So, I've created a COM-exposed user control, which is basically working fine when compiled as x86 (or AnyCPU and run on a 32-bit OS).

    The class looks like this:

        [ProgId("Test.TestControl")]
        [ClassInterface(ClassInterfaceType.AutoDual)]
        public partial class TestControl : UserControl
        {
            public TestControl()
            {
                InitializeComponent();
            }
    
    
            //
            // Publicly visible method
            //
            public void DoSomething()
            {
                MessageBox.Show("Alive!");
                return;
            }
    
    
            //
            // COM Interop
            //
            [ComRegisterFunction()]
            public static void RegisterClass(string key)
            {
                // Strip off HKEY_CLASSES_ROOT\ from the passed key as I don't need it
                StringBuilder sb = new StringBuilder(key);
                sb.Replace(@"HKEY_CLASSES_ROOT\", "");
    
                // Open the CLSID\{guid} key for write access
                RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
    
                // And create the 'Control' key - this allows it to show up in 
                // the ActiveX control container 
                RegistryKey ctrl = k.CreateSubKey("Control");
                ctrl.Close();
    
                // Next create the CodeBase entry - needed if not string named and GACced.
                RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
                inprocServer32.SetValue("CodeBase", Assembly.GetExecutingAssembly().CodeBase);
                inprocServer32.Close();
    
                // Finally close the main key
                k.Close();
            }
    
            [ComUnregisterFunction()]
            public static void UnregisterClass(string key)
            {
                StringBuilder sb = new StringBuilder(key);
                sb.Replace(@"HKEY_CLASSES_ROOT\", "");
    
                // Open HKCR\CLSID\{guid} for write access
                RegistryKey k = Registry.ClassesRoot.OpenSubKey(sb.ToString(), true);
    
                // Delete the 'Control' key, but don't throw an exception if it does not exist
                k.DeleteSubKey("Control", false);
    
                // Next open up InprocServer32
                RegistryKey inprocServer32 = k.OpenSubKey("InprocServer32", true);
    
                // And delete the CodeBase key, again not throwing if missing 
                k.DeleteSubKey("CodeBase", false);
    
                // Finally close the main key 
                k.Close();
            }
        }
    

    Then, I've added a post-build event that registers the control in a 64 bit environment.

    "%Windir%\Microsoft.NET\Framework64\v4.0.30319\regasm" "$(TargetPath)"

    All of this is working fine, basically. To test the concept, I've compiled TstCon, both as x86 and x64 executable.

    With the 32bit TstCon, I see the registered 32 bit build of my library, I can add it to the container, execute methods, no problem.

    With the 64bit TstCon, I see the registered 64 bit build of my library, but when I try to add it, I get the error "Failed to create control: Unknown error".

    I've also downloaded CSActiveX-c3f43e7d from the All-In-One Code Framework, but the same problem appears with that. 32 bit is fine, 64 errors out.

    Friday, April 20, 2012 9:27 AM

Answers

All replies

  • I think you are getting this error on x86 machine right? That is because 64 bit application cannot be run on 32 bit machines.

    I hope this makes sense.


    Please mark this post as answer if it solved your problem. Happy Programming!

    Friday, April 20, 2012 10:11 AM
  • Hi,

    When you register 64bit activex on 64bit computer, you need to register on x64 command line first, then register on x86 command line, this will write registry to both x64 and wow6432.

    Refer to: http://social.msdn.microsoft.com/Forums/en-US/isvvba/thread/35fa7a48-6319-4fc4-8d53-e20e7f08e6d2


    Forrest Guo | MSDN Community Support | Feedback to manager

    • Marked as answer by Veichtlbauer Tuesday, April 24, 2012 5:47 AM
    Monday, April 23, 2012 1:21 PM
  • Adavesh: no, I am (rather obviously) working on a x64 machine. There is no way i could even start TstCon (the x64 build!) on a x86 machine...

    Forrest: unfortunately, I still have the same problem, even after registering the DLL with a 32- and 64-bit RegAsm. Still "Failed to create control: Unknown error". Would be grateful for any other advise.

    I should add that I had the "register for COM Interop" checked before, which I assumed registers the control for 32bit. Anyhow, to be sure, now I changed my post-build event to this:

    "%Windir%\Microsoft.NET\Framework\v4.0.30319\regasm" "/unregister" "$(TargetPath)"
    "%Windir%\Microsoft.NET\Framework64\v4.0.30319\regasm" "/unregister" "$(TargetPath)"
    
    "%Windir%\Microsoft.NET\Framework64\v4.0.30319\regasm" "$(TargetPath)"
    "%Windir%\Microsoft.NET\Framework\v4.0.30319\regasm" "$(TargetPath)"
    Monday, April 23, 2012 2:13 PM
  • Correction, the last mishap was entirely my mistake, Forrest: you are my new hero! Thanks bunches!!!!
    Tuesday, April 24, 2012 5:47 AM
  • Glad to know you resolved it !

    Forrest Guo | MSDN Community Support | Feedback to manager

    Tuesday, April 24, 2012 5:52 AM
  • Hi Veichtbauer,

    I have the same issue :-s

    Could you help to give more detail on how to solve the problem ?

    at Post build, I added

    "%Windir%\Microsoft.NET\Framework64\v4.0.30319\regasm" "$(TargetPath)"
    "%Windir%\Microsoft.NET\Framework\v4.0.30319\regasm" "$(TargetPath)"

    but seem it does not work :(

    Monday, March 18, 2013 10:27 AM