Как использовать DTS.Events.FireInformation() в задаче сценария SSIS при обработке WinSCPnet.dll FileTransferProgress?

У меня есть задача сценария в пакете SSIS (2008), которая загружает файлы с удаленного FTP-сервера в локальный каталог. Задача сценария написана на C# 2008 и использует WinSCPnet.dll. Используя примеры из документации WinSCP, я придумал приведенный ниже сценарий. Сценарий загружает файлы правильно, но все сообщения об успешном/неудачном выполнении файла сохраняются до тех пор, пока весь сценарий не завершится, а затем все сообщения сбрасываются одновременно. Прогресс файла вообще не отображается с использованием Console.Write(), и попытка использовать Dts.Events.FireInformation() в SessionFileTransferProgress дает мне

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;
    }
}

person digital.aaron    schedule 08.08.2018    source источник


Ответы (1)


Ответ, который я понял, был довольно прост. Я изменил SessionFileTransferProgress с private 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;
}
person digital.aaron    schedule 08.08.2018