首页 > 解决方案 > 从 SSIS 运行 Winscp 执行进程任务

问题描述

我正在尝试在 SSIS 中实现解决方案,其中我们必须使用 Winzip 从 SFTP 下载文件。SFTP 中的文件名类似于ABC_CNT_03_06_2019_02-05_AM.csv. 要求是下载当前日期文件。在这种情况下,我们必须忽略文件名中的时间部分。

目前,我正在尝试实施以下解决方案:

  1. 在 ssis 中创建了一个变量 (User::Filename) 来创建文件名ABC_CNT_03_06_2018*.csv
  2. 在执行过程任务中:已C:\Program Files (x86)\WinSCP\WinSCP.com在可执行文件中选择
  3. 论据:/script="F:\Upload.txt /parameter " + User::Filename
  4. upload.txt 有以下文字 option batch on option confirm off open username: password@sftp2.ftpname.com get /%1% F:\downloadfolder close exit

试图运行包,但它不工作。你能进一步建议吗?

标签: ssissftpwinscp

解决方案


对于这样的事情,我建议使用带有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);
   }

 }

}

推荐阅读