SQL Server 自定义 CLR 失败,并显示错误“无法加载文件或程序集或其依赖项之一。系统找不到指定的文件。”

问题描述 投票:0回答:1

我创建了一个引用 Windows DLL、WindowsBase 的 SQL CLR。在大多数情况下,我的 CLR 工作得很好,但如果 WindowsBase 在 GAC 中更新,那么我会收到错误:

主机存储中的程序集与 GAC 中的程序集具有不同的签名。

为了解决这个问题,我构建了 CLR 以引用 GAC 中未包含的 WindowsBase 版本。现在,当我运行 CLR 时,出现错误

无法加载文件或程序集“WindowsBase,版本=4.0.0.0,...”或其依赖项之一。系统找不到指定的文件。

我设置了 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 副本而不会出现上述错误的建议将不胜感激。

~虫子~

.net sql-server sql-server-2012 sqlclr
1个回答
1
投票

SQL Server 的 CLR 主机不支持您尝试执行的操作。 SQL Server 中的 CLR 受到严格限制,以防止 SQL Server 不稳定,因为它的工作方式与操作系统上运行的应用程序不同。因此,受支持的 DLL 集非常有限(即经过验证可以工作并保证在 .NET 更新期间保持工作状态)。 WindowsBase 不是其中之一,因此您需要将其作为

UNSAFE
手动加载到 SQL Server 中。但这会让您遇到主 GAC 更改中的版本问题(GAC 和 SQL Server 的 CLR 主机之间通用的 DLL 必须是相同版本),或者更糟糕的是,如果 DLL 变得“混合” (非托管 C++ 和托管代码)并且不再是“纯粹的”。在这种情况下,新版本将无法加载,并且旧版本会出现“版本错误”错误,因此您需要做一些工作。

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

这组链接摘自我撰写的一篇文章的“补充阅读”部分:SQLCLR 5 级的阶梯:开发(在 SQL Server 中使用 .NET)


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

© www.soinside.com 2019 - 2024. All rights reserved.