SSIS 脚本任务找不到对程序集的引用
SSIS Script Task cant find reference to assembly
我有一个 SSIS 包,它使用脚本任务用来自各种不同文件类型的数据填充数据表,包括 excel。
我正在使用 NPOI 从 Excel 中读取数据,并将 NPOI.dll 文件放在与 SSIS 包相同的文件夹中,并将其作为参考添加到脚本任务中。说到NPOI,我是菜鸟,所以我现在只是在修修补补,但即便如此,我还是在第一关就倒下了!
我的脚本包含以下代码(我从 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
但是当我进入脚本任务时,引用在那里并且没有错误。
如果我注释掉除第一行之外的所有内容,我声明一个名为 wb
的 HSSFWorkBook
它运行正常。
我是否错误地添加了引用,或者添加对 SSIS 脚本任务的引用非常困难?
一如既往,我们非常感谢您的帮助。
要在脚本任务中引用和执行自定义程序集,您必须将它们添加到 GAC。这里是 an article with workflow.
替代方法 - provide your own AssemblyResolver in Script task code.
这是 Ferdipux 提到的自定义 AssemblyResolver 方法的示例。
给定的解决方案不适用于用户变量,因此您必须处理文档中的注释才能找到“非静态”方法。
此外,当您部署到 SQL Server 2017 实例并尝试从网络共享 (System.NotSupportedException) 读取程序集时,发布的解决方案将不再有效。
因此,我将 LoadFile(path) 替换为 UnsafeLoadFrom(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);
}
...
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;
}
我有一个 SSIS 包,它使用脚本任务用来自各种不同文件类型的数据填充数据表,包括 excel。
我正在使用 NPOI 从 Excel 中读取数据,并将 NPOI.dll 文件放在与 SSIS 包相同的文件夹中,并将其作为参考添加到脚本任务中。说到NPOI,我是菜鸟,所以我现在只是在修修补补,但即便如此,我还是在第一关就倒下了!
我的脚本包含以下代码(我从 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
但是当我进入脚本任务时,引用在那里并且没有错误。
如果我注释掉除第一行之外的所有内容,我声明一个名为 wb
的 HSSFWorkBook
它运行正常。
我是否错误地添加了引用,或者添加对 SSIS 脚本任务的引用非常困难?
一如既往,我们非常感谢您的帮助。
要在脚本任务中引用和执行自定义程序集,您必须将它们添加到 GAC。这里是 an article with workflow.
替代方法 - provide your own AssemblyResolver in Script task code.
这是 Ferdipux 提到的自定义 AssemblyResolver 方法的示例。 给定的解决方案不适用于用户变量,因此您必须处理文档中的注释才能找到“非静态”方法。 此外,当您部署到 SQL Server 2017 实例并尝试从网络共享 (System.NotSupportedException) 读取程序集时,发布的解决方案将不再有效。 因此,我将 LoadFile(path) 替换为 UnsafeLoadFrom(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);
}
...
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;
}