我们创建了一个 C# 类库程序集,并将其设置为 COM 可见,以便能够从 PHP 调用其方法。这曾经运行良好,但现在我们想将其安装在 Windows Server 2008 服务器上,并且不断遇到“类未注册”错误。
为了排除任何依赖性问题,我用 C# 制作了一个很小的测试类库。该类库是为任何 CPU 构建的,并且它是 COM 可见的(还在 AssemblyInfo.cs 中将 COMVisible 设置为 true)。测试类库仅包含一个类和一种方法。该类称为 TestLib,命名空间也称为 TestLib。该方法称为 Test,仅返回一个字符串。
我们所做的如下:
- 构建了 TestLib.dll
- 将其复制到 Windows Server 2008 计算机
- 将 dll 注册为:regasm /codebase TestLib.dll
- regasm 工具返回成功消息
- 在 PHP 中,我们只是尝试创建一个新的 COM 实例:
try
{
$test = new COM("TestLib.TestLib");
}
catch (Exception $e)
{
die($e->getMessage());
}
- 当我们从浏览器或命令行(php -f test.php)调用此测试脚本时,我们在两种情况下都会收到错误“类未注册”
我还尝试使用 gacutil -i 将 TestLib 添加到 GAC,但没有成功;仍然是类未注册错误。
然后我尝试使用 .NET 2.0 而不是 4.0 作为目标框架来编译 testlibrary,结果相同。顺便在服务器上安装了.NET Framework 4.0。
有任何想法吗?
好吧,经过更多研究后我明白了。 php.exe进程是32位的。 COM 可见程序集是为任何 CPU 编译的,因此 32 位和 64 位应用程序都应该可以访问它。
问题是,在 64 位操作系统 php.exe 以及任何 32 位进程上,在 HKEY_CLASSES_ROOT\Wow6432Node\CLSID 而不是 HKEY_CLASSES_ROOT\CLSID 中搜索,在 HKEY_LOCAL_MACHINE\Software\Classes\Wow6432Node\CLSID 而不是 HKEY_LOCAL_MACHINE\Software 中搜索\类\CLSID。 Wow6432 项中的注册表项不是由 Windows Server 2008 上的 .NET Framework v4 附带的 regasm 创建的。在 Windows 7 上它们是创建的,不要问我为什么。
事实证明,如果我为 .NET v2.0 创建一个小测试程序集并使用 .NET Framework v2.0 附带的 regasm 注册它,它确实会在 Windows 2008 上创建 Wow6432Node 条目。奇怪。
所以我的解决方案是使用以下命令在服务器上创建一个基本的注册表文件:
regasm /regfile MyClassLib.dll
这将创建一个仅包含“正常”64 位条目的文件 MyClassLib.reg。然后,我从 Windows 7 计算机导出 Wow6432Node 密钥并将其添加到该 .reg 文件中。现在,当我将该 reg 文件导入 Windows 2008 上的注册表时,一切正常。
有关 Wow6432Node 条目的更多信息,请查看:http://msdn.microsoft.com/en-us/library/windows/desktop/ms724072%28v=vs.85%29.aspx http://msdn.microsoft.com/en-us/library/windows/desktop/ms724072%28v=vs.85%29.aspx
希望这可以节省其他人的时间和头痛。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)