Building the Task User Interface


This section describes how to create a user interface for your task. The task UI is developed in a separate project and compiled to a separate assembly from the task to simplify localization and maintenance. Other than the DTSTask attribute, the task has no connection to its TaskUI. This section starts by describing how to build a rudimentary custom task UI for the sample task and then moves on to describe how to use the foundation class Microsoft used for building rich task UI.

Separate Task and TaskUI Assemblies

The convention of separating tasks and taskUIs into their own assemblies is only a convention and is not enforced in any way. In fact, it is possible to have multiple tasks and taskUIs in the same assembly. However, it is recommended that you use separate assemblies to simplify servicing and localization and to minimize the memory working set.


Building the Sample Task UI (Simple)

To start the TaskUI project, step through the same steps used to start any of the custom components. Because they were covered in detail earlier, only the high-level steps are given here.

1.

Create a Class Library project. Call the project TaskUI.

2.

Rename the generated source file to SampleTaskUI.cs.

3.

Add a strong name and key file. You can use the key file already generated for the sample task.

4.

Reference SSIS and other assemblies. You need to reference the Microsoft.SqlServer.Dts.Runtime namespace in the Microsoft.SqlServer.ManagedRuntime assembly as before, but you must also reference the Microsoft.SqlServer.Dts.Runtime.Design namespace in the Microsoft.SqlServer.Dts.Design.dll assembly.

5.

Define the class. Change the namespace in SampleTaskUI.cs to be the same as the sample task, namely SampleTask.

6.

Compile and install. You need only place this assembly in the GAC. You do not need to copy it to the DTS\Tasks directory.

Adding the Form

At this point, you have a compiling component, but it contains no form and it has no relationship to the sample task. To add the TaskUI form, complete the following steps:

1.

Right-click on the TaskUI project in the Solution Explorer, and select Add, New Item.

2.

Select Windows Form and name the new file SampleTaskUIWnd.cs, as shown in Figure 24.13.

Figure 24.13. Adding a form to the TaskUI project


3.

Right-click on the SampleUIWnd.cs file in the Solution Explorer, and select View Designer.

4.

Drag two Label controls over to the form, and change the text to Name for one and Description for the other.

5.

Drag two text boxes to the form.

6.

Drag a button to the form and change the text to "OK" in the property grid.

7.

Change the DialogResult property to "OK."

8.

The form should look similar to the one shown in Figure 24.14.

Figure 24.14. The TaskUI form


9.

Double-click on the text box below the Name label and enter the following event handler code. Make sure the text box name matches the event name. In the sample, the text box name is textBox1.

private string name; private void textBox1_TextChanged(object sender, EventArgs e) {    name = textBox1.Text; } 


10.

Go back to the designer and do the same for the other text box below the Description label.

private string description; private void textBox2_TextChanged(object sender, EventArgs e) {    description = textBox2.Text; } 


11.

Modify the constructor code as follows to store the Taskhost reference and to initialize the name and description text boxes.

private TaskHost m_taskHost; public SampleTaskUIWnd(TaskHost taskHost) {    m_taskHost = taskHost;    InitializeComponent();    textBox1.Text = m_taskHost.Name;    textBox2.Text = m_taskHost.Description; } 


12.

Go back to the designer one more time, double-click the OK button, and enter the following code to set the name and description on the task.

Tip

In the TaskUI, it's best to wait until the end before committing task property value changes. With this code, changes are only committed when the user clicks the OK button. If you directly change the values on the Taskhost, you would have to change them back if the user cancels the edit.

private void button1_Click(object sender, EventArgs e) {    m_taskHost.Name = name;    m_taskHost.Description = description; } 


13.

The final step is to derive the SampleTaskUI class from the IdtsTaskUI interface defined in the Microsoft.SqlServer.Dts.Design namespace. Open the SampleTaskUI.cs source file and modify the code to look like the following:

using System; using System.Collections.Generic; using System.Text; using System.Windows.Forms; using Microsoft.SqlServer.Dts.Runtime.Design; using Microsoft.SqlServer.Dts.Design; namespace SampleTask {    public partial class SampleTaskUI : IDtsTaskUI    {       private Microsoft.SqlServer.Dts.Runtime.TaskHost m_taskHost;       public void       Initialize(Microsoft.SqlServer.Dts.Runtime.TaskHost taskHost,                  System.IServiceProvider serviceProvider)      {  // Save the taskhost reference         m_taskHost = taskHost;      }      public ContainerControl GetView()      {  // Show the TaskUI         return new SampleTaskUIWnd(m_taskHost);      }      public void Delete(System.Windows.Forms.IWin32Window form)      {      }      public void New(System.Windows.Forms.IWin32Window form)      {      }    } } 


As you can see, the interface for task UIs is called IDTSTaskUI. This interface has four methods:

  • Initialize This method is called by the client (that is, the designer application) to associate a task UI with the task. Note that the Taskhost is passed in as the first parameter. The logic of the task UI can use this pointer to access the variables collection on the Taskhost, get the task pointer by calling GetInnerUnknown on the Taskhost, or view the errors collection, and so forth. The ServiceProvider provides a way to access services such as the connection service for accessing or creating connection managers. This Initialize method should be implemented at a minimum so that you can save the Taskhost reference.

  • GetView This method is called by the client whenever the task UI should show itself. This method must be implemented.

  • New This method is called when a new task is added to the package. This method is rarely implemented.

  • Delete This method is called when a task is about to be deleted. This method is rarely implemented.

This code saves the Taskhost reference and then passes it into the form when the GetView method is called. The form sets properties on the Taskhost and on the task as well if you add properties to the task. There is one more thing to do now and that is to connect the task with the task UI. You do this with the DTSTask attribute UITypeName parameter. You will remember that the format for the UITypeName is as follows:

UITypeName = "NamespaceTypeName, AssemblyName, Version=AssemblyVersion, Culture=Neutral, PublicKeyToken= PublicKeyToken".

  • NamespaceTypeName This is the fully qualified name of the TaskUI. In the SampleTaskUI case, it is SampleTask.SampleTaskUI.

  • AssemblyName This is the filename of the TaskUI assembly sans the .dll extension. For the SampleTaskUI assembly, this is SampleTaskUI.

  • Version This is the version of the task UI assembly specified in the AssemblyInfo.cs file.

  • Culture This is the culture of the TaskUI assembly and can be discovered by looking at the properties of the assembly, as shown in Figure 24.15.

  • PublicKeyToken You find this value by examining the properties of the TaskUI assembly in the GAC. Go to C:\Windows\Assembly and find the TaskUI assembly. Right-click on the assembly name and select Properties. Figure 24.15 shows the properties dialog box for the SampleTaskUI assembly. Notice the public key token that is highlighted.

Figure 24.15. Finding the public key token for the TaskUI assembly


After you get the UITypeName right, you're ready to build and install the task and task UI assemblies. Make sure the task assembly is installed in the GAC and the DTS subfolder. Also, make sure the task UI assembly is installed in the GAC. Create a new SSIS project, add the SampleTask to the Toolbox if you haven't already, and drop it onto the package surface. Double-click on the task to open the task UI.

Tip

After you have opened the task UI inside the designer, the designer caches a reference to the assembly. If you make subsequent changes to the task UI, they are not reflected in the designer until you close down all instances of the designer that have previously opened the task UI. If you make changes to the task UI, close down the designer containing the package you use to test the task UI, rebuild the entire task and task UI project, and reload the test package. That is the only way to consistently ensure that the designer picks up the updated task UI.


If you get lost or just want to go straight to the code, you can look at the SampleTask solution in the samples under SAMPLES\SRC\SampleComponents\SampleTask.

Building a Sophisticated TaskUI (Complex)

Although simple taskUIs might be sufficient for some tasks, if you want your tasks to have the same look and feel as the stock tasks, you need to create a more sophisticated taskUI. Integration Services provides a standard framework for taskUIs. It is the same framework Microsoft used for building all the stock taskUIs and supports the Property Expression page and Expression Builder by default. The taskUI foundation classes and definitions are found in the following assemblies:

  • Microsoft.SQLServer.Dts.Design Contains IDtsConnectionService for creating new connection managers and other important definitions.

  • Microsoft.DataTransformationServices.Controls Contains DtsBaseTaskUI and other important classes.

Caution

When you right-click on the References node for your taskUI project and select Add References, the Microsoft.DataTransformationService.Controls assembly does not show up in the .NET assemblies tab of the Add Reference dialog box. You need to select the Browse tab and search for the assembly. This makes a copy of the assembly while you are designing the UI. You do not need to install this assembly, however, because it is in the GAC. You only need a copy of the assembly while developing the task UI. On machines where SSIS has been installed, you'll find this assembly in the C:\Windows\Assemblies folder or its equivalent.


There are two sample tasks that use the framework. StarterTaskUI in the StarterTask sample solution is a rudimentary taskUI you can use for starting your own tasks and taskUIs. CryptoTask is a complete task and taskUI and uses some of the more interesting features of the framework such as custom UITypeEditors. The samples shown here are from the CryptoTask sample code. Only the more interesting aspects of the code are covered here because the taskUI code is somewhat lengthy. You can find both projects in the SAMPLES\SRC\SampleComponents folder.

Figure 24.16 shows the CryptoTask taskUI settings node. This taskUI has four custom properties that are typical of the kinds of properties that you might want to support on your taskUIs. The four property types are as follows:

  • Connection Managers, Source and Destination

  • Password

  • Custom Enum type selector

  • Boolean

Figure 24.16. The CryptoTask Settings node


By now, the taskUI design should be familiar to you. On the left side of the taskUI is the tree view that contains nodes that when selected present you with different property grids or views on the right side of the taskUI. The upper-left of the taskUI shows an icon and description. Each of these sections of the taskUI is customizable.

Starting the Project

To get started with the taskUI, you can use the same steps as described for the simple taskUI by creating a class library project, deriving the class from IDtsTaskUI, and implementing the Initialize and GetView methods or you can use the StarterTask project and modify it as needed. The following is the code for the CryptoTask IDtsTaskUI interface methods:

[View full width]

namespace SSIS2K5.Samples.Tasks.CryptoTask { public class CryptoTaskUI : IDtsTaskUI { // TaskUI receives a TaskHost and we cache it here. private TaskHost taskHost = null; // Get the connection service for creating connections if needed. private IDtsConnectionService connectionService = null; // Called by the designer to initialize the taskHost UI public void Initialize(TaskHost taskHost, System.IServiceProvider serviceProvider) { this.taskHost = taskHost; this.connectionService = serviceProvider.GetService(typeof (IDtsConnectionService)) as IDtsConnectionService; } // Called by the designer to show the window public ContainerControl GetView() { return new CryptoTaskUIMainWnd(taskHost, connectionService); } /// <summary> /// Called when a new Task is added to the package. /// </summary> public void New(IWin32Window parentWindow) { // do nothing } /// <summary> /// Called when an existing taskHost is about to be deleted from the package /// </summary> public void Delete(IWin32Window parentWindow) { // do nothing } } }


If you worked through the simple task sample, this code should look familiar to you. It's almost exactly the same and is how the designer communicates with the taskUI. Notice that the Initialize method stores a reference to the serviceProvider parameter and that in the GetView method a new form called CryptoTaskUIMainWnd is created. The serviceProvider parameter is later used for creating connection managers. When the designer calls GetView on CryptoTaskUI, it simply creates an instance of the CryptoTaskUIMainWnd. The CryptoTaskUIMainWnd is derived from the taskUI framework DTSBaseTaskUI base class.

The taskUI code has five source files:

  • CryptoTaskUI.cs Contains the portion of the taskUI that interacts with the Business Intelligence Development Studio.

  • CryptoTaskUIMainWnd.cs Contains the partial class definition of the CryptoTaskUIMainWnd main form you see when you open the taskUI. There is little code in this file, but it is important code nonetheless.

  • CryptoTaskUIMainWnd.Designer.cs Contains the forms editor generated code for the CryptoTaskUIMainWnd form.

  • GeneralView.cs Contains the code that implements the General view in the taskUI and is derived from IDtsTaskUIView.

  • SettingsView.cs Contains the code that implements the Settings view in the taskUI and is derived from IDtsTaskUiView.

TaskUI Foundation Classes, Interfaces, and Terms

The following list of terms are used throughout the TaskUI Foundation Classes. Understanding these terms will help you better understand the taskUI code.

  • Tree-panel This is the name used to describe the layout of the taskUI with the tree on the left and the panel or views on the right.

  • Hosted view The hosted view is the property grid control hosted inside the panel on the right side of the tree-panel dialog box.

  • Tree The tree is the selection of nodes on the left side of the taskUI.

  • IDTSTaskUIView This interface is implemented by the hosted views, which change depending on the node selected in the tree.

  • DTSBaseTaskUI This is the abstract base class from which you derive the taskUI form.

  • IDTSTaskUIHost This interface is used by the hosted views to communicate with the tree, and is also used by the tree to communicate with the views. This interface is implemented in the base class so you do not implement it.

  • IDtsTaskUI This is the interface with which the designer interacts.

The IDTSTaskUIHost Interface

The IDTSTaskUIHost interface is used for communicating back and forth between the tree and the views. You do not need to implement this interface because it is already implemented in the base DTSBseTaskUI. The IDTSTaskUIHost interface has the following methods and properties:

// Add an IDTSTaskUIView derived view to the right side panel void AddView(    string viewName,    IDTSTaskUIView view,    TreeNode parentNode ); // Add an IDTSTaskUIView derived view to the right side panel with an image // Provide an index into the image list for displaying in the tree void AddView(    string viewName,    int imageIndex,    IDTSTaskUIView view,    TreeNode parentNode ); // Return the TreeNode associated with a view TreeNode GetViewNode(IDTSTaskUIView view); // Return the view associated with a TreeNode IDTSTaskUIView GetView(TreeNode treeNode); // Add an imagelist for displaying in the tree. void SetImageList(ImageList imageList); // Remove a view from tree void RemoveView(IDTSTaskUIView view); // Remove a view from tree void RemoveView(TreeNode viewNode); // display a specific view void SelectView(IDTSTaskUIView view); // display a specific view void SelectView(TreeNode viewNode); // Display the error message in the error area of the form void DisplayError(string errorMessage); // By default set to true. If set to false the views will be initialized bool FastLoad{ get; set; } // If true the dialog can be closed with the OK button. // true by default if all the views return true from OnValidate method bool CanCommit{ get; set; } 


The IDTSTaskUIView Interface

This interface must be implemented by hosted views and allows the tree view to communicate various changes to the hosted view. The following code shows the IDTSTaskUIView methods and how they are used.

public interface IDTSTaskUIView {    // If FastLoad from IDTSTaskUIHost is set to true,    // this method is called when the view is added to the tree.    // Otherwise it will be called when the view is about to    // be displayed for the first time    void OnInitialize(     IDTSTaskUIHost treeHost,                // IDTSTaskUIHost that hosts the view.     System.Windows.Forms.TreeNode viewNode, // The task that is being edited.     object taskHost,                        // The tree node associated with this view.     object connections                      // The connection managers in the package.     );     // Called whenever the view is about to be displayed     void OnSelection();     // Called whenever the view is about to be exited.     // You can use this method to refuse to leave the view.     void OnLoseSelection(        ref bool bCanLeaveView, // True if the view can be left.        ref string reason       // Error message if bCanLeaveView returned false.     );     // Called when the OK button is clicked to validate the input.     void OnValidate(        ref bool bViewIsValid, // Result of the validation, true if validated successfully.        ref string reason      // Error message if bViewIsValid returned false.     );     // Called when OK button is clicked, but only if all OnValidate calls succeeded.     void OnCommit(        object taskHost   // The TaskHost for the task to modify.     ); } 


TaskUI Provided Attributes

The TaskUI foundation classes also provide a set of attributes you can use to modify the hosted views. These attributes control the behavior of the property grid cells and provide a way to easily support properties of different types.

EnableExpandable Use the EnableExpandableAttribute to specify whether a user-defined type is to be expandable or nonexpandable in the property grid based on a Boolean property defined by the user-defined type.

Caution

The type must have a copy constructor defined and expandable types must have the RefreshProperties(RefreshProperties.All) attribute.


The following code sample is an example of an expandable type and how to set one up in a view:

EnableExpandable("DTSExpandable")] public class ExpandableType {    private bool bExpandable = false;    private bool bExpanded = true;    // Constructor    public ExpandableType()    {    }    // Copy constructor    public ExpandableType(ExpandableType xt)    {       this.DTSExpandable = xt.DTSExpandable;       this.bExpanded = xt.Expanded;    }    // Don't show in the designer    [Browsable(false)]    public bool DTSExpandable    {       get{ return bExpandable;}       set{ bExpandable = value; }    }    public bool Expanded    {       get { return bExpanded; }       set { bExpanded = false; }    } } 


In the hosted view class, you would have the following code to add the type to the property grid:

Public class Class1 {     ...     Public ExpandableType xpand = new ExpandableType();     [RefreshProperties(RefreshProperties.All)]     public ExpandableType ExpandableProperty     {        get{ return m_xtVal; }        set{ m_xtVal = value;}     } } 


The ExpandableProperty is a property on the hosted view, but stores the value in a member variable. Later, when the user closes the taskUI with the OK button and commits the changes, the hosted view can set the task's property value to the value in the member variable.

EnableDisable Use the EnableDisable attribute to disable a property in the property grid based on an array of values of another property. One of the two properties needs to have the RefreshProperties attribute, as shown for the EnableExpandable attribute.

SortProperties Use this attribute to dictate the order of properties in the property grid. This attribute receives an array of strings containing one of the following:

  • All of the properties of the type in the order you want to sort them.

  • Some of the properties' names. Those passed in are sorted according to the order found in the array. The rest are sorted alphabetically.

  • The array is NULL. The properties are sorted in alphabetical order, which is the same as if you didn't add the attribute at all.

LocalizablePropertyDescription The LocalizablePropertyDescription attribute provides a way to retrieve a localizable description for the property that will appear in the description section at the bottom of the property grid.

LocalizablePropertyName The LocalizablePropertyName provides a way to retrieve a localizable name for the property.

LocalizablePropertyCategoryThe LocalizablePropertyCategory provides a way to retrieve a localizable category name that shows in between the properties and categorizes them into groups.

Using the TaskUI Foundation Classes

Take a look at the sample code to see some of these pieces working together. In CryptoTaskUIMainWnd.cs, you'll find the constructor for the CryptoTaskUIMainWnd class where the hosted views are created and added to the main form.

public partial class CryptoTaskUIMainWnd : DTSBaseTaskUI {    #region members    private const string Title = "Crypto Task Editor";    private const string Description = "This task encrypts and decrypts text.";    public static Icon taskIcon = new Icon(typeof(SSIS2K5.Samples.Tasks.CryptoTask.CryptoTask), "TaskIcon.ico");    #endregion    // Construct and pass base class to the    // title, taskicon, desc., taskhost, & connections.    public CryptoTaskUIMainWnd(TaskHost taskHost, object connections) :      base(Title, taskIcon, Description, taskHost, connections)    {      // Proactively assert that the taskHost is valid      Debug.Assert(taskHost != null);      // Create a new general hosted view      GeneralView generalView = new GeneralView();      // Add the view to the main form      this.DTSTaskUIHost.AddView("General", generalView, null);      // Create a new settings view      SettingsView settingsView = new SettingsView();      // Add the view to the main form      this.DTSTaskUIHost.AddView("Settings", settingsView, null);      InitializeComponent();    } } 


The description is what shows up on the top of the taskUI with the icon. The constructor also calls into the base class constructor to ensure that the icon, description, and other elements are correctly displayed. Then, the code adds the two hosted views. The hosted views are where the really interesting things happen.

Getting the Connections

The following code shows how to retrieve only the connections of a given type in the internal class FileConnections, which is a TypeConverter:

[View full width]

/// <summary> /// Method to get the file connections created or available in the package /// </summary> /// <param name="retrievalObject"></param> /// <returns>list of FILE connections</returns> private ArrayList getFileConnections(object retrievalObject) { SettingsNode node = (SettingsNode)retrievalObject; Connections runTimeCons = ((IDtsConnectionService)node.Connections). GetConnections(); ArrayList list = new ArrayList(); list.Add(NEW_CONN); foreach (ConnectionManager conn in runTimeCons) { if (conn.CreationName.CompareTo("FILE") == 0 || conn.CreationName. CompareTo ("FLATFILE") == 0) { list.Add(conn.Name); } } if (list.Count > 0)) list.Sort(); return list; }


The FileConnections TypeConverter is used to provide the names of file connection managers in the taskUI by passing it as a parameter to the TypeConverter attribute on the SourceConnection and DestinationConnection properties, as follows:

[ Category("Connections"), Description("The destination connection"), TypeConverter(typeof(FileConnections)) ] public string DestinationConnection {        get { return _destConnection; }        set { _destConnection = value; } } 


Notice also that the Category attribute creates a grouping of properties based on the string passed as a parameter, in this case "Connections."

Handling Connection Manager Events

The special handling needed for the Connection Manager combo box is done in the PropertyValueChanged event handler in the SettingsView.cs source code, as follows:

private const string NEW_CONN = ">New Connection...<"; private void propertyGridSettings_PropertyValueChanged(object s, System.Windows.Forms.PropertyValueChangedEventArgs e) {    #region New File Connection for Source path    if (e.ChangedItem.PropertyDescriptor.Name.CompareTo("SourceConnection") == 0)    {       if (e.ChangedItem.Value.Equals(NEW_CONN))       {           ArrayList list = null;           this.Cursor = Cursors.WaitCursor;           if (!((settingsNode.SourceCMName == null) || (settingsNode.SourceCMName    == "")))                    settingsNode.SourceCMName = null;           list = ((IDtsConnectionService)settingsNode.Connections). CreateConnection("FILE");           this.Cursor = Cursors.Default;           if ((list != null) && (list.Count > 0))           {              ConnectionManager cMgr = (ConnectionManager)list[0];              settingsNode.SourceCMName = cMgr.Name;           }           else           {              if (e.OldValue == null)              {                  settingsNode.SourceCMName = null;              }              else              {                 settingsNode.SourceCMName = (string)e.OldValue;              }           }        }     } } 


In the preceding code, the event handler checks to see whether the <New Connection> option was chosen from the Connection Manager combo box. If it was, the code uses the IDtsConnectionService to create a new connection manager of type FILE. This is how the taskUI launches the correct Connection Manager creation dialog box.

The taskUI is perhaps the most complex part of building a custom task; however, with the taskUI foundation class library, you can quickly build a professional looking and functional taskUI that looks identical to the stock taskUIs and automatically take advantage of the built-in property expression hosted view. This introduction didn't cover every aspect of writing taskUIs, but should get you started. You can study the sample code to get a better understanding of how to roll your own taskUIs. Also, you can copy the starter task and taskUI project into a new folder and quickly start building your custom tasks and taskUIs beginning with what is already in those projects.

Debugging the Task

Because of the way the designer (BIDS) executes packages, you must take two different approaches to debugging your custom task based on whether you are executing the package. The designer has a special debugging host called DTSDebugHost that it launches. The host prevents problems with orphaned packages or rogue tasks and helps the designer be more robust, but it also makes it a little tricky to debug components.

Debugging Tasks During Design Time

When debugging tasks and taskUIs in the designer, it is easiest to create a testing package in another instance of the designer and then attach to the second instance of the designer from the task project designer. Following are the steps to set up for debugging a task.

1.

Create a new Integration Services project.

2.

In the Visual Studio Development Studio (DevEnv) where you have your task project, set a breakpoint in either the task or taskUI code that you want to debug.

3.

From the Debug menu, select Attach to Process. The Attach to Process dialog box opens.

4.

Select the devenv.exe process with the title that appears the same as the title of the DevEnv containing your test solution, as shown in Figure 24.17.

Figure 24.17. Attaching to the Development Studio process


5.

Ensure that the code type is correct by clicking the Select button.

6.

Click the Attach button.

7.

Switch back to the DevEnv containing your test solution and open the taskUI or do something else such as change a property so that your breakpoint gets hit.

8.

In the sample case, the breakpoint is on the constructor for the CryptoTaskUIMainWnd class, as shown in Figure 24.18. When opening the taskUI for the CryptoTask, the breakpoint is hit and the development environment takes control. You can now step through the taskUI code.

Figure 24.18. Hitting the breakpoint in the development environment


This also works for the task code. However, because only certain task code paths are executed during design time, you have to judiciously decide where to put the breakpoint. For example, you can place a breakpoint in a property GET method and then modify the method through the property grid in BIDS.

Debugging Tasks During Execution Time

During execution, it's a little trickier, but not much. Instead of attaching to a running instance of BIDS, you attach to DTSDebugHost. Also, you need to set a breakpoint in the package so the package doesn't complete execution before you have a chance to attach to it. Finally, if you want to debug the InitializeTask or Validate methods, you need to use the design time debugging method. The designer calls those methods before loading the package into the debug host and executing it. The following steps show one way to debug a task's Execute method:

1.

Create a new Integration Services project.

2.

In the package, drag a task onto the Control Flow surface and configure it as you like.

3.

Set a breakpoint on the package OnPreExecute event.

4.

Run the package and let it hit the breakpoint.

5.

In the DevEnv where you have your task project, set a breakpoint on the Execute method of the task you want to debug.

6.

From the Debug menu, select Attach to Process. Look for the DtsDebugHost.exe process. There are usually two processes, but only one is correct. Select the one that has managed code available for debugging. Experiences differ on whether it is the first or second entry. Whatever order in which you find the processes listed, it seems to remain consistent.

7.

Click the Attach button.

8.

Go back to the Integration Services project where the package is waiting on a breakpoint and let the package run.

9.

When the package executes your task, the breakpoint should get hit and the development environment should take over.

10.

You can now step through the task's Execution method code.



Microsoft SQL Server 2005 Integration Services
Microsoft SQL Server 2005 Integration Services
ISBN: 0672327813
EAN: 2147483647
Year: 2006
Pages: 200
Authors: Kirk Haselden

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net