如何在处理 WinSCPnet.dll FileTransferProgress 时在 SSIS 脚本任务中使用 DTS.Events.FireInformation()?

How do I use DTS.Events.FireInformation() in SSIS Script Task while handling WinSCPnet.dll FileTransferProgress?

我在 SSIS (2008) 包中有一个脚本任务,可将文件从远程 FTP 服务器下载到本地目录。脚本任务是用 C# 2008 编写的,并使用 WinSCPnet.dll。使用 WinSCP 文档中的示例,我想出了下面的脚本。该脚本可以正确下载文件,但所有文件 success/failure 消息都将被保留,直到整个脚本完成,然后所有消息都会被一次性转储。使用 Console.Write() 根本不显示文件进度,而尝试在 SessionFileTransferProgress 中使用 Dts.Events.FireInformation() 会得到

Error: "An object reference is required for the non-static field, method, or property Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase.Dts.get"

有没有一种方法可以使用 DTS.events.Fire* 事件来显示文件进度信息,以及每个文件完成后的文件完成状态?

脚本:

/*
   Microsoft SQL Server Integration Services Script Task
   Write scripts using Microsoft Visual C# 2008.
   The ScriptMain is the entry point class of the script.
*/

using System;
using Microsoft.SqlServer.Dts.Runtime;
using Microsoft.SqlServer.Dts.Tasks.ScriptTask;
using System.AddIn;
using WinSCP;

namespace ST_3a1cf75114b64e778bd035dd91edb5a1.csproj
{
    [AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
    public partial class ScriptMain : VSTARTScriptObjectModelBase
    {
        public void Main()
        {
            // Setup session options
            SessionOptions sessionOptions = new SessionOptions
            {
                Protocol = Protocol.Ftp,
                HostName = (string)Dts.Variables["User::FTPServerName"].Value,
                UserName = (string)Dts.Variables["User::UserName"].Value,
                Password = (string)Dts.Variables["User::Password"].Value
            };

            try
            {
                using (Session session = new Session())
                {
                    // Will continuously report progress of transfer
                    session.FileTransferProgress += SessionFileTransferProgress;

                    session.ExecutablePath = (string)Dts.Variables["User::PathToWinSCP"].Value;

                    // Connect
                    session.Open(sessionOptions);

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


                    TransferOperationResult transferResult = session.GetFiles(
                                                                                (string)Dts.Variables["User::ExportPath"].Value
                                                                                , (string)Dts.Variables["User::ImportPath"].Value
                                                                                , false
                                                                                , transferOptions
                                                                            );

                    // Throw on any error
                    transferResult.Check();

                    // Print results
                    bool fireAgain = false;
                    foreach (TransferEventArgs transfer in transferResult.Transfers)
                    {
                        Dts.Events.FireInformation(0, null,
                            string.Format("Download of {0} succeeded", transfer.FileName),
                            null, 0, ref fireAgain);
                    }
                }

                Dts.TaskResult = (int)DTSExecResult.Success;
            }

            catch (Exception e)
            {
                Dts.Events.FireError(0, null,
                    string.Format("Error downloading file: {0}", e),
                    null, 0);

                Dts.TaskResult = (int)DTSExecResult.Failure;
            }
        }

        private static void SessionFileTransferProgress(object sender, FileTransferProgressEventArgs e)
        {
            //bool fireAgain = false;


            // Print transfer progress
            Console.Write("\r{0} ({1:P0})", e.FileName, e.FileProgress);

            /*Dts.Events.FireInformation(0, null,
                            string.Format("\r{0} ({1:P0})", e.FileName, e.FileProgress),
                            null, 0, ref fireAgain);*/

            // Remember a name of the last file reported
            _lastFileName = e.FileName;
        }

        private static string _lastFileName;
    }
}

我想出的答案很简单。我将 SessionFileTransferProgressprivate static void 更改为 private void。一旦这个方法不再是静态的,我就可以使用 this 来调用 Dts.Events.Fire* 方法。 SessionFileTransferProgress 更改为:

private void SessionFileTransferProgress(object sender, FileTransferProgressEventArgs e)
{
    bool fireAgain = false;

    this.Dts.Events.FireInformation(0, null,
                    string.Format("\r{0} ({1:P0})", e.FileName, e.FileProgress),
                    null, 0, ref fireAgain);

    // Remember a name of the last file reported
    _lastFileName = e.FileName;
}