SSIS Script task that FTP's files
-
Thursday, February 22, 2007 3:44 PM
I could not find the exact details on how to create a SSIS script that would ftp files on these forums, so I am adding my code to help save time for anyone else that might be wanting to do something similar. Here is the VB code for my script task to FTP files (hope this helps someone):
' 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
SystemImports
System.DataImports
System.MathImports
Microsoft.SqlServer.Dts.RuntimePublic
Class ScriptMain Public Sub Main() Try 'Create the connection to the ftp server Dim cm As ConnectionManager = Dts.Connections.Add("FTP") 'Set the properties like username & passwordcm.Properties(
"ServerName").SetValue(cm, "Enter your Server Name here")cm.Properties(
"ServerUserName").SetValue(cm, "Enter your FTP User Name here")cm.Properties(
"ServerPassword").SetValue(cm, "Enter your FTP Password here")cm.Properties(
"ServerPort").SetValue(cm, "21")cm.Properties(
"Timeout").SetValue(cm, "0") 'The 0 setting will make it not timeoutcm.Properties(
"ChunkSize").SetValue(cm, "1000") '1000 kbcm.Properties(
"Retries").SetValue(cm, "1") 'create the FTP object that sends the files and pass it the connection created above. Dim ftp As FtpClientConnection = New FtpClientConnection(cm.AcquireConnection(Nothing)) 'Connects to the ftp serverftp.Connect()
'Build a array of all the file names that is going to be FTP'ed (in this case only one file) Dim files(0) As Stringfiles(0) =
"Drive:\FullPath\YourFileName" 'ftp the file 'Note: I had a hard time finding the remote path directory. I found it by mistake by creating both the FTP connection and task in the SSIS package and it defaulted the remote path setting in the FTP task.ftp.SendFiles(files,
"/Enter Your Remote Path", True, False) ' the True makes it overwrite existing file and False is saying that it is not transferring ASCIIftp.Close()
Catch ex As ExceptionDts.TaskResult = Dts.Results.Failure
End TryDts.TaskResult = Dts.Results.Success
End SubEnd
Class
All Replies
-
Tuesday, July 03, 2007 4:30 PM
Matthew,
this was very very helpful. I could not get the FTP task to delete a remote file for the life of me. I used your script above and just modified the ftp.SendFiles to ftp.DeleteFiles and it worked like a charm.
Thanks,
S
-
Friday, July 20, 2007 10:11 AM
This is extremely useful.
ftp.SendFiles(files, "", True, False)
I just used a blank in the remote path, and it works, it does'nt work with any slashes.
Thanks so much, this got my code working. There is probably a bug in the FTP componenet in SSIS.
-
Friday, July 20, 2007 11:08 AM
Thanks for your code.. It's very helpful..
-
Tuesday, July 31, 2007 2:49 PM
Thanks so much for your post!
However, I cannot get the modified script below to delete all of the files on the FTP server. I would like to delete all of the files on the server. The file names begin like "romps.dat." and has a final extension like "192". So, an example of a file on the server is "romps.dat.192"
If I explicitly state the file name, it works great, but for some reason I cannot get it to delete anything when I insert the wildcard. I've tried it with only one file and with multiple files.
'Connects to the ftp server
'Build a array of all the file names that is going to be FTP'ed
Dim files(0) As String
files(0) = "romps.dat.*"'ftp the files
Thanks in advance for your help!
Patrick -
Tuesday, July 31, 2007 2:50 PMModeratorMany FTP sites do not support wildcards.
-
Tuesday, July 31, 2007 2:53 PM
Any suggestions?
Thanks,
Patrick
-
Tuesday, July 31, 2007 3:06 PMModerator
Patrick Browder wrote: Any suggestions?
Thanks,
Patrick
Run a directory listing, load that up into an array, and then loop through that array (list, or whatever it's called in .Net world) to delete each file. -
Tuesday, July 31, 2007 4:07 PM
That helped. Here's the script if anyone's interested:
Dim ftp As FtpClientConnection = New FtpClientConnection(cm.AcquireConnection(Nothing))
'Connects to the ftp server
'Get file listing
Dim fileNames() As String
Dim folderNames() As String
ftp.GetListing(folderNames, fileNames)'ftp the files
Patrick
-
Friday, September 21, 2007 7:58 AM
Thanks for the code!
I noticed however that the example always returns success. To fix this the codeline
Dts.TaskResult = Dts.Results.Success
should be moved to the last row before the catch.
-
Saturday, September 22, 2007 4:33 AMl ran into an error exception at the ftp.Connect() when executing the code below which is almost exactly the same
Message = "Exception from HRESULT: 0xC001602A"
Try
'Create the connection to the ftp server
Dim cm As ConnectionManager = Dts.Connections.Add("FTP")
'Set the properties like username & password
cm.Properties("ServerName").SetValue(cm, "ftp.(5 char text).com")
cm.Properties("ServerUserName").SetValue(cm, "5 char text")
cm.Properties("ServerPassword").SetValue(cm, "5 char text")
cm.Properties("ServerPort").SetValue(cm, "21")
cm.Properties("Timeout").SetValue(cm, "0") 'The 0 setting will make it not timeout
cm.Properties("ChunkSize").SetValue(cm, "1000") '1000 kb
cm.Properties("Retries").SetValue(cm, "1")
'create the FTP object that sends the files and pass it the connection created above.
Dim ftp As FtpClientConnection = New FtpClientConnection(cm.AcquireConnection(Nothing))
'Connects to the ftp server
ftp.Connect() "EXCEPTION OCCUR HERE"
'Build a array of all the file names that is going to be FTP'ed (in this case only one file)
Dim files(0) As String
files(0) = "c:\tempfolder\1.xls"
'ftp the file
'Note: I had a hard time finding the remote path directory. I found it by mistake by creating both the FTP connection and task in the SSIS package and it defaulted the remote path setting in the FTP task.
ftp.SendFiles(files, "ftp.(5 char text).com/tempfolder", True, False) ' the True makes it overwrite existing file and False is saying that it is not transferring ASCII
ftp.Close()
Dts.TaskResult = Dts.Results.Success
Catch ex As Exception
Dts.TaskResult = Dts.Results.Failure
End Try
can anyone give me a hand please. Thx
Alex -
Saturday, September 22, 2007 10:54 PMFirst thank you for taking the time to read my post!
I have tried the code you provided here and i keep getting the following error:
[Connection manager "{3246C151-503C-4DE3-AFB6-54FF6D3820A7}"] Error: An error occurred in the requested FTP operation. Detailed error description: The connection with the server was reset .
This error occurs on the GetListing line. I preceded that line with a line to set the working directory and I received no errors.
Do you have any suggestions? -
Sunday, September 23, 2007 7:37 PMI ended up using an FTP class library found on the Code Project at - http://www.codeproject.com/cs/internet/ftpdriver1.asp?df=100&forumid=11325&exp=0&select=900150
This library was great for obtaining the directory listing and deleting files from a Unix server (does not work so well on a Windows box). However, the retrieval of files was much slower than the SSIS FTP connection.
Please note that you need to create your own solution and add the files from the Code Project website into that solution, You also need to sign your solution, add it to the GAC and copy your solution's DLL to the main C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 folder in order to reference it inside of the SSIS Script editor.
Here is the complete script I am using in case anybody else runs into this issue:
Imports Custom.FTP 'This is the Code Project class reference
Imports System
Imports System.Data
Imports System.IO
Imports System.Text
Imports Microsoft.SqlServer.Dts.Runtime
Public Class ScriptMain
' This class utilizes the FTP Class Library found by going to:
' http://www.codeproject.com/cs/internet/ftpdriver1.asp?df=100&forumid=11325&exp=0&select=900150
' in order to retireve a list of file names from a Unix FTP Server
' It then uses an SSIS FTP Connection for faster retrieval of the actual files
'NOTE: The Custom FTP class also successfully deletes files from a Unix server as well
Public Sub Main()
Dim fileNames() As String
Dim ftpConn As FtpConnection
Dts.TaskResult = Dts.Results.Success
Try
'Setup a custom FTP connection to Unix
ftpConn = FtpConnection.Create(Dts.Variables("ServerName").Value.ToString, _
Short.Parse(Dts.Variables("ServerPort").Value.ToString), Console.Out, Console.Out, _
Dts.Variables("FTPUser").Value.ToString, Dts.Variables("FTPPassword").Value.ToString)
'Next we need to setup a directory link to the site
Dim directoryList As DirectoryList = New PassiveDirectoryList(ftpConn)
'Now we retrieve the directory listing which comes back in a byte array:
Dim sbClientFeedback As New StringBuilder()
Dim sbServerFeedback As New StringBuilder()
Dim clientOutput As New StringWriter(sbClientFeedback)
Dim serverOutput As New StringWriter(sbServerFeedback)
Dim rawDirectory() As Byte = directoryList.GetList(Nothing, clientOutput, serverOutput)
'Next we need to convert the binary to ASCII and convert the text into meaningful file nodes:
Dim textDirectory As String = System.Text.Encoding.ASCII.GetString(rawDirectory)
Dim fileNodes As UnixFileNode() = DirectCast(New UnixFileNode().FromFtpList(textDirectory, ftpConn.CurrentWorkingDirectory), UnixFileNode())
'Next we grab the relevant names out of the list and add them to a string collection:
ReDim fileNames(fileNodes.Length)
Dim intFileCounter As Int32 = 1
For Each fileNode As UnixFileNode In fileNodes
If fileNode.FullName.IndexOf(".xml.gz.lmp") > 0 Then
fileNames(intFileCounter) = fileNode.FullName.Replace(".lmp", "").Replace("/", "")
intFileCounter += 1
End If
Next
'Next we resize the array:
ReDim Preserve fileNames(intFileCounter - 1)
Catch ex As Exception
Dts.TaskResult = Dts.Results.Failure
Finally
'Now we close this connection as it is not the most efficient for retrieving files:
ftpConn.Close()
End Try
If Dts.TaskResult = Dts.Results.Success Then
Dim ssisFtp As FtpClientConnection
Try
'Now we create an SSIS connection for pulling the files:
Dim ssisConn As ConnectionManager = Dts.Connections.Add("FTP")
'Set the properties like username & password
Dim intRetries As Int32 = Int32.Parse(Dts.Variables("FtpRetry").Value.ToString)
ssisConn.Properties("ServerName").SetValue(ssisConn, Dts.Variables("ServerName").Value.ToString)
ssisConn.Properties("ServerUserName").SetValue(ssisConn, Dts.Variables("FTPUser").Value.ToString)
ssisConn.Properties("ServerPassword").SetValue(ssisConn, Dts.Variables("FTPPassword").Value.ToString)
ssisConn.Properties("ServerPort").SetValue(ssisConn, Dts.Variables("ServerPort").Value.ToString)
'The 0 setting will make it not timeout
ssisConn.Properties("Timeout").SetValue(ssisConn, Dts.Variables("TimeOut").Value.ToString)
ssisConn.Properties("ChunkSize").SetValue(ssisConn, Dts.Variables("ChunkSize").Value.ToString) '1000 kb
ssisConn.Properties("Retries").SetValue(ssisConn, intRetries.ToString)
'Next we create the FTP Connection
ssisFtp = New FtpClientConnection(ssisConn.AcquireConnection(Nothing))
'And we pass the modified file names in to retrieve the inflated files:
ssisFtp.Connect()
'Since the FTP connection seems to timeout with large files, we need to verify that all of the files downloaded
Dim requiredFiles() As String = VerifyFiles(fileNames, Dts.Variables("FtpDestination").Value.ToString)
Dim intCount As Int32 = 0
While (requiredFiles.Length > 0 OrElse (requiredFiles.Length = 1 AndAlso requiredFiles(0) <> "")) AndAlso intCount <= intRetries
ssisFtp.ReceiveFiles(requiredFiles, Dts.Variables("FtpDestination").Value.ToString, True, False)
requiredFiles = VerifyFiles(requiredFiles, Dts.Variables("FtpDestination").Value.ToString)
intCount += 1
End While
If intCount > intRetries AndAlso (requiredFiles.Length > 0 OrElse (requiredFiles.Length = 1 AndAlso requiredFiles(0) <> "")) Then
'We have to try to ask for each file seperately:
Dim singleFile(0) As String
For Each thisFile As String In requiredFiles
singleFile(0) = thisFile
ssisFtp.ReceiveFiles(singleFile, Dts.Variables("FtpDestination").Value.ToString, True, False)
Next
'We perform one final check and then throw an error or warning:
requiredFiles = VerifyFiles(requiredFiles, Dts.Variables("FtpDestination").Value.ToString)
If requiredFiles.Length > 0 OrElse (requiredFiles.Length = 1 AndAlso requiredFiles(0) <> "") Then
'In this FTP scenario, the files are all pointers to 0-byte files so I fire a warning:
Dts.Events.FireWarning(0, "Unix FTP Task", "The Following Did Not Transfer: " & String.Join(Environment.NewLine, requiredFiles), _
"", 0)
End If
End If
Catch ex As Exception
Dts.TaskResult = Dts.Results.Failure
Finally
' Finally we close the SSIS FTP Conection
ssisFtp.Close()
End Try
End If
End Sub
Public Function VerifyFiles(ByVal CurrentList As String(), ByVal TargetDirectory As String) As String()
Dim thisDir As New DirectoryInfo(TargetDirectory)
Dim sbFiles As New StringBuilder()
Dim haveFile As Boolean
For Each listItem As String In CurrentList
If listItem <> Nothing AndAlso listItem <> "" Then
haveFile = False
For Each downloadedFile As FileInfo In thisDir.GetFiles()
If downloadedFile.Name = listItem Then
haveFile = True
Exit For
End If
Next
If Not haveFile Then
sbFiles.Append(listItem + "|")
End If
End If
Next
Dim outputFiles() As String
If sbFiles.Length > 0 Then
outputFiles = sbFiles.ToString().Substring(0, sbFiles.Length - 1).Split("|".ToCharArray())
Else
ReDim outputFiles(1)
outputFiles(1) = ""
End If
Return outputFiles
End Function
End Class -
Thursday, February 28, 2008 4:33 PM
Thanks for the code. I'm trying to receive files from an ftp server. so I changed the code to receive files and it doesn't download anything. Am I missing something?
files(0) = filepath and name
ftp.ReceiveFiles(files, LocPath,
True, False) ' the True makes it overwrite existing file and False is saying that it is not transferring ASCII -
Saturday, March 15, 2008 9:59 PMSorry for the delay in getting back to you - notifications are not working for me. If you are connecting to a standard FTP site then use the FTP Task - this stuff really only works for non-Windows servers.
-
Thursday, May 15, 2008 8:45 PM
Does anybody know howto modify this code to use NVS DnsNameing convention when Ftping to a mainframe. My from file is Named C:\file1.txt my to file needs to be 'xxxx.xx.xxxx.CREATE.REQUEST(+1)' -
Thursday, July 31, 2008 6:42 PM
This looks like just what I need.
Could you please tell me the easiest way to execute the script within and SSIS dtsx package?
Would I need to create a full VS .NET project, or can i just paste this script into a (filename).cmd file and add to the command files properties of the package?
Thanks,
Paul
-
Tuesday, August 12, 2008 11:04 PM
I modified this to recieve a file from a mainframe to a directory on my PC. It looks as if it's successful, but it does not download the file. These were my modifications:
files(0) =
"'xxx.xxx.xxx.xxxx(0)'" 'ftp the fileftp.ReceiveFiles(files,
"C:\test\xxx.zip",True, False)I've tried the files(0) = to both with single quotes in the double quotes: "'xxx.xxx.xxx.xxxx(0)'" and without the single quotes: "xxx.xxx.xxx.xxxx(0)". In both cases it shows as if it executed successfully, but it doesn't do a thing. The file is there and I can download it using a bat program or directly through FTP.
Any suggestions would be much appreciated. Thanks
-
Wednesday, August 13, 2008 7:25 AMModerator
Viwaltzer wrote: I modified this to recieve a file from a mainframe to a directory on my PC. It looks as if it's successful, but it does not download the file. These were my modifications:
files(0) =
"'xxx.xxx.xxx.xxxx(0)'" 'ftp the fileftp.ReceiveFiles(files,
"C:\test\xxx.zip",True, False)I've tried the files(0) = to both with single quotes in the double quotes: "'xxx.xxx.xxx.xxxx(0)'" and without the single quotes: "xxx.xxx.xxx.xxxx(0)". In both cases it shows as if it executed successfully, but it doesn't do a thing. The file is there and I can download it using a bat program or directly through FTP.
Any suggestions would be much appreciated. Thanks
it might behoove you to use the execute process task for ftp'ing.
hth
-
Thursday, October 23, 2008 10:02 AM
Thanks! Works great :-) -
Monday, November 03, 2008 2:50 PM
Hi,
Is anyone still following this thread?
I have a similar issue. The FTP Task in SSIS 2005 can connect to an AS/400 FTP Server, and it can list the files needed, but the file names are cryptic, and fail. Here is the listing:
FC003 3166662 10/31/08 19:46:53 *STMF BSWAF20081030.TXT
FC003 3256877 10/30/08 17:42:52 *STMF BSWAF20081029.TXT
FC003 3165556 10/29/08 19:43:53 *STMF BSWAF20081028.TXT
...
When I put the whole "filename" as shown above, I get a 550 error - Specified directory does not exist.
When I only key the BSWAF20081030.TXT file name, I get the same error.
I am able to FTP GET this file from the FTP Client that comes with Windows XP.
Thoughts?
Bob
-
Saturday, November 15, 2008 12:49 PM
Hello, hello, Steve B.? Are you there?
Can you help? It appears that IBM and Microsoft are not talking about this issue between the IBM FTP Server and the SSIS FTP Client. They don't like each other I guess. That leaves poor little developers like me out in the cold.
See the prior question. I work for an important Microsoft Client, and I am looking bad because I cannot get the FTP connectors to work properly for the AS/400 FTP Server.
Anyone?
Bobby T
-
Saturday, November 15, 2008 5:23 PMModerator
Bobby T. wrote: Hello, hello, Steve B.? Are you there?
Can you help? It appears that IBM and Microsoft are not talking about this issue between the IBM FTP Server and the SSIS FTP Client. They don't like each other I guess. That leaves poor little developers like me out in the cold.
See the prior question. I work for an important Microsoft Client, and I am looking bad because I cannot get the FTP connectors to work properly for the AS/400 FTP Server.
Anyone?
Bobby T
if you can ftp to AS/400 using a third-party console application, then you can use the execute process task to do it for you.
hth
-
Monday, November 17, 2008 1:28 PMHave you tried SSIS+ library?
-
Tuesday, December 02, 2008 9:29 PMI created two tasks to ftp the same file. One using the code sample posted here and the other using an FTP task. The code sample ran 5 times faster than the FTP task. No idea why, but needless to say I'll be coding the FTP process from now on.
-
Wednesday, December 03, 2008 7:30 PM
Hi Matthew,
Thanks for sharing the code snippet. I was looking for a solution to avoid a CWD/CD command that is inherent in the FTP Task and your script did the trick.
Is there a way to get file listing from FTP sites based on a pattern ("*2008.DAT")?
The listing method pulls back an array of folders and files but does not let the user to specify any options.
Thanks again,
V
-
Wednesday, January 21, 2009 3:10 AMYou legend - I've been looking for 2 days to see if there's a way I could replicate the ftp -s command (where I can pass a script into the ftp command). This is going to save me a LOT of time. Thanks
niall -
Wednesday, February 11, 2009 5:37 AMhi all,.
the said code was helpfull. as i am novice so it was v.helpfull 2me.
My needs are..
I have to load the bak files to the ftp server. the file name should be in format of
backup_[YYYY][MM][DD][HH][MM]YYYY – Four digit year
MM- 2 digit Month
DD – 2 digit Date
HH – Constant at “23” - This is because the backup happens every night at 23:30
MM – Constant at “30” – This is because the backup happens every night at 23:30
their would be multiple file in folder. and the folder location and credential will comes from db.
tasks.
1. check the file name and its validation
2. check most updated files in local directory (these most-updated files will load to the ftp server)
3. If Updated files are not available then Setp 1 will run again after every 30 min
4. If file are available then these file should be removed from the local directory, after uploading
Reply me asap
please. -
Wednesday, February 25, 2009 3:36 PMAlex,
Did you every find the cause to the exception during the .Connect call? I have the same problem. -
Monday, April 27, 2009 8:39 AMHiWe've got an SSIS task that FTPs up to a windows server (not sure if its 2005 or 2008, but I suspect the latter).We're using basically the same script as the first post in this thread, but when we call the SendFiles method we get error code 0xC001602A with no message.At first we obviously assumed that the whole send was failing but it looks like the actual action is succceeding, but it is still reporting an error?Any help much appreciatedMany ThanksMark Middlemist
-
Monday, May 11, 2009 8:06 AMHi AgainJust a little follow-upWe haven't as yet got this fixed but the one thing I should add is that it is actually carrying out the action, whether it be creating/overwriting or deleting a file, but it is still reporting the error. Any thoughts anyone?Many thanks in advance for any helpMark Middlemist
-
Wednesday, June 17, 2009 4:37 PM
Hello Patrick,
I am having real trouble with deleting files within a FTP server....I used the above code snippet from Mathew to delete files and it worked absolutely fine and then i stumbled across another problm of deleting files having date extn in it.I reckon script task doesn't quite support wildcards and hence cant use filename*.csv to delete files.
I then used ur code
ftp.Connect()
'Get file listing
Dim fileNames() As String
Dim folderNames() As String
ftp.GetListing(folderNames, fileNames)
'ftp the files
ftp.DeleteFiles(fileNames)
And it deleted all the files from the FTP directory.......is there anyway I can use ur code snippet and delete a file like filename_170609.csv (today's file with today's date extn)...
Thanks a bunch ! Sweta -
Monday, July 20, 2009 7:01 PM
- Edited by DayHappy Monday, July 20, 2009 7:03 PM
-
Friday, February 12, 2010 3:43 PMHi Matthew,
I tried the above and put messageboxes in the code and it was showing the FTP connection was established but file is not written on Mainfrmae. any clue?
Thanks,
Srinivas -
Friday, February 26, 2010 1:30 PM
HI,
I have used the same code in script task, tested the connection successfully. Bu when i sned the files, script task remains in execution mode (yellow).
i tried remote location with blank also "".
Please help me to solve this issue.
Public Sub Main() Dim success As Boolean Try 'Create the connection to the ftp server Dim cm As ConnectionManager = Dts.Connections.Add("FTP") 'Set the properties like username & password cm.Properties("ServerName").SetValue(cm, "XXXXXXXXXXXXXXXX") cm.Properties("ServerUserName").SetValue(cm, "XXXXXXX") cm.Properties("ServerPassword").SetValue(cm, "XXXXXX") cm.Properties("ServerPort").SetValue(cm, "21") cm.Properties("Timeout").SetValue(cm, "0") 'The 0 setting will make it not timeout cm.Properties("ChunkSize").SetValue(cm, "1000") '1000 kb cm.Properties("Retries").SetValue(cm, "1") 'create the FTP object that sends the files and pass it the connection created above. Dim ftp As FtpClientConnection = New FtpClientConnection(cm.AcquireConnection(Nothing)) 'Connects to the ftp server ftp.Connect() success = ftp.Connect() If (success = True) Then 'Build a array of all the file names that is going to be FTP'ed (in this case only one file) Dim files(0) As String '= "\\S-SQL16\IPM Source Data\DataAcademySource\ADDRESS_ROLES.csv" files(0) = "\\S-SQL16\IPM Source Data\DataAcademySource\ADDRESS_ROLES.csv" 'Dim remotePath As String = "/" 'ftp the file 'Note: I had a hard time finding the remote path directory. I found it by mistake by creating both the FTP connection and task in the SSIS package and it defaulted the remote path setting in the FTP task. ftp.SendFiles(files, "\", True, False) ' the True makes it overwrite existing file and False is saying that it is not transferring ASCII Dts.TaskResult = Dts.Results.Success Else Dts.Events.FireError(0, "ScripTask", _ "Connection Failed", String.Empty, 0) End If ftp.Close() Catch ex As Exception Dts.TaskResult = Dts.Results.Failure End Try End Sub End Class -
Friday, February 26, 2010 5:03 PMHi,
try this
public void Main()
{
string serverName = Dts.Variables["User::FTPServerName"].Value.ToString();
string remotepath = Dts.Variables["User::FTPDestinationPath"].Value.ToString();
string userID = Dts.Variables["User::FTPUserID"].Value.ToString();
string password = Dts.Variables["User::FTPPassword"].Value.ToString();
string sourcePath = Dts.Variables["User::SourcePath"].Value.ToString();
try
{
string Result = FtpPut(serverName, userID, password,sourcePath, remotepath);
Dts.TaskResult = (int)ScriptResults.Success;
}
catch(Exception)
{
Dts.TaskResult = (int)ScriptResults.Failure;
}
}
private string FtpPut(string serverName, string userID, string password, string sourcePath, string destinationPath)
{
string result = string.Empty;
string sourceFile = Path.Combine(sourcePath, "StagingData.txt");
string batchFilePath = Path.Combine(sourcePath, "FTPBatch.txt");
StringBuilder sb = new StringBuilder();
sb.Append("open " + serverName + Environment.NewLine);
sb.Append(userID + Environment.NewLine);
sb.Append(password + Environment.NewLine);
sb.Append("ascii" + Environment.NewLine);
sb.Append("quote site conddisp=delete cylinders primary=30 secondary=20 recfm=fb" + Environment.NewLine);
sb.Append("quote site lrecl=1000" + Environment.NewLine);
sb.Append("put ");
sb.Append("\"");
sb.Append(sourceFile);
sb.Append("\"");
sb.Append(" '" + destinationPath + "'" + Environment.NewLine);
sb.Append("close" + Environment.NewLine);
sb.Append("bye" + Environment.NewLine);
string realBatchText = sb.ToString();
//create the batch file.
byte[] realBatchTextBytes = new UTF8Encoding(false, true).GetBytes(realBatchText);
using (Stream writer = new FileStream(batchFilePath, FileMode.Create, FileAccess.Write, FileShare.None))
{
writer.Write(realBatchTextBytes, 0, realBatchTextBytes.Length);
}
//Process Info to FTP and run Batch File created
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.Arguments = string.Format("-s:\"{0}\"", batchFilePath);
startInfo.FileName = "ftp.exe";
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.RedirectStandardOutput = true;
//Start Process
using (Process process = new Process())
{
process.StartInfo = startInfo;
process.Start();
result = process.StandardOutput.ReadToEnd().ToString();
process.Close();
}
File.Delete(batchFilePath);
return result;
}
}
}
-
Friday, February 26, 2010 5:21 PM
Hello,
I am using SQl server 2005, i can use only VB.NET -
Friday, February 26, 2010 6:13 PM
This is the function converted from C# to VB.net. hope this will be helpfulPrivate Function FtpPut(ByVal serverName As String, ByVal userID As String, ByVal password As String, ByVal sourcePath As String, ByVal destinationPath As String) As String
Dim result As String = String.Empty
Dim sourceFile As String = Path.Combine(sourcePath, "StagingData.txt")
Dim batchFilePath As String = Path.Combine(sourcePath, "FTPBatch.txt")
Dim sb As StringBuilder = New StringBuilder()
sb.Append("open " + serverName + Environment.NewLine)
sb.Append(userID + Environment.NewLine)
sb.Append(password + Environment.NewLine)
sb.Append("ascii" + Environment.NewLine)
sb.Append("quote site conddisp=delete cylinders primary=30 secondary=20 recfm=fb" + Environment.NewLine)
sb.Append("quote site lrecl=1000" + Environment.NewLine)
sb.Append("put ")
sb.Append("""" + sourceFile + """")
sb.Append(" '" + destinationPath + "'" + Environment.NewLine)
sb.Append("close" + Environment.NewLine)
sb.Append("bye" + Environment.NewLine)
Dim realBatchText As String = sb.ToString()
'create the batch file.
Dim realBatchTextBytes As Byte() = New UTF8Encoding(False, True).GetBytes(realBatchText)
Using writer As Stream = New FileStream(batchFilePath, FileMode.Create, FileAccess.Write, FileShare.None)
writer.Write(realBatchTextBytes, 0, realBatchTextBytes.Length)
End Using
'Process Info to FTP and run Batch File created
Dim process As New Process
With process
With .StartInfo
.FileName = "ftp.exe"
.Arguments = String.Format("-s:\"" + batchFilePath + """)
.CreateNoWindow = True
.UseShellExecute = False
.WindowStyle = ProcessWindowStyle.Hidden
.RedirectStandardOutput = True
End With
.Start()
result = .StandardOutput.ReadToEnd().ToString()
.Close()
End With
File.Delete(batchFilePath)
Return result
End Function
Thanks,
Srinivas -
Tuesday, March 09, 2010 6:08 PMYou could use the SSIS FTP Task++ from eaSkills. It has wildcard support and SFTP capabilities and it's free.
-
Tuesday, March 09, 2010 6:11 PMTry the SSIS FTP Task++ from eaSkills. It works for me using a Unix FTP Server and it's free.
-
Friday, April 16, 2010 2:53 AM
hello Mark, I just had the same as you had.... still working on solving the problem... I suspect that has something to do with VISTA.... my SSIS FTP package was working good in XP... I just have my OS changed to VISTA last week and noticed this problem today...
Did you find out any thing with your problem ?
Thanks
kythanh
-
Thursday, April 22, 2010 4:08 PMwhn i use this code its getting an error saying "dts is not declared"
-
Wednesday, July 07, 2010 9:36 PM
Hi,
I believe there may be a bug in the ftp.SendFiles command. In my case, if the file already exists on the server, the command throws error "System.Runtime.InteropServices.COMException (0xC001602A): Exception from HRESULT: 0xC001602A" This happens even though I have the overwrite property set to True. The only workaround I've been able to find for this is to first delete the file using ftp.DeleteFiles, then call ftp.SendFiles.
I'm running SQL Server 2008 (10.0.2531) on Windows Server 2008 R2 and my SSIS package is coded in Visual Studio 2008 R2.
Anyone else have this issue and come up with a way to get ftp.SendFiles to overwrite?
-
Thursday, July 08, 2010 1:12 PM
It took awhile, but I found the real bug (or I could be doing something wrong).
In my Script Task, if all I do is execute the command ftp.SendFiles it will send the files and overwrite them if they exist - all good there. However, in my case I want to immediately confirm the file is actually on the FTP server - I don't want to trust that the file is there soley on the fact that ftp.SendFiles didn't throw an exception, so I call ftp.GetListing and loop over the results to ensure the file I just sent exists on the FTP server, so far so good. If this is the first time the file is being transferred and thus you are not overwriting anything this will work, however, if you are overwriting a file it will fail consistently.
The only way I've been able to get this to work is to first copy all the files to the FTP server, disconnect from the FTP server using ftp.Close, reconnect using ftp.Connect and then call ftp.GetListing. If anyone is interested, I can post code samples which will reproduce this bug on your machine.
-
Wednesday, August 04, 2010 8:19 PMHi Matheww, Thank you for the code.I am a newbie to SSIS. It was very helpful. The script task succeeded, however it did not FTP the file to the server. Need help with this. Thanks, Nivi.
-
Tuesday, August 17, 2010 7:19 AM
Hi,
those who are facing 0xC001602A exception, try setting the UsePassiveMode to true.
cm.Properties("UsePassiveMode").SetValue(cm, true)
Thanks,
Rency
Rency -
Friday, September 24, 2010 8:08 PM
Hi,
I am a newbie to SSIS and been looking for awhile whether it is possible to write a dynamic script (SQL sp or VB or whatever) that dynamically passes different FTP related parameters (FTP server, login, password, filepath, file, etc...) and FTPs/uploads files to different FTP servers.
Basically, I am trying to create a SSIS package that will reference a SQL table for various input parameters (i.e. file name, FTP server where to send the file, user login/password for that particular FTP server, etc...)
Not sure if this is clear what I am asking, but using FTP task in SSIS does not allow this - it seems that you can only specify one FTP server and related credentials and cannot vary this dynamically at package's run time.
Thanks,
-
Thursday, September 30, 2010 3:12 PM
Hi Rossoneri76,
If you are going to use the FTP task built in to SSIS, You can store certain settings within SQL, FTP server, Login etc the only thing you can't do is the FTP password as it needs to be manually added within the package. It can be done with script though.
If you store the settings within SQL, use a Execute SQL to get the values and store each one of them in a seperate variable.. then within the FTP connection manager, go to expressions, select the relevant one and but in the relevant variable. Therefore when the package runs it picks up the settings from sql assigns them to a variable and then the ftp connection manager picks up the required settings.Hope that helps.
-
Wednesday, October 27, 2010 5:35 PM
How do I pass three files all at once? Below did not work for me. It only passed the first file.
Dim files(0) As String
files(0) = "Drive:\FullPath\FileName1" & "Drive:\FullPath\FileName2" & "Drive:\FullPath\FileName3"
ftp.SendFiles(files, "/Enter Your Remote Path", True, False)
-
Thursday, November 04, 2010 6:33 PMThanks - I do this script but receive files (ftp.ReceiveFiles). The files are saved to the D: drive yet once received the C: drive space is eaten up. It'll eventually release it but I can't figure out how to force it - I assume it's a cache thing? Issue being I send over several large files so the C: drive goes from over 1GB to about 50MB as the files get transferred. Sometimes in the middle of it a chunk of drive space is reclaimed but usually it gets eaten up over the FTP process and then later (sometimes minutes, sometimes days) the drive space will automagically free up. Definitely related to this process - I can click the SSIS with this script task and see the drive space disappear as it runs. I can't determine how to force the cache to empty?
-
Tuesday, December 21, 2010 6:36 AM
Hi Matthew, I am trying to use your script and I get an error and I don't know what I am missing.
Error 2 Name 'Dts' is not declared. C:\Users\XXXXXX\AppData\Local\Temp\13\SSIS\ST_fc630fdb35fe4f6ab3d11eba5905f5e5\ScriptMain.vb 64 13 ST_fc630fdb35fe4f6ab3d11eba5905f5e5
Am I missing a reference??
I will appreciate your help.
Thanks,
-
Thursday, March 10, 2011 3:55 PMI see why you build a client connection from code. It seems hard or undoable to add an FTP task from the toolbox and program it's properties in a loop.
-
Tuesday, May 17, 2011 6:59 PM
Hi Matthew, How do you put your code in SSIS? I'd like move my output files in batch to FTP. Please help me.
Thank you,
Thomas
-
Wednesday, June 01, 2011 5:27 PM
Thanks for your suggesttion, it worked when remotedirectory is ""
-
Thursday, September 29, 2011 12:22 AM
Thank You Mathew you have saved me from hours of painful gui work. Your code is awesome the one thing I noticed and would suggest to those of you encountering no file after a successfull run is did you have the correct \ at the end of the recieve file location. I took me a few minutes to realize that I was not ending my path with a \.
My question is this how can you force this to fail in an SSIS package within a scheduled job on SQL 2005. If i am locked out of the account it still shows success even though no connection or file was made. it does display the below error in bids if I am debugging but settin the package to fail on error does not seem to achnowledge the error. (see below)
Error: 0xC001602A at ssis_fts_corp_prbz_net_ES1, Connection manager "{6449CE4A-6536-432E-945A-1FA79480F2A6}": An error occurred in the requested FTP operation. Detailed error description: The password was not allowed
thanks in advance for your time.
-Jbird
-
Tuesday, February 07, 2012 7:40 PM
Thanks Matthew. That was very helpful. I have run this in C# for SSIS 2008 R2 and it works. Below is my code sample based off your VB version. Included is a check to only download files which do not exist on the local directory.public void Main() { string[] ftp_fileList; string[] ftp_folderList; string[] local_fileList; string[] getFiles; string serverName = Dts.Variables["User::serverName"].Value.ToString(); string serverUserName = Dts.Variables["User::serverpUserName"].Value.ToString(); string serverPassword = Dts.Variables["User::serverPassword"].Value.ToString(); string localFolder = Dts.Variables["User::localFolder"].Value.ToString(); ConnectionManager cm = Dts.Connections.Add("FTP"); cm.Properties["ServerName"].SetValue(cm, serverName); cm.Properties["ServerUserName"].SetValue(cm, serverUserName); cm.Properties["ServerPassword"].SetValue(cm, serverPassword); cm.Properties["ServerPort"].SetValue(cm, "21"); cm.Properties["Timeout"].SetValue(cm, "0"); cm.Properties["ChunkSize"].SetValue(cm, "1000"); cm.Properties["Retries"].SetValue(cm, "1"); FtpClientConnection ftp = new FtpClientConnection(cm.AcquireConnection(null)); ftp.Connect(); //Get a list of all available files on the ftp server. ftp.GetListing(out ftp_folderList, out ftp_fileList); //Get a list of all existing files on the local drive. local_fileList = Directory.GetFiles(localFolder); //Build a list of files which need to be downloaded. StringBuilder getList = new StringBuilder(); foreach (string ftpFile in ftp_fileList) { string comp = localFolder + ftpFile; if (Array.IndexOf(local_fileList, comp) == -1) { getList.Append(ftpFile); getList.Append("|"); } } if (getList.Length > 0) { getList.Remove(getList.Length - 1, 1); getFiles = getList.ToString().Split('|'); ftp.ReceiveFiles(getFiles, localFolder, true, false); } ftp.Close(); Dts.TaskResult = (int)ScriptResults.Success; } -
Monday, February 13, 2012 11:41 PM
Hi there,
Wondering if anyone has had to do something like this before:
I have to export some files to an external FTP site outside our domain. Initially I could not connect to it using something like FileZilla so contacted our IT team about it. Apparently we have to specify a proxy server first and then connect to the FTP site.
Using a tool like FileZilla I can specify a generic proxy of "HTTP/1.1 using CONNECT method", then enter in the proxy host (proxy.domain.local), a port and my domain user name and password. So then when I connect to the ftp site (ftp.domain.com) and specify a user name and password it works.
How do you do this using an SSIS Script Task??? I can use a SSIS Script task to FTP files to other FTP sites that don't need to go through the proxy server but I just can't do it to external sites that require authentication from the proxy server.
I've searched this forum, seen some connections like ftp_user_name@ftp.domain.com or ftp.domain.com:21.ftp_user_name.ftp_password but they don't work. Any thoughts would be appreciated.
Kind regards,
Chris
-
Tuesday, February 14, 2012 1:17 AM
Hi Chris,
The standard SSIS FTP Task (and classes) doesn't support advanced features like proxy support. If you can use third-party solutions, check the commercial CozyRoc SFTP Task. It includes support for both SSH and FTPS protocols and supports HTTP, SOCKS4, SOCKS5, FTP Site, FTP Open and FTP User proxy types.
SSIS Tasks Components Scripts Services | http://www.cozyroc.com/

-
Tuesday, February 14, 2012 2:45 AM
Imports System Imports System.Data Imports System.Math Imports Microsoft.SqlServer.Dts.Runtime Public Class ScriptMain Public Sub Main() Try Dim dbConn As ConnectionManager = Dts.Connections("connectionstringnamehere") dbConn.ConnectionString = "Data Source=datasource;User ID=userid;Password=password;Initial Catalog=databasename;Provider=SQLNCLI.1;Persist Security Info=True;Auto Translate=False;" Dim ftpConn As ConnectionManager = Dts.Connections("ftpconnectionstringname") ftpConn.Properties("ServerName").SetValue(ftpConn, "servername") ftpConn.Properties("ServerPort").SetValue(ftpConn, "21") ftpConn.Properties("ServerUserName").SetValue(ftpConn, "username") ftpConn.Properties("ServerPassword").SetValue(ftpConn, "password") Dts.TaskResult = Dts.Results.Success Catch ex As Exception Dts.TaskResult = Dts.Results.Failure End Try End Sub End Classcreate connection strings for production server and ftp sertver first and then use this script in script task.
srikrishna
-
Friday, August 10, 2012 5:36 PM
I have been working on scheduling an SSIS package to ftp files for a couple of days. This worked flawlessly.
Thank you so much for your time and effort putting this script task together.
You the MAN!
-
Friday, August 10, 2012 9:41 PM
Can you please tell me how you would set this up for SFTP instead of FTP?
Thanks to you , the FTP script works, but now I need to create a package sending files to an SFTP site.
-
Thursday, August 23, 2012 1:13 PM
i changed the TennesseePaul's C# code to VB code....and added some extra code in it works perfect
Thanks Ton saved my time....
Imports System
Imports System.Collections
Imports System.Data
Imports System.IO
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
Enum ScriptResults
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
End Enum
Public Class ScriptMain
Public Sub Main()
Try
Dim ftp_fileList As String()
Dim ftp_folderList As String()
Dim local_fileList As String()
Dim getFiles As String()
Dim LocalPaths As String = Dts.Variables("User::LocalPaths").Value.ToString()
Dim cm As ConnectionManager = Dts.Connections.Add("FTP")
'Set the properties like username & password
cm.Properties("ServerName").SetValue(cm, "xxxxxx")
cm.Properties("ServerUserName").SetValue(cm,"xxx")
cm.Properties("ServerPassword").SetValue(cm, "xxx")
cm.Properties("ServerPort").SetValue(cm, "21")
cm.Properties("Timeout").SetValue(cm, "0") 'The 0 setting will make it not timeout
cm.Properties("ChunkSize").SetValue(cm, "1000") '1000 kb
cm.Properties("Retries").SetValue(cm, "1")
'create the FTP object that sends the files and pass it the connection created above.
Dim ftp As FtpClientConnection = New FtpClientConnection(cm.AcquireConnection(Nothing))
ftp.Connect()
ftp.SetWorkingDirectory(Dts.Variables("FtpPaths").Value.ToString())
'Get a list of all available files on the ftp server.
ftp.GetListing(ftp_folderList, ftp_fileList)
'Get a list of all existing files on the local drive.
local_fileList = Directory.GetFiles(LocalPaths)
'Build a list of files which need to be downloaded.
Dim getList As New Text.StringBuilder()
For Each ftpFile As String In ftp_fileList
Dim comp As String = LocalPaths & ftpFile
If Array.IndexOf(local_fileList, comp) = -1 Then
getList.Append(ftpFile)
getList.Append("|")
End If
Next
If getList.Length > 0 Then
getList.Remove(getList.Length - 1, 1)
getFiles = getList.ToString().Split("|"c)
ftp.ReceiveFiles(getFiles, LocalPaths, True, False)
End If
ftp.Close()
Dts.TaskResult = ScriptResults.Success
Catch ex As Exception
' Fire error and set result to failure
Dts.Events.FireError(0, "FTP Script Task", "Error: " + ex.Message, String.Empty, 0)
Dts.TaskResult = ScriptResults.Failure
End Try
End Sub
End Class
s
-
Monday, December 03, 2012 3:27 AM
hi ,Rency Fernandes
your code :
cm.Properties("UsePassiveMode").SetValue(cm, true)
it does not working.it almost throw exception
RESULT:0xC001602A,{A754A946-7A38-4022-A8B9-31CE3C4E82CB},,.... The operation timed outbut thank for all the same.
- Edited by 科学家 Monday, December 03, 2012 3:31 AM additional information
-
Monday, December 03, 2012 2:32 PMModeratorThe time out typically is not code related, it is your environment, also consider posting your issue using your own thread.
Arthur My Blog

-
Wednesday, January 23, 2013 6:22 PMModerator
Consider posting your issue into your own (new) thread.
I can assume here the values do not get passed as you expect them because it does not connect doing this two different ways.
Arthur My Blog

-
Wednesday, January 23, 2013 6:26 PMI was going to create my own thread, I was just following the forum rules for posts. I will move this to another thread.

