ssis - 从 SSIS 运行 Winscp 执行进程任务
问题描述
我正在尝试在 SSIS 中实现解决方案,其中我们必须使用 Winzip 从 SFTP 下载文件。SFTP 中的文件名类似于ABC_CNT_03_06_2019_02-05_AM.csv
. 要求是下载当前日期文件。在这种情况下,我们必须忽略文件名中的时间部分。
目前,我正在尝试实施以下解决方案:
- 在 ssis 中创建了一个变量 (User::Filename) 来创建文件名
ABC_CNT_03_06_2018*.csv
- 在执行过程任务中:已
C:\Program Files (x86)\WinSCP\WinSCP.com
在可执行文件中选择 - 论据:
/script="F:\Upload.txt /parameter " + User::Filename
- upload.txt 有以下文字
option batch on option confirm off open username: password@sftp2.ftpname.com get /%1% F:\downloadfolder close exit
试图运行包,但它不工作。你能进一步建议吗?
解决方案
对于这样的事情,我建议使用带有WinSCP .NET 程序集的脚本任务,这将允许您使用 C# 功能在传输之前验证文件上的日期。下面是这个过程的一个例子。由于您将文件名的开头(包括日期)存储在变量中,因此该String.StartsWith
方法用于Name
属性,因为这仅返回文件名而没有文件夹路径。该String.EndsWith
方法还用于仅匹配您帖子中提到的 CSV 文件。保存文件名的 SSIS 变量将需要添加到ReadOnlyVariables
脚本任务的字段中,以及保存文件夹路径的变量(如果这是您存储这些文件的方式)。如果您遇到与加载 WinSCP 程序集有关的错误,则ResolveEventHandler
委托可用于解决此问题,如下所示。下载 WinSCP dll 的位置将是发送到该LoadFile
方法的路径。虽然看起来您每天只需要一个文件,但如果一天会有多个文件,则会使用一个列表。
using System.Linq;
using WinSCP;
using System.Collections.Generic;
//load WinSCPnet.dll
static ScriptMain()
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
if (args.Name.ToUpper().Contains("WINSCPNET"))
{
string path = @"C:\WinSCP Download Path\";
return System.Reflection.Assembly.LoadFile(System.IO.Path.Combine(path, "WinSCPnet.dll"));
}
return null;
}
public void Main()
{
//get file name and local/remote paths from SSIS variables.
string fileDateName = Dts.Variables[“User::FileDateName”].Value.ToString();
string remotePath = Dts.Variables[“User::RemoteFilePath”].Value.ToString();
string localPath = Dts.Variables[“User::LocalFilePath”].Value.ToString();
SessionOptions sessOpt = new SessionOptions
{
Protocol = Protocol.Sftp,
HostName = "SFTPsite.com",
UserName = "user",
Password = "password",
SshHostKeyFingerprint = "Your SshHostKeyFingerprint"
};
using (Session session = new Session())
{
session.Open(sessOpt);
TransferOptions transferOptions = new TransferOptions();
transferOptions.TransferMode = TransferMode.Binary;
RemoteDirectoryInfo rdi = session.ListDirectory(remotePath);
//confirm beginning of file name and extension
List<string> fileList = rdi.Files.Where(file => (file.Name.StartsWith(fileDateName))
&& (file.FullName.EndsWith(".csv"))).Select(file => file.FullName).ToList();
foreach (string s in fileList)
{
//transfer files
session.GetFiles(s, localPath, false, transferOptions);
}
}
}
推荐阅读
- javascript - JavaScript - 使用 HTML5 FileReader 读取文件
- angular - Angular 2声明预期和未终止的正则表达式错误
- java - 如何将 stanford coreNLP 服务器部署到在线 Web 服务,例如 Heroku?
- php - 使用不同的 where 子句加入 2 个表
- javascript - VideoJS - 按下播放按钮后禁用自动全屏
- php - 如何在 html5 中给出选定的选项?
- typescript - 泛型方法装饰器类型
- git - 单个设备中的多个 git 用户
- python - 如何使 Python 中的字符串解析变得不那么笨拙?
- c# - WIX 图标无法正常工作