SSIS脚本任务无法找到对程序集的引用

时间:2016-06-07 14:04:49

标签: c# dll ssis npoi

我有一个SSIS包,它使用脚本任务用来自各种不同文件类型(包括excel)的数据填充数据表。

我正在使用NPOI从Excel读取数据,并将NPOI.dll文件放在与SSIS包相同的文件夹中,并将其作为脚本任务中的参考添加。对于NPOI,我是一个Noob,所以我现在只是在修修补补,但即便如此,我仍然在第一道障碍中摔倒了!

我的脚本包含以下代码(我从this SA answer复制):

using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;

HSSFWorkbook wb;
using (FileStream file = new FileStream(FilePath, FileMode.Open, FileAccess.Read))
{
    wb = new HSSFWorkbook(file);
}

但失败并显示以下错误消息:Could not load file or assembly 'NPOI, Version=2.1.1.0, Culture=neutral, PublicKeyToken=0df73ec7942b34e1' or one of its dependencies. The system cannot find the file specified

但是当我进入脚本任务时,引用就在那里并且没有错误。

enter image description here

如果我注释掉除了第一行之外的所有内容,我宣布HSSFWorkBook名为wb,它运行正常。

我是否错误地添加了引用,或者是否正在添加对SSIS脚本任务的引用非常困难?

一如既往,我们非常感谢任何帮助。

3 个答案:

答案 0 :(得分:9)

对于要在“脚本任务”中引用和执行的自定义程序集,您必须将它们添加到GAC。这是an article with workflow 替代方法 - 脚本任务代码中的provide your own AssemblyResolver

答案 1 :(得分:1)

这里是Ferdipux提到的自定义AssemblyResolver方法的示例。 给定的解决方案不适用于用户变量,因此您必须处理文档中的注释才能找到“非静态”方法。 此外,当您部署到SQL Server 2017实例并尝试从网络共享(System.NotSupportedException)读取程序集时,发布的解决方案将不再起作用。 因此,我用UnsafeLoadFrom(path)调用替换了LoadFile(path)作为解决方法。请仅将其用于您自己的或其他知名程序集,而不是从未知作者那里下载的程序集,因为这将是安全问题。

这是工作代码,引用的DLL是“ System.Web.Helpers.dll”,并且在用户变量“ LibPath”(VS 2015,SQL Server 2017)中配置了网络共享路径:

    public System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    string path = Variables.LibPath.ToString();

    if (args.Name.Contains("System.Web.Helpers"))
    {
        return System.Reflection.Assembly.UnsafeLoadFrom(System.IO.Path.Combine(path, "System.Web.Helpers.dll"));
    }

    return null;
}

/// <summary>
/// This method is called once, before rows begin to be processed in the data flow.
/// </summary>
public override void PreExecute()
{
    base.PreExecute();

    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}

...

答案 2 :(得分:-1)

static ScriptMain()
        {
            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
        }
        static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            //(string)Dts.Variables["User::CustomDLL"].Value;
            if (args.Name.Contains("HtmlAgilityPack"))
            {
                string path = @"C:\Temp\";
                return System.Reflection.Assembly.LoadFile(System.IO.Path.Combine(path, "HtmlAgilityPack.dll"));
                //return System.Reflection.Assembly.UnsafeLoadFrom(System.IO.Path.Combine(path, "HtmlAgilityPack.dll"));
            }
            return null;
        }