首页 > 解决方案 > 以编程方式 SSIS 脚本任务引用 dll

问题描述

我已经构建了能够自动导出 DTSX 包的软件。这个包在其他对象中也有一个 ScriptTask (C#)。所有都编译并运行得很好。

现在新的要求是调用该 ScriptTask 中的一个类,该类存在于我们构建的外部 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。

标签: dllssisexternalgacprogrammatically

解决方案


更新的答案

您可以通过替换 DTSX 文件中的相应 XML 节点以编程方式更新脚本任务

节点路径取决于在 SSIS 包中创建脚本任务的位置,在我的情况下,节点路径是

/DTS:Executable/DTS:Executables/DTS:Executable/DTS:ObjectData/pipeline/components/component[@refId="Package\Data Flow Task\Script Component"]/properties

您将要查找的 @refId 将以 Package \ Dataflow name \ Component name 开头

在此处输入图像描述

此节点将具有包含 C# 脚本以及基于此脚本构建的二进制文件的子节点

属性名称“SourceCode”包含一个名为 arrayElements 的数组中的 C# scipts,该数组将为每个文件具有三个子节点,这些子节点称为 arrayElement,第一个值是相对路径和名称,第二个是文件编码,第三个是文件内容

源代码节点

属性名称“BinaryCode”包含从脚本构建的 .dll,它还包含一个带有两个条目的 arrayElement 数组,第一个是 dll 名称,第二个是 base64 编码的 dll 二进制文件

二进制代码节点

要获取数据以填充这些项目,您需要创建 C# 构建目录的模板,应用您的更改,构建代码并获取生成的文件并在相应的节点上替换它们

要创建模板,请通过 SSIS 任务打开脚本,

  1. 单击解决方案资源管理器中的项目并转到文件保存 VstaProject.sln 保存SLN
  2. 转到保存的文件夹,从解决方案属性对话框中获取该文件夹 查找文件夹
  3. 将此文件夹复制到某处,以便您可以重复使用它来构建您的自定义内容
  4. 修改模板目录中的 .cs 文件并将自定义引用 dll 添加到 .csproj 文件中
  5. 调用 .csproj 所在目录下的 MSBUILD 输出 dll,使用 VS MSBUILD 很重要,VS2017 可以在

C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\msbuild.exe

  1. 将这些文件打包到 DTSX 文件中的 XML 节点中

初步答案

Microsoft 提供了一种解决方法来加载不在 GAC 中的 DLL

加载不在 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;
}

推荐阅读