Como é que eu uso DTS.Evento.FireInformation () na tarefa de Script SSIS enquanto lida com WinSCPnet.dll FileTransferProgress?

tenho uma tarefa de Script num pacote SSIS (2008) que transfere ficheiros de um servidor FTP remoto para uma pasta local. A tarefa de Script é escrita em C# 2008, e usa WinSCPnet.dll. Usando exemplos da documentação do WinSCP, eu cheguei com o script abaixo. O script funciona corretamente para baixar os arquivos, mas todas as mensagens de sucesso/falha do arquivo são mantidos até que todo o script completa, e então todas as mensagens são descartadas de uma vez. O progresso do ficheiro não aparece de todo com a utilização Console.Write(), e tentar usar Dts.Events.FireInformation() em SessionFileTransferProgress dá-me

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

Há alguma maneira de usar o DTS?evento.Fire * eventos para exibir informações de progresso de arquivo como acontece, e estado de completação de arquivo após cada arquivo?

Script:

/*
   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;
    }
}
Author: digital.aaron, 2018-08-08

1 answers

A resposta que descobri foi muito simples. Eu mudei SessionFileTransferProgress de private static void para private void. Uma vez que este método não era mais estático, eu era capaz de usar this para invocar os métodos Dts.Events.Fire*. SessionFileTransferProgress foi alterado para:
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;
}
 1
Author: digital.aaron, 2018-08-08 19:28:22