错误ASP 0177:8007007e Server.CreateObject因COM DLL而失败

Kar*_*art 3 com dll vbscript asp-classic

我们一直在尝试在新服务器上安装COM DLL.界面是经典ASP.地图连接器DLL似乎是问题,但这是我能够得到的.

我们无法让IIS提供的页面提供除500错误之外的任何内容.

跟踪ASP时:

127.  -ASP_SCRIPT_TRACE_COM_CALL_END 


FilePath
C:\INETPUB\WWWROOT\MILER\GLOBAL.ASA 

LineNumber
6 

CurrentStatement
set g_pcmsrv=Server.CreateObject("PCMServer.PCMServer") 

SizeOfStatement
55 


0 ms


128.  -ASP_LOG_ERROR 


LineNumber
6 

ErrorCode
ASP 0177 : 8007007e 

Description
Server.CreateObject Failed

DLL PCMSRV32.DLLc:\windows

GLOBAL.ASA:

Sub Application_OnStart


set g_pcmsrv=Server.CreateObject("PCMServer.PCMServer")
set application("g_pcmsrv") = g_pcmsrv

set g_pcmmapmgr=Server.CreateObject("Pcmgole.PCMMapMgr")
set application("g_pcmmapmgr") = g_pcmmapmgr


End Sub

Sub Session_OnStart
set Session("currentTrip") = application("g_pcmsrv").NewTrip("NA")
set Session("map") = application("g_pcmmapmgr").createMap()
End Sub

Sub Session_OnEnd
set Session("currentTrip") = Nothing
set Session("map") = Nothing
End Sub

Sub Application_Onend
Set application("g_pcmsrv")=Nothing
Set application("g_pcmmapmgr")=Nothing
End Sub
Run Code Online (Sandbox Code Playgroud)

Lan*_*art 20

以下建议涉及两者Server.CreateObjectCreateObject使用

Web服务器部分特定于但仍值得一读.


是什么导致此错误?

Server.CreateObject失败

当Web应用程序从一个Web服务器移动到另一个Web服务器而不了解正在使用并向Web服务器注册的外部COM组件时,最常出现这种情况.

PRB:Server.CreateObject返回HTTP 500.100或ASP 0177错误(0x8007007E)

当您尝试使用Server.CreateObject方法实例化未在本地系统上注册的对象时,会发生此错误.

识别错误的来源

如果您在ASP Web应用程序中使用COM组件,您将看到如下所示的行

set g_pcmsrv=Server.CreateObject("PCMServer.PCMServer") 
Run Code Online (Sandbox Code Playgroud)

通常错误将指向Set使得更容易识别原因的行(幸运的是,你有一些很好的跟踪代码,所以它甚至更好).

如果您不知道DLL位于何处?

注意:访问Windows注册表时请务必小心,因为更容易无意中进行对操作系统造成严重后果的更改,在极端情况下需要进行系统还原或重新安装/修复.

方法中的字符串CreateObject称为a ProgId,用作Windows注册表中可以在其中找到的键的标识符

注意: Windows注册表可以在大多数Windows版本中使用regedit.exe也称为注册表编辑器进行浏览.使用此工具浏览Windows注册表时要非常小心.

HKEY_CLASSES_ROOT
Run Code Online (Sandbox Code Playgroud)

并通过扩展

HKEY_LOCAL_MACHINE\Classes
Run Code Online (Sandbox Code Playgroud)

每当ASP处理器遇到ProgId它时,它都会尝试与Windows注册表进行通信,并找到一个相应的密钥,该密钥表示已注册的COM可访问DLL的位置.

HKEY_CLASSES_ROOT\PCMServer.PCMServer
Run Code Online (Sandbox Code Playgroud)

一种常见的方法是密钥包含一个被调用的子密钥,该子密钥CLSID指向相关注册DLL的类GUID.一旦GUID键位于

HKEY_CLASSES_ROOT\CLSID
Run Code Online (Sandbox Code Playgroud)

通过查看子项,可以使用它来查找位置

HKEY_CLASSES_ROOT\CLSID\{GUID from CLSID}\InprocServer32
Run Code Online (Sandbox Code Playgroud)

位置将存储在(default)值中.

示例使用ProgId-Scripting.FileSystemObject

  1. 找到Scripting.FileSystemObject子项HKEY_CLASSES_ROOT

    HKEY_CLASSES_ROOT\Scripting.FilesystemObject
    
    Run Code Online (Sandbox Code Playgroud)
  2. 从子项中识别GUID CLSID

    HKEY_CLASSES_ROOT\Scripting.FilesystemObject\CLSID
    
    (default) - "{0D43FE01-F093-11CF-8940-00A0C9054228}"  
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用GUID查找已注册的DLL子项 HKEY_CLASSES_ROOT\CLSID

    HKEY_CLASSES_ROOT\CLSID\{0D43FE01-F093-11CF-8940-00A0C9054228}
    
    Run Code Online (Sandbox Code Playgroud)
  4. 检查InprocServer32 (default)DLL位置的子项值

    HKEY_CLASSES_ROOT\CLSID\{0D43FE01-F093-11CF-8940-00A0C9054228}\InprocServer32
    
    (default) - "C:\Windows\System32\scrrun.dll"
    
    Run Code Online (Sandbox Code Playgroud)

没有ProgId用于PCMServer.PCMServer在注册表中?

如果您ProgId在注册表中找不到相应的内容,可能是由于我们将在此详述的两个原因之一.

  1. DLL未注册.
  2. DLL在错误的区域中注册.

如何在Windows中注册COM DLL

可以注册COM DLL并通过regsvr32.exe使用提升的权限从Windows命令提示符运行该工具来创建相应的注册表项(这在Windows的版本之间有所不同).

在我们继续之前,操作系统和ASP Web应用程序使用的模式的架构非常重要.

大多数较新的硬件是64位,这在Windows中造成了一个难题,因为它现在必须支持更新的64位架构,并且仍然支持32位架构.微软提出的解决方案是将操作系统分成两部分,因此我们有64位元素和32位元素.主OS程序分为两个文件夹(仅在64位操作系统上,因为32位操作系统不必与64位竞争,即使硬件能够支持它).

注意:在32位仅系统上,只使用系统文件和Windows注册表的64位位置.

在64位操作系统上,系统程序位于

  1. 对于64位程序

    %SystemRoot%\System32\
    
    Run Code Online (Sandbox Code Playgroud)
  2. 对于32位程序

    %SystemRoot%\SysWOW64\
    
    Run Code Online (Sandbox Code Playgroud)

这也适用于Windows注册表

  1. 64位

    HKEY_CLASSES_ROOT
    
    Run Code Online (Sandbox Code Playgroud)
  2. 32位

    HKEY_CLASSES_ROOT\Wow6432Node
    
    Run Code Online (Sandbox Code Playgroud)

因此,例如在64位版本的Windows上,以下命令将PCMSRV32.DLL在32位注册表中注册并创建关联的COM DLL注册表项.

C:\Windows\SysWOW64>regsvr32 "C:\Windows\PCMSRV32.DLL"
Run Code Online (Sandbox Code Playgroud)

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管理器应用程序内的"应用程序池"属性中进行检查.该设置位于该部分Advanced Settings下方General并被调用Enable 32-Bit Applications (也可以在该部分下applicationHost.config使用中进行配置)enable32BitAppOnWin64<ApplicationPools>.

  • 如果Enable 32-Bit Applications设置为False

    IIS应用程序池以本机64位模式运行,并且需要由ASP Web应用程序使用的任何COM DLL都需要支持64位并使用64位版本进行注册regsvr32.exe以添加到64位注册表中.

    C:\Windows\System32>regsvr32 "C:\Windows\PCMSRV32.DLL"
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果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"
    
    Run Code Online (Sandbox Code Playgroud)

使用错误版本的注册COM DLL regsvr32.exe

例如使用

C:\Windows\SysWOW64>regsvr32 "C:\Windows\PCMSRV32.DLL"
Run Code Online (Sandbox Code Playgroud)

当IIS应用程序池不在32位模式下时,在64位版本的Windows上注册COM DLL与32位注册表将导致ASP 500.100内部服务器错误

服务器对象错误'ASP 0177:8007007e'

Server.CreateObject失败


COM DLL清单

  1. 什么是IIS应用程序池高级设置Enable 32-Bit Applications设置为,因为它会影响您注册COM DLL的方式?

  2. 是使用体系结构特定版本regsvr32.exe (如果Windows版本不是64位使用默认值)注册的DLL ,它反映了设置Enable 32-Bit Applications

  3. Windows注册表是否包含ProgId针对特定于体系结构的位置的DLL

    HKEY_CLASSES_ROOT
    
    Run Code Online (Sandbox Code Playgroud)

    那反映了Enable 32-Bit Applications什么?

  4. InprocServer32密钥是否包含DLL的正确位置?

  5. 在我用来访问COM DLL (ApplicationIdentity,LocalSystem,NetworkService等)的帐户的上下文中,我是否有权访问物理DLL文件和注册表项?


有用的链接

  • @ pho3nix从未得知此编辑,但已将其回滚,因为它100%错误并完全改变了答案的解释方式。在64位操作系统上,默认系统文件夹`%systemroot%\ System32`中存在64位版本的程序*(我知道它说的是32,但这是Microsoft不想破坏现有的东西,而imo毫无意义)*,而32位程序存储在%systemroot%\ SysWOW64文件夹中,而不是相反的方式。注册表也是如此,因此请回滚您的更改。 (2认同)