2008-12-11 53 views
2

我有一个执行多个任务的SSIS包。我在OnExecStatusChanged事件的包级别手动添加了Business Intelligence Studio 2005内的事件处理程序。如何从C#中加载的SSIS包中捕获事件?

我的问题是,我怎么能在C#中为这个事件添加一个处理程序?我已经装包为指出here,我也创造了从Microsoft.SqlServer.Dts.Runtime.DefaultEvents继承自定义类,这是我的“监听器”:

Microsoft.SqlServer.Dts.Runtime.SqlPackageEventListener sqlListener = new SqlPackageEventListener(); 
    Microsoft.SqlServer.Dts.Runtime.Application sqlPackageLoader = new Application(); 
    Microsoft.SqlServer.Dts.Runtime.Package sqlPackage = sqlPackageLoader.LoadPackage(@"path\MigrateData.dtsx", sqlListener); 
    sqlPackage.Execute(null, null, sqlListener, null, null); 

如果我检查sqlPackage.EventHandlers.Count财产我在Business Intelligence Studio中添加了处理程序的正确编号。

有没有办法在C#中处理这些事件?

谢谢。

回答

4

嗯,我没有发现任何东西,所以我想出了一个解决办法,所以我会以我的自动回应:由于没有办法直接赶上SSIS包使然后我实现了事件

public class SqlPackageEventListener : DefaultEvents 
{ 
    public SqlPackageChangedHandler OnPackageError; 

    public override bool OnError(DtsObject source, int errorCode, string subComponent, string description, string helpFile, int helpContext, string idofInterfaceWithError) { 
     OnPackageError(this, new PackageErrorEventArgs(source, subComponent, description)); 
     return base.OnError(source, errorCode, subComponent, description, helpFile, helpContext, idofInterfaceWithError); 
    } 

    public delegate void SqlPackageChangedHandler(
     object sqlPackage, 
     EventArgs packageInfo 
     ); 
} 

public class PackageErrorEventArgs : EventArgs 
{ 
    private DtsObject source; 
    public DtsObject Source { 
     get { return source; } 
     set { source = value; } 
    } 

    private string subcomponent; 
    public string Subcomponent { 
     get { return subcomponent; } 
     set { subcomponent = value; } 
    } 

    private string description; 
    public string Description { 
     get { return description; } 
     set { description = value; } 
    } 

    public PackageErrorEventArgs(DtsObject source, string subcomponent, string description) { 
     this.description = description; 
     this.source = source; 
     this.subcomponent = subcomponent; 
    } 
} 

public class Test 
{ 
    SqlPackageEventListener sqlListener = new SqlPackageEventListener(); 
    sqlListener.OnPackageError += new SqlPackageEventListener.SqlPackageChangedHandler(sqlListener_OnPackageError); 
    Microsoft.SqlServer.Dts.Runtime.Application sqlPackageLoader = new Microsoft.SqlServer.Dts.Runtime.Application(); 
    Microsoft.SqlServer.Dts.Runtime.Package sqlPackage = Microsoft.SqlServer.Dts.Runtime.sqlPackageLoader.LoadPackage(@"path_to\file.dtsx", sqlListener); 
    sqlPackage.Execute(null, null, sqlListener, null, null) 

    public void sqlListener_OnPackageError(object sender, EventArgs args) { 
     //code to handle the event 
    } 
} 

所以“绝招”就是一个委托添加到您传递给包对象的LoadPackage方法你的“监听器”对象,这样一来,我们就可以访问“的OnError:在我的listener自己的事件“在监听器内部覆盖并提出事件。正如你所看到的,我实现了自己的EventArguments类,因此我们可以将重要数据传递给我们的处理程序代码,并查看运行的包或从DefaultEvents继承时覆盖方法时可以获得的任何其他信息。

当然,我在这里只实现了OnError,你可以实现任何你喜欢的,受SQL Server支持并且可以被覆盖的处理程序,因为这是我们提出事件的范围。

这样我就可以创建我的SqlPackageEventListener对象,并使用sqlListener_OnPackageError方法处理它的“OnPackageError”事件,并在SSIS包的执行引起任何错误时执行我所需的任何操作。

+0

我不知道NLog发生了什么事,因为当我将所有数据记录到不同的位置时。基本上它没有从主线程获取动态上下文集。 – Gandarez 2016-01-21 11:58:43