从MSI自定义操作中读取文件数据以进行远程CLR安装

时间:2015-11-16 15:29:49

标签: sql-server windows-installer installshield sqlclr

我们需要能够在MSI安装期间将程序集安装到远程SQL Server数据库。为了做到这一点,我们有一个带有替换标记的SQL脚本,其中汇编数据(用0x前缀编码的十六进制)应该去。现在我需要弄清楚如何使自定义操作从MSI文件中读取程序集的二进制文件数据,并将十六进制内容放入InstallShield" SQL Scripts" action可以替换为SQL脚本。

我遇到了需要从MSI文件中读取二进制文件数据的问题。我可以等到延迟上下文在文件系统安装后从文件系统中读取文件数据,但这似乎不是MSI"想要的方式"在延迟的行动环境中如何使得访问物业变得如此困难。我甚至不确定我是否仍然可以在那时修改SQL脚本 - 这可能为时已晚。我认为"对"这样做的方法是在延迟操作阶段开始之前确定已经执行的SQL脚本。

我正在寻找一个比我的备份计划更好的解决方案,让构建过程在构建时替换SQL脚本中的内容(因为这意味着我们实际上提供了两个文件副本,一个用于参考/维护用途,另一个包含在SQL脚本中)。

那么如何读取MSI将从自定义操作安装的文件的二进制内容,或者是否有更好的方法将CLR的程序集安装到远程SQL服务器?

2 个答案:

答案 0 :(得分:2)

我建议你做你想做的事情;-),那就是让构建过程创建一个带有CREATE ASSEMBLY [name] FROM 0x....的SQL脚本。

  

我正在寻找比我的备份计划更好的解决方案,让构建过程在构建时替换SQL脚本中的内容(因为这意味着我们实际上提供了两个文件副本,一个用于参考/维护目的,另一个包含在SQL脚本中。)

我不同意这里的结论。您只需要包含FROM 0x....的脚本。您不需要保留一个引用DLL路径的引脚。即使在MSI安装程序场景之外,这也不是非常便携。从SDLC(“软件开发生命周期”对于那些想知道这个缩写词的人)的角度来看,最好有一个自包含的发布脚本:在文件系统的某个地方没有外部依赖DLL。从“参考”的角度来看,将DLL放在可能使用ILSpy或Red Gate的.NET Reflector查看其代码之外没有多大好处,这只是为了验证“已发货”的内容因为你有实际的源代码。

我唯一厌烦DLL的是演示,演示和文章。在将某些东西集成到构建过程中时,我只是将DLL读入一串十六进制代码,在每个第N个字符处用一个反斜杠(\)作为该行的最后一个字符,因为这是T-SQL行继续符。这方面的一个例子是Pastebin.com上的以下SQL脚本:

SQLCLR Meta-data function for cross-database IndexName()

该脚本安装程序集并创建一个Function作为我在此DBA.StackExchange答案中发布的代码的工作示例:

Central stored procedure to execute in calling database context

答案 1 :(得分:1)

我想我在这个主题上有一篇博客文章。

我已经编写了许多具有数据库要求的安装程序,我几乎得出结论,不尝试针对远程数据库执行脚本。有太多可能出错的事情以及MSI对安装"的理解。当它是另一台或多台机器时,它就会失去同步。

有些时候我决定将数据库功能分解为自己的MSI并直接在数据层服务器上运行。现在,应用程序层只获取连接字符串,验证兼容性并配置应用程序以使用它。

只是一个想法。