SSIS 脚本任务以编程方式引用 dll
SSIS Script Task reference dll programmatically
我已经构建了能够自动导出 DTSX 包的软件。除了其他对象之外,这个包还有一个 ScriptTask (C#)。都编译好了,运行就好了。
现在的新要求是在该 ScriptTask 中调用 class,它存在于我们构建的外部 DLL 中,因此其他应用程序可以使用相同的代码。我们做足了功课,在安装软件的过程中成功将这个DLL包含到GAC中。
问题是脚本中仍然无法识别“使用我们的库”。
经过一些搜索,我们发现,我们还需要在 References 文件夹中引用此 DLL。我们当然可以通过 DataTools / VisualStudio UI.
问题是我们需要以编程方式执行此操作:
我们有这段生成项目的代码
task.ScriptingEngine.VstaHelper.LoadNewProject(task.ProjectTemplatePath, null, "MyScriptProject");
此外,我们还有这段代码可以创建 MainScript
task.ScriptingEngine.VstaHelper.AddFileToProject(ScriptName + ".cs", MainScript.ToString());
我不知道如何以编程方式包含引用 DLL。
更新答案
您可以通过替换 DTSX 文件中的适当 XML 节点以编程方式更新脚本任务
节点路径取决于脚本任务在 SSIS 包中的创建位置,在我的例子中节点路径是
/DTS:Executable/DTS:Executables/DTS:Executable/DTS:ObjectData/pipeline/components/component[@refId="Package\Data Flow Task\Script Component"]/properties
您要查找的@refId 将以包\数据流名称\组件名称开头
此节点将包含子节点,其中包含 C# 脚本以及基于此脚本构建的二进制文件
属性 名称“SourceCode”包含名为 arrayElements 的数组中的 C# scipts,该数组将为每个文件包含三个子节点,这些子节点称为 arrayElement,第一个值是相对路径和名称,二是文件编码三是文件内容
属性 名称“BinaryCode”包含从脚本构建的 .dll,它还包含一个包含两个条目的 arrayElement 数组,第一个是 dll 名称,第二个是 base64 编码的 dll 二进制文件
要获取填充这些项目的数据,您需要创建 C# 构建目录的模板、应用您的更改、构建代码并获取生成的文件并将它们替换到相应的节点上
要创建模板,请通过 SSIS 任务打开脚本,
- 在解决方案资源管理器中单击项目并转到文件保存 VstaProject.sln
- 转到保存的文件夹,从解决方案属性对话框中获取该文件夹
- 将此文件夹复制到某处,以便您可以重新使用它来构建您的自定义内容
- 修改模板目录中的 .cs 文件并将自定义引用 dll 添加到 .csproj 文件
- 在你的.csproj目录下调用MSBUILD输出dll,重要的是你使用VS MSBUILD,VS2017你可以在
C:\Program Files (x86)\Microsoft Visual Studio17\Professional\MSBuild.0\Bin\msbuild.exe
- 获取这些文件并将它们打包到 DTSX 文件中的一个 XML 节点中
初始答案
Microsoft 提供了一种解决方法来加载不在 GAC 中的 DLL
Load assembly that isnt in the GAC
请参阅下面的 SSIS 脚本摘录,我从 nuget 安装目录加载了 JSON dll。此 DLL 不在 GAC
static ScriptMain()
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
if (args.Name.Contains("Newtonsoft.Json"))
{
string path = @"C:\Program Files\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\";
return System.Reflection.Assembly.LoadFile(System.IO.Path.Combine(path, "Newtonsoft.Json.dll"));
}
return null;
}
我已经构建了能够自动导出 DTSX 包的软件。除了其他对象之外,这个包还有一个 ScriptTask (C#)。都编译好了,运行就好了。
现在的新要求是在该 ScriptTask 中调用 class,它存在于我们构建的外部 DLL 中,因此其他应用程序可以使用相同的代码。我们做足了功课,在安装软件的过程中成功将这个DLL包含到GAC中。
问题是脚本中仍然无法识别“使用我们的库”。
经过一些搜索,我们发现,我们还需要在 References 文件夹中引用此 DLL。我们当然可以通过 DataTools / VisualStudio UI.
问题是我们需要以编程方式执行此操作:
我们有这段生成项目的代码
task.ScriptingEngine.VstaHelper.LoadNewProject(task.ProjectTemplatePath, null, "MyScriptProject");
此外,我们还有这段代码可以创建 MainScript
task.ScriptingEngine.VstaHelper.AddFileToProject(ScriptName + ".cs", MainScript.ToString());
我不知道如何以编程方式包含引用 DLL。
更新答案
您可以通过替换 DTSX 文件中的适当 XML 节点以编程方式更新脚本任务
节点路径取决于脚本任务在 SSIS 包中的创建位置,在我的例子中节点路径是
/DTS:Executable/DTS:Executables/DTS:Executable/DTS:ObjectData/pipeline/components/component[@refId="Package\Data Flow Task\Script Component"]/properties
您要查找的@refId 将以包\数据流名称\组件名称开头
此节点将包含子节点,其中包含 C# 脚本以及基于此脚本构建的二进制文件
属性 名称“SourceCode”包含名为 arrayElements 的数组中的 C# scipts,该数组将为每个文件包含三个子节点,这些子节点称为 arrayElement,第一个值是相对路径和名称,二是文件编码三是文件内容
属性 名称“BinaryCode”包含从脚本构建的 .dll,它还包含一个包含两个条目的 arrayElement 数组,第一个是 dll 名称,第二个是 base64 编码的 dll 二进制文件
要获取填充这些项目的数据,您需要创建 C# 构建目录的模板、应用您的更改、构建代码并获取生成的文件并将它们替换到相应的节点上
要创建模板,请通过 SSIS 任务打开脚本,
- 在解决方案资源管理器中单击项目并转到文件保存 VstaProject.sln
- 转到保存的文件夹,从解决方案属性对话框中获取该文件夹
- 将此文件夹复制到某处,以便您可以重新使用它来构建您的自定义内容
- 修改模板目录中的 .cs 文件并将自定义引用 dll 添加到 .csproj 文件
- 在你的.csproj目录下调用MSBUILD输出dll,重要的是你使用VS MSBUILD,VS2017你可以在
C:\Program Files (x86)\Microsoft Visual Studio17\Professional\MSBuild.0\Bin\msbuild.exe
- 获取这些文件并将它们打包到 DTSX 文件中的一个 XML 节点中
初始答案
Microsoft 提供了一种解决方法来加载不在 GAC 中的 DLL
Load assembly that isnt in the GAC
请参阅下面的 SSIS 脚本摘录,我从 nuget 安装目录加载了 JSON dll。此 DLL 不在 GAC
static ScriptMain()
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
if (args.Name.Contains("Newtonsoft.Json"))
{
string path = @"C:\Program Files\Microsoft SDKs\Azure\.NET SDK\v2.9\bin\plugins\Diagnostics\";
return System.Reflection.Assembly.LoadFile(System.IO.Path.Combine(path, "Newtonsoft.Json.dll"));
}
return null;
}