下面的建议与 Server.CreateObject 和 CreateObject 在
中的使用有关
vbscriptjscriptvba
Web 服务器部分特定于 asp-classic,但仍然值得一读。
什么原因导致这个错误?
Server.CreateObject 失败
最常见的原因是当 Web 应用程序从一个 Web 服务器移动到另一个 Web 服务器时,却不了解正在使用并在 Web 服务器上注册的外部 COM 组件。
来自PRB: Server.CreateObject Returns HTTP 500.100 or ASP 0177 Error (0x8007007E)
当您尝试使用 Server.CreateObject 方法来实例化未在本地系统上注册的对象时会发生此错误。
确定错误来源
如果您在 ASP Web 应用程序中使用 COM 组件,您将看到这样的一行
set g_pcmsrv=Server.CreateObject("PCMServer.PCMServer")
通常错误会指向Set 行,这使得识别原因更容易(幸运的是你有一些很好的跟踪代码,所以它更好)。
如果您不知道 DLL 的位置怎么办?
注意:在访问 Windows 注册表时请小心,因为很容易在不经意间做出对操作系统造成严重后果的更改,并且在极端情况下需要系统还原或重新安装/修复。
CreateObject 方法中的字符串称为ProgId,用作 Windows 注册表中的键的标识符,该键可在
注意: Windows 注册表可以在大多数版本的 Windows 中使用 regedit.exe 也称为注册表编辑器进行浏览。使用此工具浏览 Windows 注册表时要非常小心。
HKEY_CLASSES_ROOT
以及扩展
HKEY_LOCAL_MACHINE\Classes
每当 ASP 处理器遇到ProgId 时,它都会尝试与 Windows 注册表对话并找到一个对应的键,该键表示已注册的 COM 可访问 DLL 的位置。
HKEY_CLASSES_ROOT\PCMServer.PCMServer
对此的一种常见方法是密钥包含一个名为CLSID 的子项,该子项指向关联的已注册 DLL 的类 GUID。一旦 GUID 键位于
HKEY_CLASSES_ROOT\CLSID
hive 它可用于通过查看子键来查找位置
HKEY_CLASSES_ROOT\CLSID\{GUID from CLSID}\InprocServer32
(default) 值中将存储位置的位置。
使用ProgId - Scripting.FileSystemObject 的示例
-
在HKEY_CLASSES_ROOT 中找到Scripting.FileSystemObject 子键
HKEY_CLASSES_ROOT\Scripting.FilesystemObject
-
从子项 CLSID 中识别 GUID
HKEY_CLASSES_ROOT\Scripting.FilesystemObject\CLSID
(default) - "{0D43FE01-F093-11CF-8940-00A0C9054228}"
-
使用 GUID 在HKEY_CLASSES_ROOT\CLSID 中查找已注册的 DLL 子键
HKEY_CLASSES_ROOT\CLSID\{0D43FE01-F093-11CF-8940-00A0C9054228}
-
检查 DLL 位置的子项 InprocServer32 (default) 值
HKEY_CLASSES_ROOT\CLSID\{0D43FE01-F093-11CF-8940-00A0C9054228}\InprocServer32
(default) - "C:\Windows\System32\scrrun.dll"
在注册表中没有ProgId for PCMServer.PCMServer?
如果您在注册表中找不到相应的ProgId,可能是由于我们将在此处详细说明的两个原因之一。
- DLL 未注册。
- DLL 注册在错误的区域。
如何在 Windows 中注册 COM DLL
COM DLL 可以通过使用提升的权限从 Windows 命令提示符运行 regsvr32.exe 工具来注册并创建相应的注册表项(这因 Windows 版本而异)。 p>
在我们继续之前,操作系统的体系结构和 ASP Web 应用程序使用的模式都非常重要。
大多数较新的硬件是 64 位,这在 Windows 中造成了一个难题,因为它现在必须支持较新的 64 位体系结构并仍然保持对 32 位体系结构的支持。微软提出的解决方案是将操作系统一分为二,因此我们有 64 位元素和 32 位元素。主要的操作系统程序分为两个文件夹(仅在 64 位操作系统上,因为 32 位操作系统不必与 64 位竞争,即使硬件有能力)。 p>
注意:仅在 32 位系统上,系统文件和 Windows 注册表仅使用 64 位位置。
在 64 位操作系统上,系统程序位于
-
对于 64 位程序
%SystemRoot%\System32\
-
对于 32 位程序
%SystemRoot%\SysWOW64\
这也适用于 Windows 注册表
-
64 位
HKEY_CLASSES_ROOT
-
32 位
HKEY_CLASSES_ROOT\Wow6432Node
例如在 64 位版本的 Windows 上,以下命令将在 32 位注册表中注册 PCMSRV32.DLL 并创建关联的 COM DLL 注册表项。
C:\Windows\SysWOW64>regsvr32 "C:\Windows\PCMSRV32.DLL"
IIS 应用程序池
随着一切都开始支持 64 位,包括 IIS,您仍然需要能够支持仅支持 32 位 COM 的旧版应用程序,因此 IIS 6.0 中引入了 IIS(从 Windows Server 2003,Service Pack 1 开始) 在应用程序池设置下的可配置属性Enabled32BitAppOnWin64 允许应用程序池在 64 位版本的 Windows 上以 32 位模式运行。
考虑到这一点,在您注册 COM DLL 以了解您应该在哪里注册它之前,您需要知道应用程序池是否在 32 位模式下运行。在 IIS 7.0 及更高版本中,您可以从 IIS 管理器应用程序内的应用程序池属性中检查这一点。该设置在General 部分下的Advanced Settings 中,称为Enable 32-Bit Applications (也可以在applicationHost.config 中使用enable32BitAppOnWin64 在enable32BitAppOnWin64 部分下进行配置)。
-
如果 Enable 32-Bit Applications 设置为 False
IIS 应用程序池在本机 64 位模式下运行,任何需要由 ASP Web 应用程序使用的 COM DLL 都需要支持 64 位并使用 regsvr32.exe 的 64 位版本注册以添加到64 位注册表。
C:\Windows\System32>regsvr32 "C:\Windows\PCMSRV32.DLL"
-
如果Enable 32-Bit Applications 设置为True
IIS 应用程序池在 32 位模式下运行,任何需要由 ASP Web 应用程序使用的 COM DLL 都需要是 32 位 COM DLL,并使用要添加的 32 位版本的regsvr32.exe 注册进入 32 位注册表。
C:\Windows\SysWOW64>regsvr32 "C:\Windows\PCMSRV32.DLL"
使用错误版本的regsvr32.exe注册COM DLL
例如,使用
C:\Windows\SysWOW64>regsvr32 "C:\Windows\PCMSRV32.DLL"
当 IIS 应用程序池不是 32 位模式时,在 64 位版本的 Windows 上将 COM DLL 注册到 32 位注册表会导致 ASP 500.100 内部服务器错误
服务器对象错误“ASP 0177: 8007007e”
Server.CreateObject 失败
COM DLL 清单
IIS 应用程序池高级设置Enable 32-Bit Applications 设置为什么,因为它会影响您注册 COM DLL 的方式?
DLL 是否使用regsvr32.exe 的特定架构版本注册(如果 Windows 版本不是 64 位,则使用默认值) 是否反映了 Enable 32-Bit Applications 的设置?
-
Windows 注册表是否包含ProgId 用于 DLL 的体系结构特定位置
HKEY_CLASSES_ROOT
反映Enable 32-Bit Applications的设置?
InprocServer32 键是否包含 DLL 的正确位置?
在我用来访问 COM DLL (ApplicationIdentity、LocalSystem、NetworkService 等)的帐户的上下文中,我是否有权访问物理 DLL 文件和注册表项?
有用的链接