You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SSIS中基于WinSCP的Script Task连接SFTP失败求助

SSIS脚本任务中WinSCP操作异常排查与修复

问题描述

我用C#编写了SSIS脚本任务,逻辑是先判断远程SFTP服务器上的文件是否存在,再执行删除和拉取操作。单独运行这段C#代码功能正常,但移植到SSIS脚本任务后持续抛出异常导致任务失败。已添加WinSCPnet.dll引用并参考官方SSIS集成指南,仍无法定位问题,附上代码求助:

public void Main()
{
    string Log = Dts.Variables["User::MLog"].Value.ToString();
    string SFTPOne = Dts.Variables["User::SFTPFileOne"].Value.ToString();
    string SFTPTwo = Dts.Variables["User::SFTPFileTwo"].Value.ToString();
    string Src = Dts.Variables["User::SrcPath"].Value.ToString();

    SessionOptions sessionsOption = new SessionOptions
    {
        Protocol = Protocol.Sftp,
        HostName = Dts.Variables["User::SFTPHostName"].Value.ToString(),
        UserName = Dts.Variables["User::SFTPUsername"].Value.ToString(),
        Password = Dts.Variables["User::SFTPPassword"].Value.ToString(),
        PortNumber = 22,
        SshHostKeyFingerprint = Dts.Variables["User::SFTPSshHostKeyFingerprint"].Value.ToString(),
    };
    
    try
    {
        using (Session session = new Session())
        {
            session.SessionLogPath = Log;
            session.Open(sessionsOption);

            TransferOptions transferOptions = new TransferOptions();
            transferOptions.TransferMode = TransferMode.Binary;

            if (session.FileExists(SFTPOne))
            {
                RemovalOperationResult removalOperation;
                removalOperation = session.RemoveFiles(SFTPOne);
                TransferOperationResult transferResult;
                transferResult = session.GetFiles(SFTPTwo, Src, true, transferOptions);
            }
            else
            {
                MessageBox.Show("file doesn't exist");
            }
        }
    }
    catch (Exception e)
    {
        Dts.TaskResult = (int)DTSExecResult.Failure;
    }
    
    Dts.TaskResult = (int)ScriptResults.Success;
}

排查与修复步骤

1. 补全异常信息捕获(最关键)

原代码的catch块仅标记任务失败,未记录任何异常详情,且最后强制设置为Success,会掩盖真实错误。修改后:

catch (Exception e)
{
    bool fireAgain = true;
    string errorMsg = $"SFTP操作出错: {e.Message}\n堆栈信息: {e.StackTrace}";
    // 写入SSIS事件日志
    Dts.Events.FireError(0, "SFTP任务", errorMsg, string.Empty, 0);
    // 也可写入自定义日志文件
    System.IO.File.AppendAllText(Log, errorMsg + "\n");
    // 存入SSIS变量方便后续查看
    Dts.Variables["User::ErrorDetails"].Value = errorMsg;
    // 必须return,避免后续覆盖任务结果
    Dts.TaskResult = (int)DTSExecResult.Failure;
    return;
}

2. 修正任务结果逻辑

原代码无论是否触发异常,最后都会设置为Success,导致任务实际失败却显示成功。需确保异常分支直接返回失败结果,正常分支才设置成功。

3. 移除SSIS环境不支持的操作

MessageBox.Show在SSIS服务端运行时无法弹出,还可能导致任务挂起,替换为日志记录:

else
{
    string msg = $"远程文件不存在: {SFTPOne}";
    bool fireAgain = true;
    Dts.Events.FireInformation(0, "SFTP检查", msg, string.Empty, 0, ref fireAgain);
    System.IO.File.AppendAllText(Log, msg + "\n");
}

4. 验证运行环境与权限

  • 确保SSIS服务运行账户(SQL Server Integration Services服务的登录账户)对WinSCPnet.dll所在目录、**本地目标路径Src**有读写权限;
  • 确认WinSCPnet.dll对应的同版本WinSCP.exe文件放在SSIS服务可访问的路径(如脚本任务输出目录、SSIS服务工作目录),或已注册到GAC;
  • 检查所有SSIS变量的取值是否正确(如SshHostKeyFingerprint格式是否为ssh-rsa 2048 ...,SrcPath是否为合法本地路径)。

5. 添加变量值日志验证

在代码开头添加变量日志,确认所有参数取值符合预期:

// 写入变量信息到日志文件
var logContent = $"=== 变量信息 ===\n" +
                 $"日志路径: {Log}\n" +
                 "待检查文件: {SFTPOne}\n" +
                 "待拉取文件: {SFTPTwo}\n" +
                 "本地目标路径: {Src}\n" +
                 "SFTP主机: {Dts.Variables["User::SFTPHostName"].Value}\n" +
                 "SFTP用户名: {Dts.Variables["User::SFTPUsername"].Value}\n";
System.IO.File.AppendAllText(Log, logContent);

内容的提问来源于stack exchange,提问作者Junsh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 10:55:30