SQL 服务器自定义 CLR 失败并出现错误 "Could not load file or assembly or one of its dependencies. The system cannot find the file specified."

SQL Server custom CLR fails with error "Could not load file or assembly or one of its dependencies. The system cannot find the file specified."

我创建了一个 SQL CLR,它引用 Windows DLL,WindowsBase。在大多数情况下,我的 CLR 工作正常,但如果 WindowsBase 在 GAC 中得到更新,那么我会收到错误“Assembly in host store has a different signature than assembly in GAC.”。

为了解决这个问题,我构建了我的 CLR 以引用不在 GAC 中的 WindowsBase 版本。现在当我 运行 我的 CLR 我得到错误“Could not load file or assembly 'WindowsBase, Version=4.0.0.0, ...' or one of its dependencies. The system cannot find the file specified.

我设置了 FusLogVw 以查看发生了什么并获得以下输出

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\MSSQL11.MSSQLSERVER\MSSQL\Binn\sqlservr.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
    LOG: DisplayName = WindowsBase, Version=4.0.0.0
    LOG: Appbase = file:///C:/Program Files/Microsoft SQL Server/MSSQL11.MSSQLSERVER/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: 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: WindowsBase, Version=4.0.0.0
    LOG: The same bind was seen before, and was failed with hr = 0x80070002.
    ERR: Unrecoverable error occurred during pre-download check (hr = 0x80070002).

程序集加载程序似乎正在使用 machine.config 文件来确定应在何处查找程序集。基于这个假设,我将 machine.config 更新为

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly>
             <assemblyIdentity name="WindowsBase"... />
              <codBase version="4.0.0.0"
                   href="./AdditionalAssemblies/WindowsBase.dll"/>
        </dependentAssembly>
    </assemblyBinding>
</runtime>

我尝试过使用相对路径(相对于 SQlservr.exe)和绝对路径,但仍然出现上述相同的错误。任何有关如何设置 SQL CLR 以便它引用 GAC 外部的 WindowsBase 副本而不会出现上述错误的任何建议,我们将不胜感激。

~Bugz~

SQL 服务器的 CLR 主机不支持您尝试执行的操作。 SQL 服务器中的 CLR 受到高度限制,以防止破坏 SQL 服务器的稳定性,因为它的工作方式不同于 OS 上的应用程序 运行。因此,支持的 DLL 集非常有限(即经过验证可以工作并且保证 运行teed 可以在更新到 .NET 的过程中保持工作)。 WindowsBase 不是其中之一,因此您需要将其作为 UNSAFE 手动加载到 SQL 服务器中。但这给你留下了你 运行 进入主 GAC 版本更改的问题(GAC 和 SQL 服务器的 CLR 主机之间通用的 DLL 必须是相同的版本),或者更糟,如果 DLL 变得“混合”(非托管 C++ 和托管代码)并且不再是“纯”。在这种情况下,新版本将不会加载,旧版本会出现“错误版本”错误,因此您需要做一些工作。

更多详细信息,请参阅以下文章/文档:

那组链接摘自我写的一篇文章的“补充阅读”部分:Stairway to SQLCLR Level 5: Development (Using .NET within SQL Server)


有关使用 SQLCLR 的更多信息,请访问我的网站:SQLCLR Info