SSIS Script Task (Not working when Scheduled) - sql-server

I have as SSIS Package with a script task. The task works great in Visual Studio 2015. However when I deploy the package and run it via SSMS the task script shows sucessful, but it runs extremely quickly and the file is not created. My code is farily simple (Grabs a file from a url, and saves it to a network location)
Public Sub Main()
Dim url, destination As String
destination = Dts.Variables("StagingPath").Value.ToString + Dts.Variables("DeliveryFile").Value.ToString
url = Dts.Variables("ReportURL").Value.ToString
'Delete staging file if it exists
Try
If IO.File.Exists(destination) Then IO.File.Delete(destination)
Dim result As Boolean = SaveFile(url, destination)
If result = True Then
Dts.TaskResult = ScriptResults.Success
Else
Dts.TaskResult = ScriptResults.Failure
End If
Catch ex As Exception
Dts.TaskResult = ScriptResults.Failure
End Try
End Sub
Protected Function SaveFile(ByVal url As String, ByVal localpath As String) As Boolean
Dim loRequest As System.Net.HttpWebRequest
Dim loResponse As System.Net.HttpWebResponse
Dim loResponseStream As System.IO.Stream
Dim loFileStream As New System.IO.FileStream(localpath, System.IO.FileMode.Create, System.IO.FileAccess.Write)
Dim laBytes(256) As Byte
Dim liCount As Integer = 1
Try
loRequest = CType(System.Net.WebRequest.Create(url), System.Net.HttpWebRequest)
loRequest.Credentials = System.Net.CredentialCache.DefaultCredentials
loRequest.Timeout = 600000
loRequest.Method = "GET"
loResponse = CType(loRequest.GetResponse, System.Net.HttpWebResponse)
loResponseStream = loResponse.GetResponseStream
Do While liCount > 0
liCount = loResponseStream.Read(laBytes, 0, 256)
loFileStream.Write(laBytes, 0, liCount)
Loop
loFileStream.Flush()
loFileStream.Close()
'Success
SaveFile = True
Catch ex As Exception
SaveFile = False
End Try
End Function
Like I said, everything is fine when run locally but not when deployed to SSISDB Catalog. The url passed is to a local resource on our SSRS Server, that is a pdf file.

The solution was to deploy the whole project whenever I had a change to the script task, or the script task will not even attempt to run but reports as running sucessfully.

Related

SSIS Script Task - how accept wildcard files in VB.net

I have this SSIS script task code copied from a site. I'm trying to avoid FTP failed error when the folder is empty. Does not need to a specific name file. The code below is for specific filename. How to make the filename a wildcard?
Public Sub Main()
Dim StrFolderArrary As String()
Dim StrFileArray As String()
Dim fileName As String
Dim RemoteDirectory As String
RemoteDirectory = Dts.Variables("User::RemoteFolder").Value.ToString()
Dim cm As ConnectionManager = Dts.Connections("FTPConnection") 'FTP connection manager name
Dim ftp As FtpClientConnection = New FtpClientConnection(cm.AcquireConnection(Nothing))
ftp.Connect() 'Connecting to FTP Server
ftp.SetWorkingDirectory(RemoteDirectory) 'Provide the Directory on which you are working on FTP Server
ftp.GetListing(StrFolderArrary, StrFileArray) 'Get all the files and Folders List
'If there is no file in the folder, strFile Arry will contain nothing, so close the connection.
If StrFileArray Is Nothing Then
MessageBox.Show(Dts.Variables("User::Flag").Value.ToString())
ftp.Close()
Dts.Variables("User::Flag").Value = 0
'If Files are there, Loop through the StrFileArray arrary and insert into table
Else
For Each fileName In StrFileArray
MessageBox.Show(fileName)
If fileName = Dts.Variables("User::FileName").Value.ToString() Then
Dts.Variables("User::Flag").Value = 1
MessageBox.Show(Dts.Variables("User::Flag").Value.ToString())
End If
Next
ftp.Close()
End If
' Add your code here
'
Dts.TaskResult = ScriptResults.Success
End Sub
first it is better to add the following Validation to the If statment:
If StrFileArray Is Nothing OrElse _
StrFileArray.length = 0 Then
Filter using Linq (need to import System.Linq)
If StrFileArray.Where(Function(x) x.equals(Dts.Variables("User::FileName").Value)).ToList().Count() > 0 Then
Dts.Variables("User::Flag").Value = 1
End If
UPDATE `
After reading your comment
If StrFileArray.Where(Function(x) x.StartsWith("Abc") AndAlso x.EndsWith(".txt")).ToList().Count() > 0 Then
Dts.Variables("User::Flag").Value = 1
End If

Trying to use a VB Script in an SSIS package to get the Server name from a connection

I'm writing an SSIS package that uses VB Scripts to send several confirmation emails. One of the confirmation emails needs to have the name of the server from one of the connection managers. I have a script doing the following:
Public Sub Main()
'------------- Set Vriables
Dim htmlMessageTo As String = _
Dts.Variables("Email_To").Value.ToString
Dim htmlMessageCC As String = _
Dts.Variables("Email_CC").Value.ToString
Dim htmlMessageFrom As String = _
Dts.Variables("Email_From").Value.ToString
Dim ServerAConnectionString As String = _
DirectCast(Dts.Connections("ServerA").AcquireConnection(Dts.Transaction), String)
Dim smtpConnectionString As String = _
DirectCast(Dts.Connections("Mail1").AcquireConnection(Dts.Transaction), String)
Dim smtpServerStr As String = _
smtpConnectionString.Split(New Char() {"="c, ";"c})(1)
Dim smtpServer As New SmtpClient(smtpServerStr)
Dim myMail As New MailMessage
With myMail
.From = New MailAddress(htmlMessageFrom)
.To.Add(htmlMessageTo)
If Len(htmlMessageCC) > 0 Then
.CC.Add(htmlMessageCC)
End If
.IsBodyHtml = True
.Subject = "The process failed for server " & ServerAConnectionString
.Body = "The process failed for server " & ServerAConnectionString
End With
smtpServer.Send(myMail)
Dts.TaskResult = ScriptResults.Success
End Sub
Where I'm trying to get just the server name of ServerA. And the connection manager Mail1 is the SMTP server I'm using. Everything is working fine for my other strings but this particular one gives me an error. I believe I can get the connection string but don't know enough VB to parse it. I'm hoping there is a way to get into the connection object and view the server name property, I just haven't been able to find it.
For ADO.NET connections:
Dim dbConn As System.Data.SqlClient.SqlConnection = Dts.Connections("ServerA").AcquireConnection(Dts.Transaction)
Dim dbServer As String = dbConn.DataSource
Dts.Events.FireInformation(-1, "", dbServer, String.Empty, -1, False)
It yields the following in the log:
[] Information: ServerName\InstanceName
OleDB connections are a bit trickier -- to access the same thing in a vb script, add a reference to the .NET assembly Microsoft.SqlServer.DTSRuntimeWrap, then use the following:
Dim connectionManager As ConnectionManager = Dts.Connections("oleDBConnection")
Dim cmParam As Microsoft.SqlServer.Dts.Runtime.Wrapper.IDTSConnectionManagerDatabaseParameters100
cmParam = CType(connectionManager.InnerObject, Wrapper.IDTSConnectionManagerDatabaseParameters100)
Dim conn As OleDb.OleDbConnection = CType(cmParam.GetConnectionForSchema(), OleDb.OleDbConnection)
Dts.Events.FireInformation(-1, "", conn.DataSource, String.Empty, -1, False)
Tested and verified reference: http://blogs.msdn.com/b/mattm/archive/2008/08/22/accessing-oledb-connection-managers-in-a-script.aspx

Unzip a zip file in silverlight

I am trying to develop code to unzip file from the zip file in Silverlight 5. The files are in a directory within the zip file.
I translated this code I found elsewhere from c# to VB since we are a VB shop. It is failing on the fourth line "Object reference not set to an instance of an object.".
I realize now that the problem is that the third line is expecting a relative uri and I am passing it a file, but I don't know how to fix this.
Can you tell me what is wrong with this code. I will also welcome other ideas.
Thanks.
Public Shared Function GetZipContents(ByVal filename As String) As String()
Try
Dim zipStream As System.IO.Stream = New System.IO.MemoryStream()
Dim zipInfo As New StreamResourceInfo(zipStream, Nothing)
Dim streamInfo As StreamResourceInfo = Application.GetResourceStream(zipInfo, New Uri(filename, UriKind.Relative))
Dim fileStream As Stream = streamInfo.Stream
Dim names As New List(Of String)()
Dim reader As New BinaryReader(fileStream)
Do While reader.ReadUInt32() = &H4034B50
' Skip the portions of the header we don't care about
reader.BaseStream.Seek(14, SeekOrigin.Current)
Dim compressedSize As UInteger = reader.ReadUInt32()
Dim uncompressedSize As UInteger = reader.ReadUInt32()
Dim nameLength As Integer = reader.ReadUInt16()
Dim extraLength As Integer = reader.ReadUInt16()
Dim nameBytes() As Byte = reader.ReadBytes(nameLength)
names.Add(Encoding.UTF8.GetString(nameBytes, 0, nameLength))
reader.BaseStream.Seek(extraLength + compressedSize, SeekOrigin.Current)
Loop
' Move the stream back to the begining
fileStream.Seek(0, SeekOrigin.Begin)
Return names.ToArray()
Catch ex As Exception
MessageBox.Show(ex.Message)
Return Nothing
End Try
End Function
There is quick and dirty way to unzip in Silverlight.
Use Application.GetResourceStream Method.
http://msdn.microsoft.com/en-us/library/cc190632(v=vs.95).aspx
Check out my blogpost on this: http://www.sharpgis.net/post/2010/08/25/REALLY-small-unzip-utility-for-Silverlight-e28093-Part-2.aspx
Sorry I would have time to explore the suggestions. I did find a way to accomplish my goal on my own. See the code below. I would be using this code either because the Technical Leader here prefers I do it a different way using a WCF service. Warning I was not able to test this code 100% since I am not planning to use it, but it is close to being right.
Imports ICSharpCode.SharpZipLib.Zip
Public Shared Sub UnZip(ByVal SrcFile As String, ByVal DstFile As String, ByVal BufferSize As Integer)
Try
Dim _FileName As String
Dim _ZipEntry As ZipEntry
Dim _FileStreamOut As FileStream = Nothing
Dim _Done As Boolean = False
Dim _FileStreamIn As New FileStream(SrcFile, FileMode.Open, FileAccess.Read)
Dim _ZipInStream As New ZipInputStream(_FileStreamIn)
Do Until _Done = True
_ZipEntry = _ZipInStream.GetNextEntry()
If IsNothing(_ZipEntry) Then
_Done = True
Exit Do
End If
_FileName = DstFile & "\" & _ZipEntry.Name
_FileName = _FileName.Replace("/", "\")
If Right(_FileName, 1) = "\" Then
If Directory.Exists(_FileName) = False Then
Directory.CreateDirectory(_FileName)
End If
Else
_FileStreamOut = New FileStream(_FileName, FileMode.Create, FileAccess.Write)
Dim size As Integer
Dim buffer(BufferSize - 1) As Byte
Do
size = _ZipInStream.Read(buffer, 0, buffer.Length)
_FileStreamOut.Write(buffer, 0, size)
Loop While size > 0
End If
Loop
_ZipInStream.Close()
_FileStreamOut.Close()
_FileStreamIn.Close()
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
End Sub

Windows service on system startup behaves differently

I have a Windows service which inserts into a database whenever there is a change in data from an OPC Server(KepServer). The service inserts correctly when I manually start it from the Services Task Manager of Windows 7. But the service only inserts one row of data when starting up on system startup, whereas the desired number of rows must be 20. Because it is Windows Service, it is difficult to debug and it is not giving any error as well.
jjag
OS:Windows 7;
DB:SQL Server Express;
Win Service:run under Administrator
My code:
Protected Overrides Sub OnStart(ByVal args() As String)
' Add code here to start your service.
'Create a new OPC Server object
ConnectedOPCServer = New OPCServer
ConnectedOPCServer.Connect("KEPware.KEPServerEx.V5")
Try
' Add the group and set its update rate
ConnectedServerGroups = ConnectedOPCServer.OPCGroups
ConnectedGroup = ConnectedServerGroups.Add("Test1")
Catch ex As Exception
' Error handling
End Try
' Set the update rate for the group
ConnectedGroup.UpdateRate = 400
' Subscribe the group so that you will be able to get the data change
' callbacks from the server
ConnectedGroup.IsSubscribed = True
ItemCount = 3
OPCItemIDs(1) = "Channel2.Device1.EndDate"
OPCItemIDs(2) = "Channel2.Device1.Material"
OPCItemIDs(3) = "Channel2.Device1.BatchSchedule"
ClientHandles(1) = 1
ClientHandles(2) = 2
ClientHandles(3) = 3
Try
' Establish a connection to the OPC item interface of the connected group
OPCItemCollection = ConnectedGroup.OPCItems
OPCItemCollection.DefaultIsActive = True
OPCItemCollection.AddItems(ItemCount, OPCItemIDs, ClientHandles, ItemServerHandles, ItemServerErrors)
Catch ex As Exception
' Error handling
End Try
EventLog1.WriteEntry("In OnStart")
End Sub
Public Sub ConnectedGroup_DataChange(ByVal TransactionID As Integer, ByVal NumItems As Integer, ByRef ClientHandles As System.Array, ByRef ItemValues As System.Array, ByRef Qualities As System.Array, ByRef TimeStamps As System.Array) Handles ConnectedGroup.DataChange
'This is my sub which inserts into database in the event of data change from OPC Server
Const NoOfItems = 3
Dim ObjOPCItem As OPCAutomation.OPCItem
Dim Array_Values(NoOfItems) As Object
For Each ObjOPCItem In OPCItemCollection
Array_Values(ObjOPCItem.ClientHandle) = ObjOPCItem.Value
Next
ObjOPCItem = Nothing
Dim sql As String
sql = "INSERT INTO BatchReport (BatchCode,BatchNumber)VALUES(#AV,#AVa);"
If Array_Values(3) < 20 Then
Try
connection.Open()
dataadapter.InsertCommand = New SqlCommand(sql, connection)
dataadapter.InsertCommand.Parameters.Add("#AV", SqlDbType.Int, 4).Value = Array_Values(1)
dataadapter.InsertCommand.Parameters.Add("#AVa", SqlDbType.Int, 4).Value = Array_Values(3)
dataadapter.InsertCommand.ExecuteNonQuery()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
connection.Close()
End If
End Sub

Upload Progressbar with FtpWebRequest

I have a program that uploads files to our server when they are dropped over the form, to make it easy for our customers to get large files to us.
I have it mostly working, but I want to have a progress bar so that the user knows it's working, instead of having it just sit there for 5 minutes while the files upload quietly in the background.
I would be happy to just have the progress bar pulse so it looks the program is working, and not frozen. If I can show actual status then that would be better.
My code:
Private Sub Grid1_Drop(sender As System.Object, e As System.Windows.DragEventArgs) Handles Grid1.Drop
Dim sFileInfo As System.IO.FileInfo
Dim sStatus As String = ""
If e.Data.GetDataPresent("FileDrop") Then
Try
Dim theFiles() As String = CType(e.Data.GetData("FileDrop", True), String())
For Each file As String In theFiles
sFileInfo = New System.IO.FileInfo(file)
If UploadFile(txtUsername.Text, sFileInfo) Then
lstFileList.Items.Add(file & " - Uploaded")
Else
lstFileList.Items.Add(file & " - Upload Failed")
End If
Next
Catch ex As Exception
MsgBox(ex.Message)
End Try
End If
End Sub
Public Function UploadFile(ByVal User As String, ByVal oFile As FileInfo) As Boolean
Dim ftpRequest As FtpWebRequest
Dim ftpResponse As FtpWebResponse
Try
ftpRequest = CType(FtpWebRequest.Create(Base + User + "/" + oFile.Name), FtpWebRequest)
ftpRequest.Method = WebRequestMethods.Ftp.UploadFile
ftpRequest.Proxy = Nothing
ftpRequest.UseBinary = True
ftpRequest.Credentials = Cred
ftpRequest.KeepAlive = KeepAlive
ftpRequest.EnableSsl = UseSSL
If UseSSL Then ServicePointManager.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf ValidateServerCertificate)
Dim fileContents(oFile.Length) As Byte
Using fr As FileStream = oFile.OpenRead
fr.Read(fileContents, 0, Convert.ToInt32(oFile.Length))
End Using
Using writer As Stream = ftpRequest.GetRequestStream
writer.Write(fileContents, 0, fileContents.Length)
End Using
ftpResponse = CType(ftpRequest.GetResponse, FtpWebResponse)
ftpResponse.Close()
ftpRequest = Nothing
Return True
Catch ex As WebException
Return False
End Try
End Function
Have a look at the background worker class. http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx which will free up your ui so you can add in a progress bar control and have it animate while your files are being uploaded

Resources