Debugging SSIS vb.net Script - vb.net

I am debugging a SSIS vb.net script in a Visual Studio 2005 SSIS project.
Is there a way to execute just the script without having to start in my control flow? Otherwise I have to work through my other steps and drill down through my Script Task into the Editor into the actual script.
As a side not my script is pretty simple, it just creates a directory if a directory with today's date is not found.
Imports System
Imports System.IO
Imports Microsoft.VisualBasic
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
Public Class ScriptMain
' Checks to see if todays folder exists on sqlzdocs -> if it doesnt it creates it. Else it errors
Public Sub Main()
Dim todaysdate As String = String.Format("{0:yyyyMMdd}", DateTime.Now)
Dim di As IO.DirectoryInfo = New IO.DirectoryInfo("\\MyServer\Path\Current\" + todaysdate )
If di.Exists = True Then
Dts.Variables("User::FolderExists").Value = True
Else
Try
Dim createdirectory As IO.DirectoryInfo = Directory.CreateDirectory(di.ToString)
Catch ex As Exception
Dts.Variables("User::Errors").Value = "Could not create the directory:" + di.ToString
Dts.Variables("User::FolderExists").Value = False
End Try
End If
Dts.TaskResult = Dts.Results.Success
End Sub
End Class

When i was developing ETL modules that had Script tasks, i followed couple of things to help in testing
Logging the Script task execution points - I wrote simple custom module to handle that
Seperated the functions in the script task and created a seperate Vb.net console project. I executed that project and once it was working successfully, i then included the same in the SSIS project.

Related

SSIS VB.Net Script to download a file using a proxy

I am trying to write a VB.Net script to download a file from the web in a SSIS dtsx package.
I started from this, but I am having only proxy authentication errors (error 407).
I double checked the proxy, the port and the URL an they are right!
Can anyone help me please? I can't understand where the problem could be.
' Microsoft SQL Server Integration Services Script Task
' Write scripts using Microsoft Visual Basic
' The ScriptMain class is the entry point of the Script Task.
Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
Imports System.Net
Public Class ScriptMain
Public Sub Main()
Dim objWebClient As WebClient = New WebClient()
Dim objCache As New CredentialCache()
Dim strDownloadURL As String = "http://www.example.com/data.xlsx"
Dim strProxyURL As String = "myproxy.mycompany.local"
Dim intProxyPort As Integer = 1234
'Set Proxy & Credentials as a Network Domain User acc to get through the Proxy
Dim wp As WebProxy = New WebProxy(strProxyURL, intProxyPort)
objWebClient.Proxy = wp
'Download file, use Flat File Connectionstring to save the file
objWebClient.DownloadFile(strDownloadURL, "E:\MyFile.xlsx")
Dts.TaskResult = Dts.Results.Success
End Sub
End Class
The file of strDownloadURL is accessible by browser and doesn't need any form of authentication. Anyone can access it by a web browser.

Parse solution using DTE Visual Basic

I have to parse my solution to list all files that it is using.
I have created this:
Imports EnvDTE
Imports EnvDTE80
Imports Microsoft.VisualBasic
Imports System.Collections
Public Class C
Implements VisualCommanderExt.ICommand
Sub Run(DTE As EnvDTE80.DTE2, package As Microsoft.VisualStudio.Shell.Package) Implements VisualCommanderExt.ICommand.Run
listing(DTE)
End Sub
Sub listing(DTE As EnvDTE80.DTE2)
Dim prj As Project
Dim prjs As Projects
prjs = DTE.Solution.Projects
For Each prj In prjs
Dim item As String
Dim itemEnum as IEnumerator = prj.GetEnumerator()
itemEnum.Reset()
While itemEnum.MoveNext()
item = itemEnum.Current().FullName
My.Computer.FileSystem.WriteAllText("C:\tmp\list.txt", item, True)
End While
Next
End Sub
End Class
Unfortunately I encounter the Exception:
System.Runtime.InteropServices.COMExcption(0x80020003): Member not found....
My solution has 10 projects.
Navigating projects and files is recursive because they can be nested.
See my articles:
HOWTO: Navigate the files of a solution from a Visual Studio .NET macro or add-in.
HOWTO: Navigate the files of a solution using the IVsHierarchy interface from an add-in.
http://www.visualstudioextensibility.com/articles/add-ins/

Error in VB Function in SSIS but not in VisualStudio

I have some VB.Net code that I'm trying to add to a SSIS package. The code runs fine in VisualStudio 2012 and when I compile it there are no errors and the executable runs as well. When I insert the code into an SSIS package Script Task and copy/paste my code in I'm getting an error in one of my functions:
'Any' is not a member of 'System.Collections.Generic.IEnumerable(Of String)'.
I copied and pasted the main body of the code exactly and inserted one Imports line:
#Region "Imports"
Imports System
Imports System.Data
Imports System.Math
Imports System.IO 'Added this one Imports
Imports Microsoft.SqlServer.Dts.Runtime
#End Region
<Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute()> _
<System.CLSCompliantAttribute(False)> _
Partial Public Class ScriptMain
Inherits Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
Public Sub Main()
Dim sDirectoryRoot As String = "\\Server\Drive$\SubFolder\SubFolder2\"
Dim dirList As New DirectoryInfo(sDirectoryRoot)
ListFiles(dirList)
Dts.TaskResult = ScriptResults.Success 'left this line from SSIS default
End Sub
Public Sub ListFiles(ByVal dirList As DirectoryInfo)
Dim bEmpty As Boolean = False
[...] bunch of code with no errors. Actual function call below where clientdir is a directory path
bEmpty = IsDirectoryEmpty(clientdir.ToString)
End Sub
Public Function IsDirectoryEmpty(ByVal path As String) As Boolean
Return Not (Directory.EnumerateFileSystemEntries(path).Any())
End Function
The Directory.EnumerateFileSystemEntries(path).Any is underlined with the 'Any' is not a member of 'System.Collections.Generic.IEnumerable(Of String)' error. I can't figure out why it runs fine in Visual Studio, but when I use the Edit Script button in the Script Task Editor (which starts another instance of Visual Studio) it errors out.
Any is an extension method and, as with all extension methods, requires that you import the appropriate namespace. It is, in fact, the System.Linq.Enumerable.Any method, hence you must import the System.Linq namespace. That's probably done at the project level by default in your non-SSIS project. Note that you will also have to have referenced the System.Core.dll assembly.

How do I check if the attachment variable is empty before adding it to mail message?

I have managed to send email from my SSIS package using the script task with VB.NET code. I am not good at scripting, I basically looked at various scripts online to get me to where I am. The problem I have is that I have set up all my variables in my SSIS package in BIDS and I have set them to ReadOnly in my package.
Everything works fine if I specify a value for my Attachment package variable but if I don't, then my script fails. I don't always want to send an attached file when I send an email with my script. I would like the code to be modified so that if there is no value specified for my Attachement variable in my SSIS package in BIDS then my script task will only send the message in the body and not fail.
Also if possible when, attachments are sent would like to be able to send multiple attachments. I have also realised that now that I have set up my script as it seems that I no longer need the the SendMail Task in SSIS everything works just from the script and my variables set in SSIS.
Shouldn't I be able to connect the Script Task to the Send Mail Task to make them work together?
Here is my Script Task code:
Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
Imports System.Net.Mail
Imports System.Net
<System.AddIn.AddIn("ScriptMain", Version:="1.0", Publisher:="", Description:="")> _
<System.CLSCompliantAttribute(False)> _
Partial Public Class ScriptMain
Inherits Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
Enum ScriptResults
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
End Enum
Public Sub Main()
MsgBox(Dts.Variables("Username").Value.ToString)
Dim myHtmlMessage As MailMessage
Dim mySmtpClient As SmtpClient
Dim mailAuthentication As System.Net.NetworkCredential
mailAuthentication = New System.Net.NetworkCredential( _
Dts.Variables("Username").Value.ToString(), _
Dts.Variables("Password").Value.ToString())
myHtmlMessage = New MailMessage( _
Dts.Variables("From").Value.ToString(), _
Dts.Variables("To").Value.ToString(), _
Dts.Variables("Subject").Value.ToString(), _
Dts.Variables("Body").Value.ToString())
myHtmlMessage.Attachments.Add(New Attachment(Dts.Variables("Attachments").Value.ToString))
mySmtpClient = New SmtpClient(Dts.Variables("SMTPServer").Value.ToString(), Dts.Variables("Port").Value.ToString())
mySmtpClient.UseDefaultCredentials = False
mySmtpClient.Credentials = mailAuthentication
mySmtpClient.EnableSsl = True
mySmtpClient.Send(myHtmlMessage)
Dts.TaskResult = ScriptResults.Success
End Sub
End Class
Logic to check the variable before adding the value to mail attachment
Change the following line in your script to check if the value in variable Attachments is not empty using the function String.IsNullOrEmpty.
It is always a good practice to prefix the scope of the variable like User:: or System:: when using package variables inside the Script Task.
To add one more condition, you can check if the file actually exists in the specified path using function System.IO.File.Exists before adding it to the mail attachment.
From:
myHtmlMessage.Attachments.Add(New Attachment(Dts.Variables("Attachments").Value.ToString))
To:
Dim attachment As String = Dts.Variables("User::Attachments").Value.ToString()
If Not String.IsNullOrEmpty(attachment) Then
If System.IO.File.Exists(attachment) Then
myHtmlMessage.Attachments.Add(New Attachment(attachment))
End If
End If
"Shouldn't I be able to connect the Script Task to the Send Mail Task to make them work together?"
You can make the Send Email Task dynamic by using the Expressions (third tab). Expression allow you to make anything in an SSIS package behave differently based on values. As you can see, most any property you'd need to modify is exposed in the drop down list.

How do you run a bat file and a custom cmd file from vb resources?

I'm trying to run a batch file with a cmd file I have in my resources. I'm not trying to extract them anywhere. I simply want to edit the bat command in the form and run it with the cmd file I have. Is this possible?
There's no way to run a .cmd or .bat file without saving it to disk first. It has to be there for cmd.exe to read and interpret. You'll have to save it to disk first and run it from there.
Once you save it, you can run it using System.Diagnostics.Process. From the link's VB.Net example:
Imports System
Imports System.Diagnostics
Imports System.ComponentModel
Namespace MyProcessSample
Class MyProcess
Public Shared Sub Main()
Dim myProcess As New Process()
Try ' Get the path that stores user documents.
myProcess.StartInfo.UseShellExecute = False
' You can start any process, HelloWorld is a do-nothing example.
myProcess.StartInfo.FileName = "C:\\HelloWorld.exe"
myProcess.StartInfo.CreateNoWindow = True
myProcess.Start()
' This code assumes the process you are starting will terminate itself.
' Given that is is started without a window so you cannot terminate it
' on the desktop, it must terminate itself or you can do it
' programmatically from this application using the Kill method.
Catch e As Exception
Console.WriteLine((e.Message))
End Try
End Sub 'Main
End Class
End Namespace