none
FTP Upload Multiple Files via OpenFileDialog RRS feed

  • Question

  • Hello there. I am new to programming WPF applications and I am trying to build a FTP uploader using the WinSCP library. I am using OpenFileDialog to choose my files. I can get it to upload one file not issue, however I need to upload all files that are selected in the listview box that I chose via openfiledialog. I know I need a foreach loop on my upload, I just don't know what to put as the arguments.

    Here is my code.

    using System;
    using System.ComponentModel;
    using System.Globalization;
    using System.IO;
    using System.Windows;
    using System.Windows.Threading;
    using Microsoft.Win32;
    using WinSCP;

    namespace FTP.Dialogs
    {
        public partial class Dialog
        {
            BackgroundWorker backgroundWorker1;
            public Dialog()
            {
                InitializeComponent();

                // Create new BackgroundWorker.
                backgroundWorker1 = new BackgroundWorker();

                backgroundWorker1.DoWork += backgroundWorker1_DoWork;
                backgroundWorker1.RunWorkerCompleted += backgroundWorker1_RunWorkerCompleted;
                backgroundWorker1.WorkerReportsProgress = true;
                //backgroundWorker1.WorkerSupportsCancellation = true; // This can be used with a button defined with backgroundWorker1.CancelAsync(); to cancel a upload. (doesn't work)
            }

            private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

            private string filen { get; set; }

            private string filePath { get; set; }

            private string Host { get; set; }

            private string Stamp { get; set; }

            private string Files { get; set; }

            private void BtnOpenFiles_Click(object sender, RoutedEventArgs e)
            {
                // The browse button will allow to select multiple files, and give the ability to filter by certain file extensions.
                // By default it shows all file types.
                OpenFileDialog openFileDialog = new OpenFileDialog
                {
                    Multiselect = true,     // Allow the ability to select multiple files in the opendialog.
                    Filter = "All Files (*.*)|*.*|Text Files (*.txt)|*.txt|Image files (*.png;*.jpeg)|*.png;*.jpeg", // First option on far left sets default file type. Format is description|file extension. EX: SQL (.sql)|*.sql
                    CheckFileExists = true, // Making sure the file we selected actually exists on the disk.
                    CheckPathExists = true, // Making sure the path for the file is a valid path.
                    ValidateNames = true    // Make sure the file name isn't something funky that will get rejected.
                };

                // If we actually have the file select box open, add them to the Listview xaml box and send a message to the status box what file was added.
                if (openFileDialog.ShowDialog() == true)
                {
                    foreach (string filename in openFileDialog.FileNames)
                    {
                        string[] Files = openFileDialog.FileNames;
                        string Stamp = DateTime.Now.ToString("MM-dd-yyyy HH:mm:ss", CultureInfo.InvariantCulture);
                        lbFiles.Items.Add(Path.GetFileName(filename)); // Add the selected file in the listview box.
                        filePath = openFileDialog.FileName; // Get the full directory path and the filename.
                        filen = Path.GetFileName(filename); // Get just the filename without directories attached.
                        TextBox1.Text += Stamp + ": Added " + filename + ".\n";
                        lbFiles.SelectAll(); // Mark the files highlighted as they are added so below code knows which files the user wants to upload.
                    }
                }
            }

            // Remove all items in the ListView box.
            private void BtnClear_Click(object sender, RoutedEventArgs e)
            {
                lbFiles.Items.Clear();
            }

            // Remove selected items in the ListView box.
            private void BtnRemove_Click(object sender, RoutedEventArgs e)
            {
                int Listboxitemcount = lbFiles.SelectedItems.Count;
                for (int i = 0; i < Listboxitemcount; i++)
                {
                    lbFiles.Items.Remove(lbFiles.SelectedItem);
                }
            }

            // Select all items in the ListView box.
            private void BtnSelectAll_Click(object sender, RoutedEventArgs e)
            {
                if (lbFiles.SelectedIndex == -1)
                {
                    lbFiles.SelectAll();
                }
                // Clicking the button again will unselect all.
                else
                {
                    lbFiles.SelectedIndex = 0;
                    lbFiles.UnselectAll();
                }
            }

            // Clear all the messaging in all the boxes and reset the progressbar.
            private void BtntxtboxClear_Click(object sender, RoutedEventArgs e)
            {
                TextBox1.Text = string.Empty;
                progressBar1.Value = 0;
                lblStatus.Text = string.Empty;
                TextBox2.Text = string.Empty;
            }

            //Start the upload process if there isn't already a upload in progress.
            private void BtnUpload_Click(object sender, RoutedEventArgs e)
            {
                Stamp = DateTime.Now.ToString("MM-dd-yyyy HH:mm:ss", CultureInfo.InvariantCulture);
                if (backgroundWorker1.IsBusy != true || filen != null)
                {
                    backgroundWorker1.RunWorkerAsync();
                    progressBar1.Value = 0;
                    lblStatus.Text = string.Empty;
                    TextBox2.Text = string.Empty;
                    TextBox1.Text = Stamp + ": Starting Upload of " + filen + ".\n";
                }
                if (filen == null)
                {
                    TextBox1.Text  = Stamp + ": You have not picked a file to upload!\n";
                }
            }

            private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
            {
                BackgroundWorker worker = sender as BackgroundWorker;

                // Check to see if the background worker has been canceled and stop operations.
                if (worker.CancellationPending)
                {
                    e.Cancel = true;
                    e.Result += Stamp + ": You are trying to start an upload but there is a upload currently being canceled. Your upload has been canceled.\n";
                    return;
                }
                if (filen == null)
                {
                    e.Result = "You have not selected a file to upload!";
                    e.Cancel = true;
                    return;
                }

                else
                {
                    try
                    {
                        Stamp = DateTime.Now.ToString("MM-dd-yyyy HH:mm:ss", CultureInfo.InvariantCulture);

                        // Setup session options.
                        SessionOptions sessionOptions = new SessionOptions
                        {
                            // Set all the session options here. winscp.net/eng/docs/library_sessionoptions
                            Protocol = Protocol.Sftp,
                            HostName = "myservername",
                            UserName = "myusername",
                            Password = "mypassword",
                            SshHostKeyFingerprint = "ssh-rsa 1024 d1:d6:18:64:46:48:b1:b2:4f:05:69:ad:2d:b6:2f:1a",
                            //SecurePrivateKeyPassphrase = "",
                            Timeout = new TimeSpan(0, 0, 30), // Server response timeout. Parameters are (hours,minutes,seconds)
                            //SshPrivateKeyPath = "/path/goes/here",
                        };

                        sessionOptions.AddRawSettings("SshProt", "3");

                        using (Session session = new Session())
                        {
                            TransferOptions transferOptions = new TransferOptions
                            {
                                TransferMode = TransferMode.Automatic,  // Pick which file type you want. Binary, Ascii, and Automatic are the options.
                                SpeedLimit = 4096                      // Set the transfer rate here.
                            };
                            transferOptions.ResumeSupport.State = TransferResumeSupportState.On; // If set on, this saves the file in parts as it transfers, attaching a .filename extension until completed.

                            session.FileTransferProgress += SessionFileTransferProgress; // WinSCP FileTransferProgressEvent to update progressbar.
                            session.Open(sessionOptions);           // Start the connection to the host.
                            string RemotePath = "/";                // Set the remote server upload path here again.
                            string RemoteFile = RemotePath + filen; // Combine the path of the remote server and the filename we're uploading.

                            // Check if the file exists on the remote server. If it does exist, throw error and disconnect.
                            if (session.FileExists(RemoteFile))
                            {
                                e.Result = filen + " already exists on Host \"" + sessionOptions.HostName + "\" in directory \"" + RemotePath + "\". Disconnecting from host.\n";
                                session.Dispose();
                            }

                            else
                            {
                                    TransferOperationResult transferResult;
                                    transferResult = session.PutFiles(filePath, RemotePath, false, transferOptions); // Upload the file.
                                    transferResult.Check(); // Check if there are any errors.

                                using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite)) // Set read and write access to the file, open it and then stream it.
                                {
                                    int bufferLength = 4096;                        // Size of the chunks we'll be sending.
                                    byte[] buffer = new byte[bufferLength];         // Set the array size for the buffer.
                                    int bytesRead;

                                    while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0)
                                    {
                                        fs.Write(buffer, 0, buffer.Length); // Write to Buffy the Vampire Slayer.
                                    }
                                    fs.Close();
                                }
                            }
                            session.Dispose();
                        }
                    }
                    catch (Exception ex)
                    {
                        e.Result = ex;
                    }
                }
            }

            private void SessionFileTransferProgress(object sender, FileTransferProgressEventArgs e)
            {
                this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate ()
                {
                    // Sets boundaries on what values are legit for the progressbar.
                    progressBar1.Maximum = 100;
                    progressBar1.Minimum = 0;
                    progressBar1.Value = Convert.ToInt32(e.FileProgress * 100); // Take the value and multiply it to give it a whole number.
                    lblStatus.Text = "Uploaded " + (e.FileProgress * 100) + "%";
                    int v = (e.CPS / 1024 / 1024); // Convert bytes to megabytes to shower transfer speed.
                    TextBox2.Text = "Transferring at " + v + " MB's.";
                }));
            }
            
            private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                Stamp = DateTime.Now.ToString("MM-dd-yyyy HH:mm:ss", CultureInfo.InvariantCulture);

                // If the upload is canceled which currently doesn't work with CancelAsync(). Give message, reset the progressbar and update the upload status box.
                if (e.Cancelled)
                {
                    TextBox1.Text += Stamp + ": Upload of " + filen + " canceled." + "\n";
                    progressBar1.Value = 0;
                    lblStatus.Text = "Canceled";
                }

                // Show errors if there are any.
                else if (e.Result != null)
                {
                    TextBox1.Text += Stamp + ": Error in Process: " + e.Result + "\n";
                }

                // If the upload was successful, let the user know and then remove the file from the listview box.
                else
                {
                    TextBox1.Text += Stamp + ": Upload of " + filen + " complete. " + e.Result + "\n";
                    lbFiles.Items.Remove(filen);
                }
            }
        }
    }

    Monday, September 16, 2019 5:24 PM

Answers

  • Curtis_

    You already have it in your code:

    foreach (string filename in openFileDialog.FileNames)
    {
    //string[] Files = openFileDialog.FileNames; // why are you doing this in a foreach?
    
    //use filename to upload, you are done! filename has path and everything, what else are you looking for?
     }


    noorbakhsh حميد نوربخش

    • Marked as answer by Curtis_ Thursday, September 19, 2019 1:34 PM
    Monday, September 16, 2019 10:29 PM

All replies

  • Curtis_

    You already have it in your code:

    foreach (string filename in openFileDialog.FileNames)
    {
    //string[] Files = openFileDialog.FileNames; // why are you doing this in a foreach?
    
    //use filename to upload, you are done! filename has path and everything, what else are you looking for?
     }


    noorbakhsh حميد نوربخش

    • Marked as answer by Curtis_ Thursday, September 19, 2019 1:34 PM
    Monday, September 16, 2019 10:29 PM
  • Thanks. This did the trick. After I got that done, the UI would only let me know if all files were uploaded from runworkercompleted. So I created another method to fire after every upload finished and invoked it to run so it would update my message boxes to let me know after every file was successfully uploaded.
    Thursday, September 19, 2019 1:37 PM