如何将 ILMerge 与 SQL Server 2005 CLR 程序集和 XmlSerializer 结合使用

发布于 2025-01-01 12:19:50 字数 2558 浏览 4 评论 0原文

我有四个程序集(加上 .NET 3.5 system.core),我将它们作为不安全的 CLR 程序集安装在 SQL Server 2005 数据库中。以正确的顺序安装程序集(基于它们的依赖关系)工作正常,并且我能够使用我需要的 CLR 函数。如果可能的话,我想在四个程序集上使用 ILMerge,这样我就可以只安装一个 DLL。无论如何,只有一个程序集是从 SQL 端直接引用的;其他的是依赖项。碰巧这四个程序集之一是使用 sgen 生成的 XmlSerializer 程序集,这是必需的,因为 SQL Server CLR 不允许在运行时创建序列化程序。

在下面的讨论中,这些程序集被称为:

  1. ClrIntegration.dll(这是 Visual Studio 2008 中的 CLR 库,并且是 SQL 实际引用的唯一库)
  2. CalcLibrary.dll (这只是 ClrIntegration.dll 使用的 .NET 3.5 库)
  3. CalcLibrary.Schema.dll (这是一个 .NET 3.5 库,其代码完全由在两个 .xsd 文件上运行 xsd.exe - CalcLibrary.dll 使用此库)
  4. CalcLibrary.Schema.XmlSerializers.dll(这是通过在 CalcLibrary.Schema 上运行 sgen 生成的,并由 XmlSerializer 自动使用在 CalcLibrary.dll 中)

据我所知,不可能引用我的 CalcLibrary.dll 中的版本VS2008解决方案直接来自ClrIntegration项目。相反,我必须在正在运行的 SQL Server 2005 实例上安装 CalcLibrary.dll,并将其添加为 ClrIntegration 项目的数据库引用。这很麻烦,但到目前为止我已经成功了。

我在 ClrIntegration 项目中用作构建后事件的基本命令行是:

"c:\Program Files (x86)\Microsoft\ILMerge\ILMerge.exe" /targetplatform:v2 /out:ClrMergedAssembly.dll \
"$(TargetDir)ClrIntegration.dll" \
"$(SolutionDir)Source\CalcLibrary\$(OutDir)CalcLibrary.dll" \
"$(SolutionDir)Source\CalcLibrary.Schema\$(OutDir)CalcLibrary.Schema.dll" \
"$(SolutionDir)Source\CalcLibrary.Schema\$(OutDir)CalcLibrary.Schema.XmlSerializers.dll"

我在这里遇到了一些问题。

  1. 如果我只是如上所示运行 ILMerge,它就会起作用,并且我会得到 ClrMergedAssembly.dll。我可以在 SQL Server 2005 上安装 ClrMergedAssembly.dll,但是当我尝试使用它时,任何使用 XmlSerializer 的内容都会出现如下错误:

    <块引用>

    执行用户定义例程或聚合“Whatever”期间发生 .NET Framework 错误:
    System.InvalidOperationException:无法加载动态生成的序列化程序集。在某些托管环境中程序集加载功能受到限制,请考虑使用预生成的序列化程序。

    这与我根本不生成 XmlSerializer 时遇到的错误相同。我发现这篇优秀的博客文章指出 sgen需要在 ILMerge 后再次运行,但这样做会产生两个问题。首先,我确实需要 sgen 在 CalcLibrary.Schema.dll 上运行。在整个程序集上运行它会严重失败;事实上,这就是 CalcLibrary.Schema 首先与 CalcLibrary 分开的原因。其次,将序列化程序分开在某种程度上完全违背了使用 ILMerge 的目的:我只想部署一个 DLL。这里有任何解决方案吗?

  2. ILMerge 安装附带的 ILMerge.doc 文件似乎表明添加 /union 和/或 /lined 可能会解决一些问题。但是,单独使用 /union 或将 /union/close 一起使用会导致 ILMerge 失败并出现以下错误:

    <块引用>

    合并时发生异常:
    不允许未解析的程序集引用:CalcLibrary。

    错误后出现堆栈跟踪。我怀疑,由于 ClrIntegration 必须引用 CalcLibrary 的数据库版本而不是 VS2008 解决方案的版本,因此 ILMerge 无法找到该类型,因此无法完成联合,即使 CalcLibrary.dll 是同一个库。我的怀疑正确吗?有什么办法解决这个问题吗?

I have four assemblies (plus the .NET 3.5 system.core) that I am installing as unsafe CLR assemblies in a SQL Server 2005 database. Installing the assemblies in the correct order (based on their dependencies) works fine, and I am able to use the CLR functions I need. If possible, I would like to use ILMerge on the four assemblies so that I can install just one DLL. Only one assembly is directly referenced from the SQL side anyway; the others are dependencies. It happens that one of those four assemblies is an XmlSerializer assembly generated with sgen, which is required because the SQL Server CLR will not allow the serializer to be created at runtime.

In the following discussion, the assemblies are called:

  1. ClrIntegration.dll (this is a CLR library in Visual Studio 2008 and is the only library actually referenced from SQL)
  2. CalcLibrary.dll (this is just a .NET 3.5 library that ClrIntegration.dll uses)
  3. CalcLibrary.Schema.dll (this is a .NET 3.5 library whose code is generated entirely by running xsd.exe on two .xsd files -- CalcLibrary.dll uses this library)
  4. CalcLibrary.Schema.XmlSerializers.dll (this is generated by running sgen on CalcLibrary.Schema and is used automatically by an XmlSerializer in CalcLibrary.dll)

To my knowledge, it is not possible to reference the version of CalcLibrary.dll that is in my VS2008 solution directly from the ClrIntegration project. Instead, I have to install CalcLibrary.dll on a running SQL Server 2005 instance and add it as a database reference to the ClrIntegration project. This is a nuisance, but I've made it work so far.

The basic command line I am using as a post-build event in the ClrIntegration project is:

"c:\Program Files (x86)\Microsoft\ILMerge\ILMerge.exe" /targetplatform:v2 /out:ClrMergedAssembly.dll \
"$(TargetDir)ClrIntegration.dll" \
"$(SolutionDir)Source\CalcLibrary\$(OutDir)CalcLibrary.dll" \
"$(SolutionDir)Source\CalcLibrary.Schema\$(OutDir)CalcLibrary.Schema.dll" \
"$(SolutionDir)Source\CalcLibrary.Schema\$(OutDir)CalcLibrary.Schema.XmlSerializers.dll"

I'm running into a few problems here.

  1. If I just run ILMerge as shown above, it works, and I get ClrMergedAssembly.dll. I can install ClrMergedAssembly.dll on SQL Server 2005, but when I try to use it, anything that uses XmlSerializer gives me an error like:

    A .NET Framework error occurred during execution of user-defined routine or aggregate "Whatever":
    System.InvalidOperationException: Cannot load dynamically generated serialization assembly. In some hosting environments assembly load functionality is restricted, consider using pre-generated serializer.

    This is the same error I get when not generating the XmlSerializer at all. I found this excellent blog entry stating that sgen needs to be run again after ILMerge, but doing so creates two problems. First, I really need sgen to be run only on CalcLibrary.Schema.dll. Running it on the whole assembly will fail badly; in fact, that is why CalcLibrary.Schema is separate from CalcLibrary in the first place. Second, having the serializer be separate somewhat defeats the purpose of using ILMerge at all: I want just one DLL to deploy. Are there any solutions here?

  2. The ILMerge.doc file that comes with the ILMerge installation seems to suggest that adding /union and/or /closed might solve some problems. But, using either /union alone or /union along with /closed causes ILMerge to fail with the following error:

    An exception occurred during merging:
    Unresolved assembly reference not allowed: CalcLibrary.

    A stack trace follows the error. My suspicion is that, because ClrIntegration must reference the database version of CalcLibrary rather than the VS2008 solution's version, ILMerge cannot find the type and, therefore, cannot complete the union even though CalcLibrary.dll is the same library. Is my suspicion correct? Is there any way around this issue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

病女 2025-01-08 12:19:50

你不能。框架代码始终在不同的程序集中查找 sgen 生成的类(以 .XmlSerializers 后缀命名的程序集),并且它在框架中进行硬编码。检查您选择的反编译工具。

You can't. The framework code always looks for the sgen generated classes in a different assembly - the one named with .XmlSerializers suffix - and it is hardcoded in the framework. Check with your decompilation tool of choice.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文