32位DLL在Server 2008上"可能不兼容",但在Server 2003上可以正常工作。

22
我们有一个项目,可以编译成32位COM DLL和64位COM DLL(与我之前的问题中相同)。在我的Windows 7机器上注册这两个DLL时,都能成功注册。在Windows Server 2003机器上注册这两个DLL时也都能成功注册。
但是,在Windows Server 2008 R2标准SP1机器上尝试注册这些DLL时,64位DLL可以成功注册,但是32位DLL失败,并显示以下错误信息(原文如下): The module ""%1"" may not compatible with the version of Windows that you're running. Check if the module is compatible with an x86 (32-bit) or x64 (64-bit) version of regsvr32.exe. 我认为一个32位DLL不能兼容WS2003和Win7,却不兼容WS2008。这毫无意义。
可能会发生什么情况呢?

1
这可能是一个愚蠢的问题,但如果您同时拥有32位和64位版本的程序集,那么为什么要尝试在64位操作系统上注册32位版本呢? - NotMe
6
为什么错误信息中会出现语法错误呢?这是否暗示着当前情况不太妙? - arsaKasra
2
回答第一个愚蠢的问题:质量保证。由于64位Windows支持32位DLL,我们必须确保我们的32位DLL在这种情况下能够正常工作。 - Null Pointers etc.
5
回答第二个愚蠢的问题:微妙的语法错误在于消息本身。读者可能会读成“may not be compatible”,尽管消息实际上是写着“may not compatible”。毕竟,这并不像臭名昭著的“All your base are belong to us.”那样明显糟糕。 - Null Pointers etc.
6个回答

14

Regsvr32.exe版本必须与您要注册的DLL文件的32位/64位相匹配。64位regsvr32无法加载32位dll,反之亦然。

您可能需要显式调用位于%systemroot%\SysWoW64\regsvr32.exe中的32位版本的regsrv32。

来自http://support.microsoft.com/kb/249873

Regsvr32.exe包括在Microsoft Internet Explorer 3.0或更高版本、Windows 95 OEM Service Release 2(OSR2)或更高版本以及Windows NT 4.0 Service Pack 5(SP5)或更高版本中。Regsvr32.exe安装在System(Windows Me / Windows 98 / Windows 95)或System32(Windows NT / Windows XP / Windows Vista / Windows 7)文件夹中。

注意,在Windows操作系统的64位版本中,有两个版本的Regsv32.exe文件:

  • 64位版本为%systemroot%\System32\regsvr32.exe。
  • 32位版本为%systemroot%\SysWoW64\regsvr32.exe。

Regsvr32.exe用法 RegSvr32.exe具有以下命令行选项: Regsvr32 [/u] [/n] [/i:cmdline] dllname

/u - 注销服务器 /i - 调用DllInstall并传递可选的[cmdline];与/u一起使用时调用dll卸载 /n - 不调用DllRegisterServer;此选项必须与/i一起使用 /s - 静默;不显示消息框(添加在Windows XP和Windows Vista中) 当您使用Regsvr32.exe时,它会尝试加载组件并调用其DLLSelfRegister函数。如果此尝试成功,Regsvr32.exe会显示指示成功的对话框。如果尝试失败,则Regsvr32.exe返回错误消息。这可能包括Win32错误代码。有关详细信息,请单击以下文章编号查看Microsoft Knowledge Base中的文章: 193625 WinInet错误代码(12001至12156)


3
64位的regsvr32版本可以委派给32位版本来(取消)注册32位DLL,反之亦然。更有可能的情况是WOW64根本没有安装。从Windows Server 2008 R2开始,WOW64现在是一个可选组件。 - Remy Lebeau
5
我们已经尝试使用SysWOW64\regsvr32来注册32位的DLL文件,但是仍然出现了相同的错误。 - Null Pointers etc.

6

在您的情况下,这不太可能是问题,但对于通过搜索相同错误消息找到此问题的其他人可能会有用:

我遇到了类似的问题:一个DLL文件无法在32位或64位版本的RegSvr32中注册。我使用依赖项检查器(depends.exe,http://www.dependencywalker.com/)加载了DLL,并获得了更有用的消息:

错误:至少有一个文件不是32位或64位Windows模块。

在模块列表中扫描CPU列可以确定有问题的模块。(在我的情况下,它说“未找到DOS或PE签名。此文件不是有效的32位或64位Windows模块。”)

寓意:依赖项检查器可能会给您比RegSvr32.exe更有用的错误消息。


这为我展示了问题的根源。我的路径是这样的,加载的是64位dll而不是32位版本。 - Armbie

3
我将其注册,将dll移动到c:\windows\syswow64\目录下(如果放在system32目录下将不起作用),然后显式地调用syswow64\regsvr32,例如:
c:\windows\syswow64\regsvr32 yourdll.dll
顺便提一下,当调用c:\windows\syswow64\regsvr32 c:\windows\syswow64\yourdll.dll时也无法正常工作。

2
使用SysInternals的Process Monitor1. 按“进程名称”筛选 = regsvr32.exe。

Filter

2. 尝试使用正确版本的regsvr32.exe(32位版本在SysWow64文件夹中)注册您的DLL文件。
3. 进程监视器将跟踪计算机上发生的所有事情。
4. 首先通过消除注册表事件(目前)来开始分析:

enter image description here

您可以看到哪些 DLL 文件被找到和未找到。以下是 Threed32.ocx 的 regsvr32.exe 的(非常)部分截图,其中我们可以看到一些所需的 DLL 文件:

enter image description here

你的工作才刚刚开始。从现在起。

1
以管理员身份运行命令提示符解决了我的问题。

1

我有同样的问题,但是我用命令解决了它

CD \windows\syswow64 regsvr32 c:\filename. dll


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接