How to get a 64bit ActiveX control to work in Visual Studio 2012? RRS feed

  • Question

  • We create ActiveX controls in Embarcadero Delphi for resale to clients to work in dozens of development environments. Our OCX file works in every development environment we tested, including 64 bit Internet Explorer using VBScript or JavaScript. We believe the issue is faulty assemblies. What do we have to do to get this to work? Is there a bug in VS creating 64 bit assemblies for ActiveX controls? Here are our steps:

    1. Install and register a 32bit version of the OCX in Program Files(x86)\ourcompany\myControl\  (32 bit version of the OCX)
    2. Install and register a 64bit version of the OCX in System32 (64 bit version of the OCX)
    3. Create a new windows forms project in VS2012, VB personality
    4. Make sure both platform and target are set for "any cpu"
    4. Drag the controls onto a form and create a small sample program. This creates the assemblies.

    5. Run the program.

    The first problem is a warning:

    A first chance exception of type 'System.Runtime.InteropServices.COMException' occurred in Microsoft.VisualStudio.HostingProcess.Utilities.dll

    The program then works just fine until any events fire. The controls calls into the windows API and the message from the callback function has 3 parameters that are DWORD_PTR types now. So I am guessing that a message with a 64bit parameter fires and crashes my system with the next series of errors:

    {"Access violation at address 0000000000737967 in module 'MyControl.ocx'. Read of address 0000000046DB4898"}
    Error Code: -2147418113
    Source: MyControl.Control1
    So "MyControl.Control1" is the assembly call to a method that returns a message (event) back from the API.
    System.Runtime.InteropServices.COMException was unhandled
      Message=Access violation at address 0000000000737967 in module 'MyControl.ocx'. Read of address 000000006EAB4898
           at MyControl.IControl1.Send()
           at AxMyControl.Control1.Sendl()
           at WindowsApplication1.Form1.Button1_Click(Object sender, EventArgs e) in C:\Users\Fred\AppData\Local\Temporary Projects\WindowsApplication1\Form1.vb:line 12
           at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
           at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
           at System.Windows.Forms.Control.WndProc(Message& m)
           at System.Windows.Forms.ButtonBase.WndProc(Message& m)
           at System.Windows.Forms.Button.WndProc(Message& m)
           at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
           at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
           at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
           at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
           at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
           at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
           at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
           at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
           at WindowsApplication1.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
           at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
           at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart()


    Do I need to manually create 64bit assemblies for the OCX? If so, where do I put them? Why doesn't Visual Studio generate the correct ones? How can I debug into the process to see which line inside the ActiveX or the interop assemblies is causing the problem? Thank you.
    Monday, February 18, 2013 3:15 PM

All replies

  • Instead of setting the Target to Any CPU, set x86 for 32 Bit Application & x64 for 64 Bit Application.

    Try to run the application with these settings & you will find it working without any issues.

    One more correction in your problem statement.

    2. Install and register a 64bit version of the OCX in System32 (64 bit version of the OCX)

    2. Install and register a 64bit version of the OCX in SysWow64 (64 bit version of the OCX)

    It all Happenz Sendil

    Monday, February 18, 2013 4:38 PM
  • Hi. I did try to create just an x64 compile to see if it would make a difference, it does not. And I believe I was correct in my statement to put the 64 bit version of my OCX in the System32 folder. The SysWow64 folder is for 32bit files. The System32 folder is for 64 bit files. As I mentioned, with the settings I am using, the 64bit OCX works in both Delphi and Internet Explorer 9, 64 bit. It does NOT work in Visual Studio 2012, VB project. Thanks.
    Tuesday, February 19, 2013 8:50 PM
  • Hi fndecker,

    I'll try to consult other engineers with this question

    It may take some time to get the result.

    Thanks for your patience.

    Best regards,

    Chester Hong
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, February 20, 2013 8:38 AM
  • Hi fndecker,

    Yes, we may need to manually generate these assemblies with AxImp.exe.  I believe they would be placed in the same directory with the .ocx then.  Can you try that to see if it resolves the crash?


    Thursday, February 21, 2013 9:47 PM
  • I am now wondering if this has something to do with the registry and now visual studio is finding the correct versions of the OCX.  The project can but BUILT, but not DEBUGGED! Here are my steps:

    1. Create the 32bit and 64bit OCX control in another development environment (Delphi)

    2. Register the OCXs the way we do for developers so we can have different versions of our software much like you can have different versons of Visual Studio.  64bit OCX in Program Files\company\version and 32bit OCX in Program Files (x86)\company\version. I used the developer command prompt and just ran "regsvr32 myOCX.ocx" by changing to the correct folder for each ocx. It would be nice if there was some clue as to what was happening, for example an output on the "ocx registered" box that let you know if you got the 64bit one or not. 

    3. Test the 32bit version, then change to x64. I can't debug the program because of "first chance" com exceptions and then actual com exceptions with certain properties and events. So I just click "build".

    4. If I try to run that application on the same machine, it doesn't run. There is no error, nothing in task manager, it just tries to load and then must exit somehow.

    5. If I take that same EXE and the assemblies that were automatically generated and go to a Windows 7 64bit machine it works! Any ideas?

    Friday, March 1, 2013 7:26 PM
  • I unregistered the 32bit and 64bit OCX, then reregistered them in System32 and SysWow64. Same result, I can not debug or run the 64 bit version of my code on this Windows 8 machine and VS 2012. I can still move the EXE, assemblies and OCXs to a Windows 7 machine and it works.
    Friday, March 1, 2013 8:40 PM