{
DTS.Application App=new DTS.Application();
DTS.PackageSQLServer package= App.GetPackageSQLServer("(local)\\NetSDK", "sa", "", DTS.DTSSQLServerStorageFlags.DTSSQLStgFlag_Default);
DTS.PackageInfos Infos;
Infos = package.EnumPackageInfos("", false, "");
foreach(DTS.PackageInfo Info in Infos)
{
Console.WriteLine("Name : {0}\tVersionID : {1}",Info.Name,Info.VersionID);
}
Console.Read();
}
First interesting thing here is DTS.Application which is actually "public interface Application" according to Object Browser. So we are creating our instance of that interface and using it to create our package object (PackageSQLServer) which is again interface. Further we are getting our infos and retrieving two out of 11 possible properties. Certainly I was quite surprised that we can create instance of interface simply by calling constructor of that interface. If we open EXE with ILDASM we will find:
newobj instance void [Interop.DTS]DTS.ApplicationClass::.ctor()
So it is really a constructor. Of course next in queue to be examined is Interop.DTS.dll (RCW created by VS.NET)
.
class interface public abstract auto ansi import Application implements DTS._Application{
.custom instance void [mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string) = ( 01 00 24 31 30 30 33 30 30 30 31 2D 45 42 31 43 2D 31 31 43 46 2D 41 45 36 45 2D 30 30 41 41 30 30 34 41 33 34 44 35 00 00 ) // 04A34D5..
.custom instance void [mscorlib]System.Runtime.InteropServices.CoClassAttribute::.ctor(class [mscorlib]System.Type) = ( 01 00 14 44 54 53 2E 41 70 70 6C 69 63 61 74 69 6F 6E 43 6C 61 73 73 00 00 ) // onClass..
} // end of class Application So we must be careful with Object Browser or IntelliSense when we are using unmanaged libraries in future. Procedure to enumerate what is in structured storage is almost identical : static void Main(string[] args)
{
DTS.Package2Class package=new DTS.Package2Class();
DTS.SavedPackageInfos Infos = package.GetSavedPackageInfos("C:\\Pubs2Pubs2Package.dts");
foreach(DTS.SavedPackageInfo Info in Infos)
{
Console.WriteLine("Name : {0}\tVersionID : {1}",Info.PackageName,Info.VersionID);
}
package.UnInitialize();
Console.Read();
}
Number of properties is somewhat smaller for info but treatment is about the same. Package2Class is object which we are going to use for execution or manipulation of properties.
static void Main(string[] args)
{
DTS.Package2Class package=new DTS.Package2Class();
try
{
Object MIA=System.Reflection.Missing.Value;
package.LoadFromSQLServer("(local)\\NetSDK", "sa", "", DTS.DTSSQLServerStorageFlags.DTSSQLStgFlag_Default, "", "", "{F580DFC4-1F6A-4D70-B6A1-1C200B0D7890}", "CustomTaskPKG",ref MIA);
Console.WriteLine(package.Description);
package.Description="My description";
Console.WriteLine(package.Description);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
package.UnInitialize();
package=null;
}
Console.Read();
}
If you want the freshest version of the package than just omit VersionID. To save new description use :
package.SaveToSQLServer("(local)\\NetSDK", "sa", "", DTS.DTSSQLServerStorageFlags.DTSSQLStgFlag_Default, "", "","",ref MIA,false);
For global variables procedure is again very similar.
static void Main(string[] args)
{
DTS.Package2Class package = new DTS.Package2Class();
try
{
Object MIA=System.Reflection.Missing.Value;
package.LoadFromStorageFile("C:\\Pubs2Pubs2Package.dts","","","","Pubs2Pubs2Package",ref MIA);
package.GlobalVariables.AddGlobalVariable("MyVariable","MyValue");
foreach(DTS.GlobalVariable GVar in package.GlobalVariables)
Console.WriteLine("Name : {0}\tValue : {1}",GVar.Name,GVar.Value);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
package.UnInitialize();
}
Console.Read();
}
To save changes to file use :
package.SaveToStorageFile("C:\\Pubs2Pubs2Package.dts","","",ref MIA,false);
Finally if you want to change value of some variable use :package.GlobalVariables.Item("MyVariable").let_Value("Hello from C#");
To execute package use :
package.Execute();
As you noticed so far the number of lines of code to achieve any of these operations is extremely small. This covers some simple manipulations of existing DTS package(s). Thanks to reach System.Collections namespace it's easy to manipulate DTS packages and their belonging properties and variables and create associations between packages, servers, CSV files and so on. As a matter of fact I have an application written in VB.NET ( as well as one in C#) which does that, so if anybody is interested in buying it my e-mail is at the bottom of the page.
Join the conversation! Your thoughts help the community grow.