如何在处理 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;
}
}
我想出的答案很简单。我将 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;
}
我在 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;
}
}
我想出的答案很简单。我将 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;
}