我最近在.NET(Visual Studio 2008,针对.NET 2.0的项目)中开发了一个用于VB6应用程序的互操作用户控件。程序集公开了1个控件、1个类以及一些枚举和结构。我用C#翻译的
Interop Forms Toolkit 2.0
项目模板
found here
. 程序集具有强名称,安装在GAC中,并使用以下脚本向regasm注册:
@"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"
问题是:
当我在我的机器上编译VB6应用程序时,它将在任何其他机器上正常运行(当然是安装了控件)。但是,当应用程序在另一台机器上编译时,它将在该机器上运行,但不会在任何其他机器上运行。当我说它不运行时,我的意思是你试图运行它,但绝对没有发生任何事情。
我使用OleView检查我的机器和另一台机器上的控件,并且所有的GUID在类型信息中都是相同的。唯一的区别是一个有importlib行(“stdole2.tlb”),另一个有importlib行(“stdole2.tlb”)。
我的机器有:Visual Studio 6.0 sp6、VB6互操作用户控件模板、Windows SDK 6.0和6.0A、Visual Studio 2008 sp1。这台机器是能工作的。
同事机器:Visual Studio 6.0 sp6,Visual Studio 2005
另一台机器:VisualStudio6.0SP6,VisualStudio2008。2008已于今天上午安装,但未纠正问题。
如何让这些其他机器正确编译VB6应用程序,使其在编译它的机器以外的机器上运行?
(将更多信息的请求放在评论中,我将对此进行编辑以提供答案。)
编辑:
可能是线索
如果有人熟悉OleView.exe的使用,我想我可能已经发现了线索。当我查看类型库列表时,有“OrderControl(0.1版)”和“OrderControlCtl(0.1版)”。第一个使用为程序集定义的GUID,路径显示使用RegAsm.exe生成的OrderControl.tlb。第二台机器在不同的机器上有不同的GUID,我的路径是“C:\Program Files\Microsoft Visual Studio\VB98\vbc00305.oca”,另一台机器上的路径是“C:\Program Files\Microsoft Visual Studio\VB98\mscoree.oca”,同事的机器上的路径是“C:\windows\system32\mscoree.oca”。两个mscoree.oca的大小相同,但我的计算机上的vbc00305.oca要小几KB。
我再次查看了VB6项目的参考资料。引用同时列出OrderControl和OrderControlCtl,但仅选中OrderControlCtl。OrderControl的位置是TLB文件,但OrderControlCtl的位置是OCA文件,每个工作站上的位置不同。
依赖步行者
我在DW中运行了在我的机器上编译的exe版本和在我们的构建机器上编译的exe版本的配置文件(在我的机器上不会运行)。它们在以下两条线处分叉。两者都有第一行,但运行的一行会继续进行更多的调用/加载,而不运行的一行会在第一行之后立即开始分离:
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.