Shaitan00 Posted October 19, 2005 Posted October 19, 2005 I need my C# code to be able to connect to an FTP (IP=10.10.10.1, USER=ADMIN, PASS=TOTAL) and download a file (Information.zip) stored in "\Stores\Details\" from the FTP Account HOME directory. I need to save/copy the downloaded file to a specific location (C:\Temp\). Problem - I have no clue how to open an FTP connection and perform an FTP file transfer in C#... currently I do everything directly (using \\MachineName\ and basic copy commands) but I am loosing that access and being forced to go through an FTP account. Any help/hints would be greatly appreciated ... I hope this is a really simple/easy task... Thanks, Quote
Diesel Posted October 19, 2005 Posted October 19, 2005 Ftp is insanely simple. Are you looking to use your own client..or go through the windows ftp app? If you want to use the windows app, simply create a new process and send commands. Here's a sample function... Dim myproc As New System.Diagnostics.Process 'You probably either want to make this an absolute path or set the directory myproc.StartInfo.FileName = "ftp" myproc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden myproc.StartInfo.CreateNoWindow = True myproc.StartInfo.UseShellExecute = False myproc.StartInfo.RedirectStandardInput = True ' myproc.StartInfo.RedirectStandardOutput = True ' myproc.StartInfo.RedirectStandardError = True ' allow the process to raise events myproc.EnableRaisingEvents = True ' add an Exited event handler AddHandler myproc.Exited, AddressOf Me.ProcessExited Dim errorOutput As IO.StreamReader Try myproc.Start() ftpWriter = myproc.StandardInput 'ftpReader = myproc.StandardOutput() ' errorOutput = myproc.StandardError() Catch ex As Exception 'You should catch a more specific exception End Try If Not (ftpWriter Is Nothing) Then ''Save starting time 'Send ftp commands ftpWriter.WriteLine("open " + obj.ToString()) ftpWriter.WriteLine("O3a") ftpWriter.WriteLine("StRct") ftpWriter.WriteLine("bin") ftpWriter.WriteLine("prompt n") ftpWriter.WriteLine("lcd " + Me.outputDir) ftpWriter.WriteLine("cd s:") ftpWriter.WriteLine("mget *.dvr") ftpWriter.WriteLine("mdelete *.dvr") ftpWriter.WriteLine("Close") count = count + 1 'update progress bar every 10 seconds If updateTime.AddSeconds(10) < DateTime.Now Then Me.UpdateData() updateTime = DateTime.Now End If Next ftpWriter.Write("quit" + Chr(13)) End If Create a ftp client is also an option and is actually not that big of a project. http://www.codeproject.com/csharp/ftpdriver1.asp Quote
Shaitan00 Posted October 19, 2005 Author Posted October 19, 2005 Sounds great but that is a new Process (thread)... One thing I am wondering about, if my program launches this ftp process which needs to transfer a 100meg which should take around 2 minutes - I need to ensure my program waits for the FTP process to terminate. Meaning, I can't have my program launch the ftp process/thread and then just simply move on because the next line of code is trying to open the file I just copied over via FTP... Quote
Diesel Posted October 19, 2005 Posted October 19, 2005 Sure, that's what this line ' add an Exited event handler AddHandler myproc.Exited, AddressOf Me.ProcessExited does. It fires an event after the process has exited. Handle the event any way you want... Private Sub ProcessExited(ByVal sender As Object, ByVal e As System.EventArgs) Dim myProcess As Process = CType(sender, Process) myProcess.Close() 'ftp finished, do something else End Sub And I guess I should explain the other events. This code: 'update progress bar every 10 seconds If updateTime.AddSeconds(10) < DateTime.Now Then Me.UpdateData(startTime, totalFiles, filesCompleted) updateTime = DateTime.Now End If can be used to update the front end. You could calculate the time remaining and then raise an event on the front end..as such: Private Sub UpdateData(ByVal startTime As DateTime, ByVal total As Integer, ByVal completed As Integer) 'take the elapsed time divided by completed records times total - completed Dim elapsed As TimeSpan = DateTime.Now.Subtract(startTime) Dim averageTime As Single = CType(elapsed.TotalSeconds, Single) / completed Dim timeLeft As Single = averageTime * (total - completed) Dim minutesLeft As Integer = CType(timeLeft / 60, Integer) Dim secondsLeft As Integer = CType(timeLeft Mod 60, Integer) If minutesLeft = 0 And secondsLeft = 0 Then lprogressText = "Calculating Time..." Else lprogressText = "Time Remaining: " + minutesLeft.ToString() + " minutes " + secondsLeft.ToString() + " seconds" End If RaiseEvent ProgressChanged(lprogressText, Nothing) End Sub and you could handle the ProgressChanged event on the front end in a manner like so: Private Sub UpdateThreadData(ByVal sender As Object, ByVal e As EventArgs) Dim graphics As Drawing.Graphics = Me.CreateGraphics() graphics.FillRectangle(Drawing.SystemBrushes.Control, 32, 16, 250, 15) If NOT(sender Is Nothing) Then 'Update Progress Text graphics.DrawString(sender.ToString(), New Drawing.Font(Drawing.FontFamily.GenericSerif, 10), Drawing.Brushes.Black, 32, 16) End If End Sub One major problem with using a process is that it's hard to handle errors. Or at least I haven't found an easy way. If you had your own client, you could have a more robust error handling system. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.