I'm loading a ssis package from my application which works fine. However, what I'm trying to work out and failing miserably is that the package executes in 1 second (which is great) but the loading of the package takes 9 seconds.
Working locally in visual studio 2015 connecting remotely to a SQL Server 2014 instance.
The package is being loaded in a business object behind an async web api call from a console application.
Heres the code (standard stuff)...
Application application = new Application();
DTSExecResult result;
DTSPackageEventListener eventListener = new DTSPackageEventListener();
packageLocation = request.packageLocation;
//using (Package package = application.LoadPackage(packageLocation, eventListener)) // 9 seconds to load
using (Package package = application.LoadFromDtsServer(#"File System\<PACKAGENAME>", #"<SERVERNAME>", eventListener)) // 9 seconds to load
{
.
.
.
Does anyone have any tips? Any help/guidance would be much appreciated.
Simon.
This is normal, dtsx file is an xml file and the DtsRuntime library need to deserialize the file to load it as dot net class. Also there are some validation that are done on package loading.
Related
I have the following code which seems to works OK for executing an SSIS package from c# BUT every time the variable "Resp" returns a Failure even if the package passes when I execute it directly in SSIS.
Again, the package contains a Script component that writes to an SQL server table. All that works OK when the package is executed directly in SSIS but nothing happens when the same package is called via C# with the code below. I cant work out what I am doing wrong. help!
string packageLocation = #"c:\packageLocationPath";
Package pkg;
Application app;
app = new Application();
pkg = app.LoadPackage(packageLocation, null);
var Resp = pkg.Execute();
Detecting error
First you have to read the errors raised by the package. There are two options to detect these errors:
(1) loop over errors
You can loop over the package errors by accessing Errors property. As example:
if(p.Errors.Count > 0){
foreach(DtsError err in p.Errors){
Messagebox.Show(err.Description);
}
}
More information at:
How to get all errors of all SSIS packages in a solution
(2) Enable logging from package
You can capture all errors, warning and information from a package by enabling logging option:
Add and configure logging
Possible failure causes
Make sure that if you are using windows authentication to connect to SQL, that the user account used to execute the application via C# is granted to make a connection.
If the package is accessing a file system, make sure that the user has the required permissions to access these files
We have created a webservice on IIS which calls a R script. The R script includes some libraries like: data.table, caret and few a more. R is returning an error that it cannot find the data.table library:
"Error in library(data.table) : there is no package called
'data.table'".
We confirmed that the data.table package is installed in: "C:\Program Files\R\R-3.3.3\library\data.table". When we run .libPaths() to check where R tries to load the libraries from, it returns that this is the folder "C:/Program Files/R/R-3.3.3/library".
It does work successfully in a Visual Studio 2017 unit test or even in a console application environment. So the question is why can't R load the data.table library within IIS?
We using the following software versions:
R for Windows 3.3.3
Internet Information Services version 10.0.14393.0
RDotnet community 1.6.5
C# code:
R = REngine.GetInstance();
R.Initialize();
R.Evaluate("install.packages('data.table', repos='http://cran.us.r-project.org', dependencies = TRUE)");
R.Evaluate("library(data.table)");
We have decided to switch to 'Microsoft R Open' (MRAN) instead of R for Windows (CRAN). This solved a lot of problems for us. We couldn't get CRAN to work with IIS.
Only thing we need to do with MRAN is give the user the IIS application is running on modify access to the library folder at "C:\Program Files\Microsoft\R Open\library". This is needed to enable the R-engine within our application to install R-libraries.
I've been using TuesPechkin for some time now and today I went to update the nuget package to the new version 2.0.0+ and noticed that Factory.Create() no longer resolved, so I went to read on the GitHub the changes made and noticed it now expects the path to the dll?
IConverter converter =
new ThreadSafeConverter(
new PdfToolset(
new StaticDeployment(DLL_FOLDER_PATH)));
For the past few hours I've tried almost all the paths I can think of, "\bin", "\app_data", "\app_start", etc and I can't seem to find or figure out what it wants for the path and what dll?
I can see the TuesPechkin dll in my bin folder and it was the first path I tried, but I got the following error:
Additional information: Unable to load DLL 'wkhtmltox.dll': The
specified module could not be found. (Exception from HRESULT:
0x8007007E)
Where is that dll and now can I get it as the library doesn't seem to contain it, I tried installing the TuesPechkin.Wkhtmltox.Win32 package but the dll still is nowhere to be found. Also I am using this in a asp.net website project so I assume that using the following should work for obtaining the path, right?
var path = HttpContext.Current.Server.MapPath(#"~\bin\TuesPechkin.dll");
Further information: https://github.com/tuespetre/TuesPechkin/issues/57
The Tuespechkin has a zip file as a resource in the Win32 and Win64 embedded packages for the 'wkhtmltox.dll' file.
What it does when you use the Win32 or Win64 Embedded package is unzips the file and places it in the directory that you specify.
I have been putting a copy of the wkhtmltox dll at the root portion of my web app directory and pointing the DLL_FOLDER_PATH to it using the server physical path of my web app to get to it.
According to the author, you must set the converter in a static field for best results.
I do that, but set the converter to null when I am finished using it, and that seems to work.
Tuespechkin is wrapper for the wmkhtmlox dll file.
The original file is written in C++ and so will not automatically be usable in C# or VB.NET or any of the other managed code domains.
The Tuespechkin.dll file DOES NOT contain a copy of 'wkhtmltox.dll'. You either have to use one of the other embedded deployment modules or install a copy of the 'wkhtmltox.dll' in your web app after downloading it from the internet. That is what I do, and it seems to work just fine.
I am using Team Foundation Server, and attempts to compile code after using the Tuespechkin routines will fail the first time because the 'wkhtmltox.dll' file gets locked, but all you have to do is simply retry your build and it will go through.
I had issues with the 32-bit routine not working in a 64-bit environment and the 64-bit environment not being testable on localhost. I went with the workaround I came up with after examining the source code for Tuespechkin and the Win32 and Win64 embedded deployment packages.
It works well as long as you specify a url for the input rather than raw html.
The older package didn't render css very well.
If you are using a print.aspx routine, you can create the url for it as an offset from your main url.
I don't have the source code I am using with me at this point to offset to your base url for your web application, but it is simply an offshoot of HttpRequest.
You have to use the physical path to find the .dll, but you can use a web path for the print routine.
I hope this answers your question a bit.
If you are getting this error -> Could not load file or assembly 'TuesPechkin.Wkhtmltox.Win64' or one of its dependencies. An attempt was made to load a program with an incorrect format.
In Visual Studio Go to -
Tools -> Options -> Projects and Solutions -> Web Projects -> Use the 64 bit version of IIS Express for web sites and projects.
I installed TuesPechkin.Wkhtmltox.Win64 Nuget package and used the following code in a singleton:
public class PechkinPDFConvertor : IPDFConvertor
{
IConverter converter =
new ThreadSafeConverter(
new RemotingToolset<PdfToolset>(
new Win64EmbeddedDeployment(
new TempFolderDeployment())));
public byte[] Convert(string html)
{
// return PechkinSync.Convert(new GlobalConfig(), html);
return converter.Convert(new HtmlToPdfDocument(html));
}
}
The web application then has to be run in x64 otherwise you will get an error about trying to load an x64 assembly in an x86 environment. Presumably you have to choose x64 or x86 at design time and use the corresponding nuget package, it would be nicer to choose this in the web.config.
EDIT: The above code failed on one server with the exact same message as yours - it was due to having not installed VC++ 2013. So the new code is running x86 as follows
try
{
string path = Path.Combine(Path.GetTempPath(), "MyApp_PDF_32");
Converter = new ThreadSafeConverter(
new RemotingToolset<PdfToolset>(
new Win32EmbeddedDeployment(
new StaticDeployment(path))));
}
catch (Exception e)
{
if (e.Message.StartsWith("Unable to load DLL 'wkhtmltox.dll'"))
{
throw new InvalidOperationException(
"Ensure the prerequisite C++ 2013 Redistributable is installed", e);
}
else
throw;
}
If you do not want run the installer for wkhtmltox just to get the dll, you can do the following:
As #Timothy suggests, if you use the embedded version of wkhtmltox.dll from TuesPechkin, it will unzip it and place it in a temp directory. I copied this dll and referenced it with the StaticDeployment option without any issues.
To find the exact location, I just used Process Monitor (procmon.exe). For me it was C:\Windows\Temp\-169958574\8\0.12.2.1\wkhtmltox.dll
In my case, I am deploying on a 64-bit VPS then I got this error. I have solved the problem by installing the wkhtmltopdf that I downloaded from http://wkhtmltopdf.org/downloads.html. I chose the 32-bit installer.
In my case, I have solved the problem by installing the Wkhtmltox for win32 at https://www.nuget.org/packages/TuesPechkin.Wkhtmltox.Win32/
This error: Unable to load DLL 'wkhtmltox.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E) is returned in two situations:
1- Deploy dependency not installed:
For solve this, you can install nuget package "TuesPechkin.Wkhtmltox.Win64" and use this code (for WebApplications running in IIS):
IConverter converter =
new ThreadSafeConverter(
new RemotingToolset<PdfToolset>(
new Win64EmbeddedDeployment(
new TempFolderDeployment())));
// Keep the converter somewhere static, or as a singleton instance!
// Do NOT run the above code more than once in the application lifecycle!
byte[] result = converter.Convert(document);
In runtime this code will copy the dependency "wkhtmltox.dll" in a temporary directory like: "C:\Windows\Temp\1402166677\8\0.12.2.1". It's possible to get the destination of file using:
var deployment = new Win64EmbeddedDeployment(new TempFolderDeployment());
Console.WriteLine(deployment.Path);
2- Microsoft Visual C++ 2013 Redistributable not installed:
As described here:
https://github.com/tuespetre/TuesPechkin/issues/65#issuecomment-71266114, the Visual C++ 2013 Runtime is required.
The solution from README is:
You must have Visual C++ 2013 runtime installed to use these packages. Otherwise, you will need to download the MingW build of wkhtmltopdf and its dependencies from their website and use that with the library. https://github.com/tuespetre/TuesPechkin#wkhtmltoxdll
or, you can install the Microsoft Visual C++ 2013 Redistributable:
choco install msvisualcplusplus2013-redist
Here is AnyCpu version, also support iis-base or winform application
using TuesPechkin.Wkhtmltox.AnyCPU;
...
var converter = PDFHelper.Factory.GetConverter();
var result = converter.Convert(This.Document);
Reference : https://github.com/tloy1966/TuesPechkin
Installing the Visual C++ Redistributable for Visual Studio 2013 resolved the error for me.
https://www.microsoft.com/en-us/download/details.aspx?id=40784
Setup
I have a vs2010 SSIS package that I can run from visual studio. I have deployed it to my local 2012 server, and I can also execute that package from SSMS. In SSMS, I see the package here:
\Integration Services Catalogs\SSISDB\DAT_Load\Projects\UploadSYS.dtsx
Note: vs2010 does not give me an option to deploy a package anywhere but in a server, and then only in Integration Services Catalogs. Once in there, the MSDB database does not have an entry in the sysssispackages table.
Previously, it was adequate to bring up SSMS and run the package from there(right-click & execute). Now, I have to execute this from a C# web application. Furthermore, I need to trap progress messages and such through events.
Effort
I was able to determine how to set up the event trapping and I got myself to the point where I should have been able to execute the package from code:
public DTSExecResult ExecutePackage(string packageName, HttpContextBase context)
{
string ppath = ConfigurationManager.AppSettings[packageName + "Package"];
string pserv = ConfigurationManager.AppSettings[packageName + "Server"];
string puser = ConfigurationManager.AppSettings[packageName + "User"];
string ppass = ConfigurationManager.AppSettings[packageName + "Pwd"];
_context = context;
_pkgLocation = "";
_app = new Application();
_pkg = _app.LoadFromSqlServer(ppath, pserv, puser, ppass, _SSISEvents);
_pkgResults = _pkg.Execute(_connections, _variables, _SSISEvents, _log, null);
return _pkgResults;
}
Problem
I cannot locate the package. When I reach the LoadFromSqlServer statement, I receive an error that says:
Cannot find folder "\Integration Services Catalogs\SSISDB\DAT_Load\Projects\UploadSYS.dtsx"
The same thing happens for variations in the path (variable = ppath):
\Integration Services Catalogs\SSISDB\DAT_Load\Projects\UploadSYS.dtsx
\SSISDB\DAT_Load\Projects\UploadSYS.dtsx
\DAT_Load\Projects\UploadSYS.dtsx
etc.
Running this from the command line or a stored procedure is not an option.
So, can anyone tell what I am missing here? Does the Application object need to initialize something? Is this even possible?
Taking another bite at the problem but see Set SSIS database package path and SSIS Organization for background reading.
Until SSIS 2012, if packages were deployed to SQL Server, they lived in the msdb. The .NET API for interacting with them was the same across versions.
With the 2012 release of SSIS, we have two different deployment models. Package deployment, which is the "classic" model is alive and fully supported. The same code for running a package on 2005 will work for 2012 package deployment model projects. This is the Microsoft.SqlServer.Dts.Runtime Namespace
Your code is attempting to load a 2012 solution built using the "project deployment model" with the "package deployment model" API. This is the Microsoft.SqlServer.Management.IntegrationServices Namespace and the two don't mix.
Your options are to switch your project back to the Package deployment model or update your code. In the first linked question, I provided the VB.NET implementation for running an SSIS package in the SSISDB catalog. There is some way of running a .ispac file because I see the option in dtexec but I'm not seeing the specific method. This is mechanism VS/SSDT uses when it runs the packages locally.
I have an application where whenever a file is uploaded to a directory, I have to call SSIS to parse the XML file.
Can I call a SSIS directly from a .NET Windows service?
Running SSIS package programmatically.
I prefer the second method:
Start DTEXEC.EXE process. DTEXEC is command line utility for executing SSIS packages. See its command line options here: http://msdn2.microsoft.com/en-us/library/ms162810.aspx
Benefits: running package out of process gains reliability. Can be used from any programming language (including .NET 1.1 :)). Easy to pass parameters by setting variables values.
Drawbacks: Also local only. Harder to get information about package progress (but SSIS logging can give you most functionality). Some overhead on starting new process (likely minimal compared to execution time for big packages).
ASP.NET specific: Win32 CreateProcess function ignores the thread impersonation. So if you want DTEXEC to run under account different from ASP.NET process account, you should either make user enter name/password and pass it to Process.Start, or use method described in the following KB to run child process under impersonated account http://support.microsoft.com/kb/889251.
you can run your SSIS package programmatically, as follow:
using System;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
namespace ConsoleApplicationSSIS
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Loading SSIS Service...");
//Application object allows load your SSIS package
Application app = new Application();
//In order to retrieve the status (success or failure) after running SSIS Package
DTSExecResult result ;
//Specify the location of SSIS package - dtsx file
string SSISPackagePath = #"C:\Microsofts\BI\SSIS\ConsoleApplicationSSIS\IntegrationServiceScriptTask\Package.dtsx";
//Load your package
Package pckg = (Package)app.LoadPackage(SSISPackagePath,true,null);
//Execute the package and retrieve result
result = pckg.Execute();
//Print the status success or failure of your package
Console.WriteLine("{0}", result.ToString());
Console.ReadLine();
}
}
}
if you want a complete sample, go to :http://hassanboutougha.wordpress.com/2012/10/13/run-your-ssis-package-progammatically/
I explain how create a simple SSIS package and after how to call it programmatically from a console application. Don't forget to have this assembly :C:\Program Files (x86)\Microsoft SQL Server\100\SDK\Assemblies\Microsoft.SQLServer.DTSRuntimeWrap.dll to reference runtime ssis namespace
you can also pass your variables programmatically and change also source and destination connections of your ssis package
You can call SSIS programtically, execute the package and change the configuration from a .NET code using DTS runtime. Here is complete code of how you can do it.
You can call the SSIS package from your windows service. But Microsoft.SqlServer.Dts should be installed into the system where windows services are going to run. If you have installed DTS installed in that machine, directly call the SSIS package. If it is not installed then you should do the following.
Create the SSIS package
Create the job which runs the SSIS package
In your ADO.NET[resides in windows services code], Call stored
procedure which runs job[configured to run the SSIS package].
Following is an example should be called from your .NET code.
EXEC msdb.dbo.sp_start_job N'YourJobName'
Hope this helps!
Updating this pretty old question:
On SQL Server 2012 you can do this simply by creating stored procedure that will call to create_execution and set_execution_parameter
Step-by-step guide can be found here: https://blogs.msdn.microsoft.com/biblog/2013/05/07/step-by-step-of-executing-ssis-2012-package-through-stored-procedure/