如何从加载c#的SSIS包捕获事件?

时间:2021-11-20 00:08:16

I have an SSIS package that executes several tasks. I manually added an event handler inside Business Intelligence Studio 2005 at the package level for the OnExecStatusChanged event.

我有一个SSIS包,它执行几个任务。我在OnExecStatusChanged事件的包级别上,在Business Intelligence Studio 2005中手动添加了一个事件处理程序。

My question is, how can I add a handler for this event inside C#? I have loaded the package as pointed here and I also created a custom class inherited from Microsoft.SqlServer.Dts.Runtime.DefaultEvents which is my "Listener":

我的问题是,如何在c#中为这个事件添加一个处理程序?我在这里已经加载了这个包,并创建了一个从Microsoft.SqlServer.Dts.Runtime继承的自定义类。是我的“倾听者”:

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

If I check the sqlPackage.EventHandlers.Count property I get the right number for handlers added inside Business Intelligence Studio.

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

Is there some way to handle those events inside C#?

有什么方法可以处理c#中的这些事件吗?

Thanks.

谢谢。

1 个解决方案

#1


4  

Well I did not find anything so I came up with a work around so I will auto-respond to me:

我什么都没找到,所以我想出了一个办法,所以我会自动回复我:

Since there is no way to directly catch the events that the SSIS package make then I implemented my own events inside my listener:

由于无法直接捕获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
    }
} 

So the "trick" is to add a delegate to your "Listener" object that you pass to the LoadPackage method of the Package object, that way, we can access the "OnError" override inside the listener and raise the event. As you can see I implemented my own EventArguments class so we can pass important data to our handler code and see what package is running or any other information that you can get from overriding the methods when you inherit from DefaultEvents.

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

Of course I only implemented OnError here, you can implement any other handler you like that is supported by SQL Server and that can be overrided since that is the scope where we raise the event.

当然,我在这里只实现了OnError,您可以实现SQL Server支持的任何其他处理程序,这些处理程序可以被覆盖,因为这是引发事件的范围。

That way I can create my SqlPackageEventListener object and handle it's "OnPackageError" event with the sqlListener_OnPackageError method and do whatever I need in case of any error that the execution of the SSIS package caused.

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

#1


4  

Well I did not find anything so I came up with a work around so I will auto-respond to me:

我什么都没找到,所以我想出了一个办法,所以我会自动回复我:

Since there is no way to directly catch the events that the SSIS package make then I implemented my own events inside my listener:

由于无法直接捕获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
    }
} 

So the "trick" is to add a delegate to your "Listener" object that you pass to the LoadPackage method of the Package object, that way, we can access the "OnError" override inside the listener and raise the event. As you can see I implemented my own EventArguments class so we can pass important data to our handler code and see what package is running or any other information that you can get from overriding the methods when you inherit from DefaultEvents.

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

Of course I only implemented OnError here, you can implement any other handler you like that is supported by SQL Server and that can be overrided since that is the scope where we raise the event.

当然,我在这里只实现了OnError,您可以实现SQL Server支持的任何其他处理程序,这些处理程序可以被覆盖,因为这是引发事件的范围。

That way I can create my SqlPackageEventListener object and handle it's "OnPackageError" event with the sqlListener_OnPackageError method and do whatever I need in case of any error that the execution of the SSIS package caused.

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