sp_OACreate返回(0x‭80131051‬)SQL 2016 x64,以x64为目标的程序集

我知道关于32/64位冲突的问题有很多答案,但是在这种情况下,所有内容都可以在64位进程中运行。

我正在帮助客户从SQL Server 2008 R2 x64升级到SQL Server 2016 x64上的新实例。 客户有一些旧过程(数百个),这些过程使用sp_OACreate / Method / Destroy序列来使我们的产品的COM接口使用C#编码并暴露给COM和目标x64。使用x64版本的RegAsm注册,并具有强大的名称并将其加载到GAC中。

在我的环境中,我具有SQL 2008 R2 runnign,并且所有这些均按预期工作。我安装了SQL 2016并重现了该问题。

(我知道最好使用不同的方法,但是由于这种方法在很多地方都可以使用,因此不易更改。)

我还测试了在VB脚本中创建对象的过程,这可以按预期工作。能够在64位进程中运行VBScript并调用CreateObject

EXEC @hr = sp_OACreate 'Satori64.CASSTask',@TaskObject OUT,4
EXEC sp_OAGetErrorInfo @TaskObject,@ErrorSource out,@ErrorDescription out
ErrorSource = "ODSOLE Extended Procedure"
ErrorDescription = "Class not registered"
hr = "-2147221164" (‭80040154‬)

EXEC @hr = sp_OACreate 'Satori64.CASSTask',1
EXEC sp_OAGetErrorInfo @TaskObject,@ErrorDescription out
ErrorSource = "ODSOLE Extended Procedure"
ErrorDescription = ""
hr = "-2146234287" (‭80131051‬)

在进行了更多研究并查看了procmon日志之后,我发现SQL Server查找COM对象的方式与vbscript查找并加载它的方式大不相同。

由于有一些评论,我更深入地介绍了procmon日志,以查看可能发生的情况。在SQL 2008 R2和2016之间,文件和注册表访问类似。 2008日志显示装配了装配体,并找到并创建了预期的对象。 2016日志显示它能够找到程序集,但随后立即意外失败。尽管这样做有帮助,但它没有回答出什么问题了。

因此,我更加深入地研究了是否可以找到为什么未加载程序集的原因。

我添加了:

[HKEY_LOCAL_MACHINE\SOFTWARE\microsoft\Fusion]
"LogFailures"=dword:00000001
"ForceLog"=dword:00000001
"LogPath"="C:\\Temp\\Fusion\\"

并查看了两个版本的日志:

SQL R2 2008成功

*** Assembly Binder Log Entry  (11/18/2019 @ 10:06:54 PM) ***

The operation was successful.
Bind result: hr = 0x0. The operation completed successfully.

Assembly manager loaded from:  C:\Windows\microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable  C:\Program Files\microsoft SQL Server 2008\MSSQL10_50.MSSQL2008\MSSQL\Binn\sqlservr.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: DisplayName = Satori64,Version=4.7.1.1,Culture=neutral,PublicKeyToken=ac6bbd3b7853cfdf
 (Fully-specified)
LOG: Appbase = file:///C:/Program Files/microsoft SQL Server 2008/MSSQL10_50.MSSQL2008/MSSQL/Binn/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = sqlservr.exe
Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: Download of application configuration file was attempted from file:///C:/Program Files/microsoft SQL Server 2008/MSSQL10_50.MSSQL2008/MSSQL/Binn/sqlservr.exe.config.
LOG: Configuration file C:\Program Files\microsoft SQL Server 2008\MSSQL10_50.MSSQL2008\MSSQL\Binn\sqlservr.exe.config does not exist.
LOG: No application configuration file found.
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Post-policy reference: Satori64,PublicKeyToken=ac6bbd3b7853cfdf
LOG: Found assembly by looking in the GAC.
LOG: Binding succeeds. Returns assembly from C:\windows\microsoft.Net\assembly\GAC_64\Satori64\v4.0_4.7.1.1__ac6bbd3b7853cfdf\Satori64.dll.
LOG: Assembly is loaded in default load context.

SQL 2016失败

*** Assembly Binder Log Entry  (11/18/2019 @ 10:08:37 PM) ***

The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.

Assembly manager loaded from:  C:\Windows\microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable  C:\Program Files\microsoft SQL Server\MSSQL13.SQLSERVER\MSSQL\Binn\sqlservr.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: DisplayName = Satori64,PublicKeyToken=ac6bbd3b7853cfdf
 (Fully-specified)
LOG: Appbase = file:///C:/Program Files/microsoft SQL Server/MSSQL13.SQLSERVER/MSSQL/Binn/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = sqlservr.exe
Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Program Files\microsoft SQL Server\MSSQL13.SQLSERVER\MSSQL\Binn\sqlservr.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Post-policy reference: Satori64,PublicKeyToken=ac6bbd3b7853cfdf
LOG: Fusion is hosted. Check host about this assembly.
LOG: Assembly is not in CLR Loaded list. Asking host assembly store.
LOG: Try host assembly store with assembly satori64,version=4.7.1.1,culture=neutral,publickeytoken=ac6bbd3b7853cfdf,processorarchitecture=amd64.
LOG: Try host assembly store with assembly satori64,processorarchitecture=msil.
LOG: Try host assembly store with assembly satori64,publickeytoken=ac6bbd3b7853cfdf.
WRN: Host assembly store does not contain this assembly.
ERR: Unrecoverable error occurred during pre-download check (hr = 0x80070002).

在这里我有点茫然。 SQL可以加载程序集,但是由于某些原因,不能通过COM访问它。

我决定从头开始,创建一个具有绝对最小引用的新程序集,一个具有单个方法的类。 我强烈命名它,并在RegAsm(x64)中注册了它,并将其加载到GAC。

这显示了完全相同的结果。 sp_OACreate可以在2008 R2中正常运行。在2014年和2016年失败。

任何想法将不胜感激!

tian_tang123 回答:sp_OACreate返回(0x‭80131051‬)SQL 2016 x64,以x64为目标的程序集

暂时没有好的解决方案,如果你有好的解决方案,请发邮件至:iooj@foxmail.com
本文链接:https://www.f2er.com/3093648.html

大家都在问