In SSIS how to load the package inside Script Task c# code - ssis

In SSIS Script task I am able to load the package by providing the full path as following, but on the server I don't know the exact path after deployment, Is there any way to load the package and its configuration file.
public void Main()
{
Dts.TaskResult = (int)ScriptResults.Success;
Microsoft.SqlServer.Dts.Runtime.Application app = new Microsoft.SqlServer.Dts.Runtime.Application();
Package package = app.LoadPackage(#"C:\tfs01\AURA\DB\Main\Src\ReportSolution\AURA_ETL\AURA_ETL\DTS_PatientModel.dtsx", null);
}

As always, the documentation is your friend.
Instead of calling LoadPackage, you need to use LoadFromSqlServer. LoadPackage pulls from disk, LoadFromSqlServer talks to the msdb.
Note that if you are working with the 2012 project deployment, it's an entirely different mechanism.

Related

SSIS Script Task Error in Azure PAAS Server: The type or namespace name 'Office' does not exist in the namespace

I'm working on a SSIS project using SSDT (Sql Server Data Tools) with Visual Studio 2015 and I'm referencing the Microsoft.Office.Interop.Excel.dll in a Script Task and I have deployed the project through Azure Dev Ops(Pipeline and Release model) but it keeps throwing the following message:
Script Task: Error - The type or namespace name 'Office' does not exist in the namespace 'Microsoft'(Are you missing an assembly reference?)
I am not sure how to map the dlls inside the TFS.
I have also tried below approach as well but it didn't work out. Because there is no concept of drive concept in PAAS. So need to know how we can give the dlls reference inside the SSIS script task.
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
static ScriptMain()
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
if (args.Name.Contains("ssisHelper"))
{
string path = #"c:\temp\";
return System.Reflection.Assembly.LoadFile(System.IO.Path.Combine(path, "ssisHelper.dll"));
}
return null;
}
Any help please?
The office automation DLLs are part of an installation of Microsoft Office (licensing is also part of this install).
If you can install software on that box, you'll need to do so. Otherwise, you won't be able to use the office automation with your SSIS package

How to Encrypt the password to Excel using SSIS package? Is it possible?

How to Encrypt the password to Excel using SSIS package?
I thought, we can use script task to achieve this. I tried the below code by using the Spire.xls nugget package but the respective nugget dll reference are not adding to the solution.
Script task Code:
using Spire.Xls;
namespace ProtectExcel
{
class Program
{
static void Main(string[] args)
{
//Load Workbook
Workbook book = new Workbook();
book.LoadFromFile(#"C:\Test\Test.xlsx");
//Protect Workbook
book.Protect("vinay-123");
//Save and Launch
book.SaveToFile(#"C:\Test\ProtectExcel.xlsx", ExcelVersion.Version2010);
//System.Diagnostics.Process.Start("ProtectExcel.xlsx");
}
}
}
I tried the same code in c# console application it worked well but not working in SSIS script task.
Can anyone help me on this how to fix this or any other approach??
Script task Code:
using Spire.Xls;
namespace ProtectExcel
{
class Program
{
static void Main(string[] args)
{
//Load Workbook
Workbook book = new Workbook();
book.LoadFromFile(#"C:\Test\Test.xlsx");
//Protect Workbook
book.Protect("vinay-123");
//Save and Launch
book.SaveToFile(#"C:\Test\ProtectExcel.xlsx", ExcelVersion.Version2010);
//System.Diagnostics.Process.Start("ProtectExcel.xlsx");
}
}
}
Excel should be protected with password by using SSIS.
In SSIS, the dll has to be deployed to GAC to refer in the Script task code. Refer to the post on deploying to GAC for SSIS script task reference. For workaround on avoiding deploying to GAC, refer here
I would suggest you to generate exe out of the console application & use Execute Process task to call the console application with parameters, as explained here

Executing child package in SSIS package store from script task, with a twist

I have a parent package that needs to execute the same child package multiple times. To make things more fun, each instance needs to have a different value defined for the parent parameter passed to the child package.
I've created a script task using the following script:
Microsoft.SqlServer.Dts.Runtime.Application App = new Microsoft.SqlServer.Dts.Runtime.Application();
Package pkg = new Package();
try
{
pkg = App.LoadPackage(#"\\server\SSIS Packages\ChildPackage.dtsx", null);
pkg.Variables["ChildVariableName"].Value = Dts.Variables["AParentVariableName"].Value;
pkg.Execute();
Dts.TaskResult = (int)ScriptResults.Success;
}
catch (Exception ex)
{
Dts.Events.FireError(0, "Run child pkg for parent task", ex.Message, string.Empty, 0);
Dts.TaskResult = (int)ScriptResults.Failure;
}
Problem is, my packages are stored in the SSIS package store of my SQL 2008 R2 server and I can't figure out how to reference them; every code sample I've seen is for a physical location. This is on an HA cluster so having a physical location for the package will be difficult to maintain.
So I either need to (a) figure out how to change the value of ParentVariable every time an Execute Package task is kicked off for this child package or (b) figure out how to reference the proper package inside the SSIS package store, at which point I can safely pass the proper value. Anyone have any ideas?
Instead of App.LoadPackage method, you would use the LoadFromSqlServer method
app.LoadFromSqlServer("\OptionalFolderButSlashRequired\ChildPackage", "server", null, null, null);
The documentation on Application and Package usually have examples in the methods I've needed to use.

Running a package from memory with out saving it

I created a SSIS package pro-grammatically in C-sharp. Now I am running the package by creating it and saving it as FileName.dtsx and executing it as package.execute();
Now what I want to do is run the package in the memory itself without saving it. Is this possible to do that.
Tried a lot but cannot figure it out how to do that.
Don't save it?
static void Amarnath()
{
Microsoft.SqlServer.Dts.Runtime.Package p = null;
p = new Microsoft.SqlServer.Dts.Runtime.Package();
p.Execute();
}

Programmatically load SSIS package configurations

I am making a framework in SSIS to load files from configurable folders and match them to a logical job in the database. In this job a package name is configured and in SSIS I execute this package in runtime.
I want to programmatically load a package configuration for this package, depending on the job loaded. SSIS SQL Server package configuration is not an option, because that loads values to this package just once in runtime for the package itself, but I want to load a specific package configuration in runtime that has been stored with the job (job has one package, but has many package configurations)....
Schematically:
folderA -> file A.1 -> job A -> load package configuration for job A -> execute package in job A.
Is that possible?
We do something simliar using parent and child packages to run a standard package for differnt clients with differnt configuration values. The parent packge uses and enviroment variable and our configuration table to pull the configuration values for that particular process. The child table is configured to accept variables for the configuration which are sent from the parent package inthe execute package task. This also allows us to do some custom steps for a particular client in the parent package if need be (which is about 100% of the time here). So of you get one file form one client that they just cannot provide in the format the standard child import uses you can do transformation steps to get teh file ready for the standard import and then run the standard. Or you can add steps after the standrd package to send an email to the client with exceptions that they need to fix in their data for instance if only one client requires that.
You create Variables in the parent package for each piece of configuration information you want to send, typically to other variables or connection strings for the conmnections in the child package. You then put in an Excute package task that uses a connection to the child package.
In the child package you then go to the SSIS menu and choose package configurations and Add. Then for the type of configuration, you choose Parent Package variable. You will create one Parent package variable for each configuration item you want to send to the Child package. Things we send are things like the client_id, the connection strings to a client specific database, variables for things that might vary by client, etc.
We also store all our configurations in a table in a meta database where we store information about imports. So we set up our parent pacakge to use an environment variable to tell it which database to connect to to get the configuration information Then the second confiuration is to the SSISConfiguration table that stores the configuration information. We populate that information by server (it will vary by server generally, connection strings are different for dev, qa and prod) through an insert script that we run before testing the package.
For further detail, look in Books Online for execute package task and it wil show you how to set up the packages to pass variables.
I found the solution now. It is only possible by using a script task that uses the SSIS object model to create a package in runtime based on the SQL Server Application class where you can load the package by filename. After loading the package from file, I can read the configuration from file by xml or by SQL Server and add it in runtime to the child package configuration list.
Two important notes:
1) Parent variables are not passed to child package automatically.
Only when an execute package task is used the parent variables are passed to the child automatically. To get this working I search the variables in runtime and write the values in it, because I know the exact variables I want to pass to each child package.
2) When using SQL Server as a package configuration for a child package, you must also create a connection manager in runtime and add it to the connection manager collection of the package. when adding the package configuration to the child package, be sure that the name of that connection manager is part of the connection string.
Here is the code to prove it works:
//load the information of the job into these variables. Package is the File system deployed package on a share. Package configuration can be the package configuration in an xml file on a share, or a connection string when using SQL Server (this one is used here).
string package = this.Dts.Variables["Package"].Value.ToString();
string packageConfiguration = this.Dts.Variables["PackageConfiguration"].Value.ToString();
//create a package from package factory, by file.
Microsoft.SqlServer.Dts.Runtime.Application app = new Microsoft.SqlServer.Dts.Runtime.Application();
Package packageToRun = app.LoadPackage(package, null);
//------------------------------------------ CHILD PACKAGE VARIABLES PASSING
packageToRun.EnableConfigurations = true;
//add one extra package configuration for child package specific configuration
Configuration config = packageToRun.Configurations.Add();
config.Name = "MyConfig";
config.ConfigurationType = DTSConfigurationType.SqlServer;
config.ConfigurationString = packageConfiguration;
//use the name 'MyConnectionManager' in your packageConfiguration
ConnectionManager cm = packageToRun.Connections.Add("OleDb");
cm.Name = "MyConnectionManager";
//TODO: retrieve this from an environvariable to allow change in data source for DEV, QA, PROD, now temporarly fixed to this value
cm.ConnectionString = "Data Source=.;Initial Catalog=YYYYYYYYYY;Provider=SQLNCLI10.1;Integrated Security=SSPI;";
//For Parent-Child var passing, I used the technique to let all the parent variables being defined in the child packages.
//Other technique could be to allow the child package not define the parent variables, but then the child packages have to reference them from code
//------------------------------------------ PARENT VARIABLES PASSING
//Now check if these parent variables exist in child package and write the actual values in them
try
{
Variables vars = null;
VariableDispenser variableDispenser = packageToRun.VariableDispenser;
if (
packageToRun.Variables.Contains("User::XXXXXXXXXXXX") &&
)
{
packageToRun.VariableDispenser.LockForWrite("User::XXXXXXXXXXXX");
variableDispenser.GetVariables(ref vars);
packageToRun.Variables["User::XXXXXXXXXXXX"].Value = this.Dts.Variables["User::XXXXXXXXXXXX"].Value;
vars.Unlock();
packageToRun.Execute();
Dts.TaskResult = (int)ScriptResults.Success;
}
else
{
this.Dts.Events.FireError(0, string.Empty, "Child package: " + package + " has no required master variables defined or unable to unlock.", string.Empty, 0);
}
}
catch (Exception ex)
{
this.Dts.Events.FireError(0, string.Empty, ex.Message, string.Empty, 0);
Dts.TaskResult = (int)ScriptResults.Failure;
}