Search code examples
c#ssissql-server-data-toolssmoscript-task

How to send Dts information messages SSIS from event handler?


I have an SSIS package with a Script Task that calls some basic C# code. I'm using SQL SMO to copy a list of tables from DB1 to DB2.

I have that working, but what I am trying to do is subscribe to the SMO event handlers and send progress messages back to SSIS, so that while the SSIS package is running, I'll know what it's doing.

I've found the event handlers to use, but the issue is I can't access the Dts variable to send messages...what am I doing wrong?

public static void DataTransferReport(object sender, DataTransferEventArgs args)
{
    bool fireAgain = false;

    // This line does not work. sender is `Transfer`
    var Dts = sender as Microsoft.SqlServer.Dts.Tasks.ScriptTask.ScriptObjectModel;            

    Dts.Events.FireInformation(2, "MySubComponent", "My Message Test", "", 0, ref fireAgain);
}
protected static void DiscoveryProgressReport(object sender, ProgressReportEventArgs args)
{
    Console.WriteLine("1[" + args.Current.Value + "]");
}
protected static void ScriptingProgressReport(object sender, ProgressReportEventArgs args)
{
    Console.WriteLine("2[" + args.Current.Value + "]");
}
protected static void ScriptingErrorReport(object sender, ScriptingErrorEventArgs args)
{
    Console.WriteLine("3[" + args.Current.Value + "]");
}

Abbreviated main method below that shows how I call event handlers.

public void Main()
{
    // Some code above...

    // Setup the transfer and parameters
    Transfer transfer = new Transfer
    {
        Database = sourceDatabase,

        //set destination server and database
        DestinationServer = edwConnection.Name,
        DestinationDatabase = edwConnection.Databases[targetDatabaseName].Name
    };

    //include data
    transfer.CopyData = true;

    bool fireAgain = false;

    // Loop over each table candidate var
    foreach (string tableName in tableNames)
    {
        // Create a table object
        Table table = sourceDatabase.Tables[tableName];

        // verify it exists and is not a system table
        if (table != null && !table.IsSystemObject)
        {
            // Add table object to transfer list
            transfer.ObjectList.Add(table);
        }
    }

    // Subscribe event handlers 
    transfer.DataTransferEvent += new DataTransferEventHandler(DataTransferReport);
    transfer.DiscoveryProgress += new ProgressReportEventHandler(DiscoveryProgressReport);
    transfer.ScriptingProgress += new ProgressReportEventHandler(ScriptingProgressReport);
    transfer.ScriptingError += new ScriptingErrorEventHandler(ScriptingErrorReport);

    // DO THE WORK!           
    transfer.TransferData();

    // More code below...
}

Solution

  • I may not be understanding correctly...but couldn't you just remove static and it would work? Here's one of your methods, you'll need to do the same for the others. Sender will still be the Transfer object that you are subscribing the event to.

    public void DataTransferReport(object sender, DataTransferEventArgs args)
    {
        bool fireAgain = false;       
    
        Dts.Events.FireInformation(2, "MySubComponent", "My Message Test", "", 0, ref fireAgain);
    }