I recently developed an interop user control in .NET (Visual Studio 2008, project targetting .NET 2.0) to be used in a VB6 application. The assembly exposes 1 control, 1 class, and a few enums and structs. I developed it using C# translations of the Interop Forms Toolkit 2.0 project template found here. The assembly has a strong name and gets installed in the GAC and registered with regasm with the following script:
@"C:\gacutil.exe" /i "C:\Program Files\AppName\Control.dll" /f
@"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\regasm.exe" "C:\Program Files\AppName\Control.dll" /tlb:"C:\Program Files\AppName\Control.tlb"
The Problem: When I compile the VB6 app on my machine, it will run just fine on any other machine (control installed, of course). However, when the app is compiled on a different machine, it will run on that machine, but not on any other machine. And when I say it doesn't run, I mean you try to run it and absolutely nothing happens.
I used OleView to examine the control on both my machine and the other machine, and all GUIDs are the same in the type information. The only difference was one had the line importlib("stdole2.tlb") and the other had importlib("STDOLE2.TLB").
My machine has: Visual Studio 6.0 sp6, VB6 interop user control templates, Windows SDK 6.0 and 6.0A, Visual Studio 2008 sp1. This machine is the one that works.
Coworkers machine: Visual Studio 6.0 sp6, Visual Studio 2005
Another machine: Visual Studio 6.0 sp6, Visual Studio 2008. 2008 was installed on this this morning and did not rectify the problem.
How do I get these other machines to compile the VB6 app correctly so that it runs on machines other than the one on which it was compiled?
(Put requests for more information in comments and I'll edit this to provide answers.)
Edits:
A suggestion was made regarding permissions in relation to registering the control. I'd like to clarify that the control seems to work well. I register it in the exact same way on the machine that works and the ones that don't. The problem manifests itself when the VB6 app that references the control is compiled on a machine other than my own.
I should also add that I had a small VB6 host app that had 1 form and the interop control and a couple buttons. This one does not exhibit the same problem as the main VB6 app.
Possibly a clue
If anybody is familiar with using OleView.exe, I think I may have discovered a clue. When I view the Type Libraries list, there is "OrderControl (Ver 0.1)" as well as "OrderControlCtl (Ver 0.1)". The first uses the GUID defined for the assembly and the path shows the OrderControl.tlb generated from using RegAsm.exe. The second has different GUIDs on the different machines and the path on mine is "C:\Program Files\Microsoft Visual Studio\VB98\vbc00305.oca", the path on the other machine is "C:\Program Files\Microsoft Visual Studio\VB98\mscoree.oca", and on the coworker's machine is "C:\windows\system32\mscoree.oca". Both mscoree.oca are the same size, but the vbc00305.oca on my machine is several KB smaller.
I looked again at the VB6 project's references. The references list both OrderControl and OrderControlCtl, but only OrderControlCtl is checked. OrderControl's location is the TLB file, but OrderControlCtl's location is the OCA file that's different on each station.
Dependency Walker
I ran profiles in DW for a version of the exe compiled on my machine and one compiled on our build machine (which won't run on mine). They diverge at the following 2 lines. Both have the first line, but the one that runs continues on with more calls/loads, while the one that does not run immediately begins detaching after the first line here:
GetProcAddress(0x7E720000 [SXS.DLL], "SxsOleAut32RedirectTypeLibrary") called from "OLEAUT32.DLL" at address 0x7712A637 and returned 0x7E746129.
GetProcAddress(0x7E720000 [SXS.DLL], "SxsOleAut32MapConfiguredClsidToReferenceClsid") called from "OLEAUT32.DLL" at address 0x7712A637 and returned 0x7E745C0D.
Try removing the user control from the form in your main VB6 app and re-adding it.
Not sure, but I had also issues like that. Try using regasm with /codebase.
I've since discovered that it had to do with 3 particular methods on my control that were 'returning' (via
ref
parameter) structs. I ended up using a workaround involving returning classes instead of structs. But I'm still curious, so I asked a different question.