Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WPF

Simple FTP Uploader Using Zip File For Software Update

5.00/5 (1 vote)
18 Feb 2019CPOL3 min read 8.8K  
This program is designed to upload an XML file and a zip file automatically created to your FTP server. It can be used for software update.

Introduction

If you want to upload some files to your FTP server, you can put these files to the FTP server one by one.

But if the local directory path of these files is different from each other, you should check on the FTP server whether all those directory names exist or not.

Furthermore, if some file's path has many directories, you should create the directories in FTP server step by one. Because you can't create a directory having 2 more steps not existing at once.

It's uncomfortable for me, so, I will make a zip file and put all files on it. ZipArchive offers to create a hierarchy directory by once.

Background

  1. Drag drop files into a datagrid control in WPF project.
  2. When clicking the button which is labeled 'save and upload', the program run creates an XML file (contains files information like path, size, writetime) and makes zip file automatically, and all the files you drag-dropped on it.
  3. Then, that XML and ZIP file will be uploaded to the FTP server you indicated.
  4. For this, you should know the relative directory path.

    For example, if you add two files in a zip file and they are in different directory paths, you should know a base root path to create an entry folder path in a zip.

    First file's real path is d:\abcd\goodjob.txt

    Second file's real path is d:\abcd\folder\goodjob1.txt

    Then, the local root path must be considered 'd:\abcd\'

    So, the first file's relative path is '\goodjob.txt' and the second file's relative path is 'folder\goodjob1.txt'.

  5. In short, zip file's root has one file and one directory entry called folder and 'goodjob1.txt' file will be in that.

Using the Code

First, you do create a WPF project using .NET 4.6.

The reason why I'm using that version is that ZipArchive class is offered after .NET 4.5 as I know.

This code below is for 'MainWindow.xaml'.

First of all, you must drag drop files you want to a DataGrid control named 'dgToUploadFiles'.

Then, input FTP server URL to the 'Server Root Url'.

If you have to manage different kinds of program version files, you can use the 'Key Directory'. The directory will be created automatically in the FTP server next to 'Server Root Url/SWUpdate/'.

Lastly, you should input the id and password, and click the 'Save and Upload' button.

XML
<Window x:Class="NewSoftwareFileUploader.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="New Software Version Files Uploader" 
        Height="350" Width="525" x:Name="_this">
    <DockPanel LastChildFill="True">
        <DockPanel DockPanel.Dock="Top" LastChildFill="True">
            <TextBlock Width="100" DockPanel.Dock="Left">Server Root Url:</TextBlock>
            <TextBox Name="txtServerRoot" DataContext="{Binding ElementName=_this}" 
             Text="{Binding Path=ServerRootPath}"></TextBox>
        </DockPanel>
        <DockPanel DockPanel.Dock="Top" LastChildFill="True">
            <TextBlock Width="100" DockPanel.Dock="Left">Key Directory:</TextBlock>
            <TextBox Width="100" DockPanel.Dock="Left" Name="txtKeyDir" 
             DataContext="{Binding ElementName=_this}" Text="{Binding Path=KeyDirectory}" 
             Margin="0,0,5,0"></TextBox>
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
                <TextBlock Width="50" DockPanel.Dock="Left">User ID:</TextBlock>
                <TextBox Width="80" DockPanel.Dock="Left" Name="txtUserID" 
                 DataContext="{Binding ElementName=_this}" Text="{Binding Path=UserID}" 
                 Margin="0,0,5,0"></TextBox>
                <TextBlock Width="60" DockPanel.Dock="Left">Password:</TextBlock>
                <PasswordBox Width="80" DockPanel.Dock="Left" 
                Name="txtPassword"></PasswordBox>
            </StackPanel>            
        </DockPanel>
        <StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" 
        HorizontalAlignment="Right">
            <Button Width="50" Height="30" Name="btnDel" 
             Click="btnDel_Click" Margin="5">Delete</Button>
            <Button Width="150" Height="30" Name="btnUpload" 
             Click="btnSaveAndUpload_Click" Margin="5">Save and Upload</Button>
        </StackPanel>
        <DockPanel DockPanel.Dock="Bottom" LastChildFill="True">
            <TextBlock DockPanel.Dock="Left" Text="Base Relative Path : "></TextBlock>
            <TextBlock DataContext="{Binding ElementName=_this}" 
             Text="{Binding Path=LocalRootPath}"></TextBlock>
        </DockPanel>
        <DockPanel LastChildFill="True">
            <DataGrid Name="dgToUploadFiles" Drop="dgToUploadFiles_Drop" 
             AutoGenerateColumns="False" 
             IsReadOnly="True" CanUserDeleteRows="False" 
             CanUserAddRows="False" SelectionUnit="FullRow" AllowDrop="True">
                <DataGrid.Columns>
                    <DataGridTextColumn Header="Path" Width="200*" 
                     Foreground="Black" 
                     Binding="{Binding FullPathDesc}"></DataGridTextColumn>
                    <DataGridTextColumn Header="Length" Width="100" 
                     Foreground="Black" 
                     Binding="{Binding LengthDesc}"></DataGridTextColumn>
                    <DataGridTextColumn Header="LastWriteTime" Width="150" 
                     Foreground="Black" 
                     Binding="{Binding LastWriteTimeDesc}"></DataGridTextColumn>
                </DataGrid.Columns>
            </DataGrid>
        </DockPanel>
    </DockPanel>
    
</Window>

And this code below is MainWindow.xaml.cs:

C#
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace NewSoftwareFileUploader
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        // FTP Server Root
        public static readonly DependencyProperty ServerRootPathProperty =
            DependencyProperty.Register("ServerRootPath", typeof(string), 
                  typeof(MainWindow), new UIPropertyMetadata(string.Empty));

        public string ServerRootPath
        {
            get 
            {
                string strTmp = (string)this.GetValue(ServerRootPathProperty);
                if (String.IsNullOrEmpty(strTmp)) return "";

                // url must be ended with a character '/'
                if (!strTmp.EndsWith("/")) strTmp += "/";
                return strTmp;
            }
            set 
            {
                string strTmp = value;
                if(String.IsNullOrEmpty(strTmp)) return;

                // url must be ended with a character '/'
                if (!strTmp.EndsWith("/")) strTmp += "/";

                this.SetValue(ServerRootPathProperty, strTmp); 
            }
        }

        // You will use a key directory url if there're many different 
        // sw versions in FTP server in case.
        public static readonly DependencyProperty KeyDirectoryProperty =
            DependencyProperty.Register("KeyDirectory", typeof(string), 
                    typeof(MainWindow), new UIPropertyMetadata(string.Empty));

        public string KeyDirectory
        {
            get 
            {
                string strTmp = (string)this.GetValue(KeyDirectoryProperty);
                if (String.IsNullOrEmpty(strTmp)) return "";

                // url directory must be ended with a character '/'
                if (!strTmp.EndsWith("/")) strTmp += "/";
                return strTmp;
            }
            set 
            {
                string strTmp = value;
                if(String.IsNullOrEmpty(strTmp)) return;

                // url directory must be ended with a character '/'
                if (!strTmp.EndsWith("/")) strTmp += "/";

                this.SetValue(KeyDirectoryProperty, strTmp); 
            }
        }

        // user id to log in
        public static readonly DependencyProperty UserIDProperty =
            DependencyProperty.Register("UserID", typeof(string), 
                 typeof(MainWindow), new UIPropertyMetadata(string.Empty));

        public string UserID
        {
            get { return (string)this.GetValue(UserIDProperty); }
            set { this.SetValue(UserIDProperty, value); }
        }

        // This is a path which the created zip file will be in.
        public static readonly DependencyProperty SaveTemporaryPathProperty =
            DependencyProperty.Register("SaveTemporaryPath", typeof(string), 
                      typeof(MainWindow), new UIPropertyMetadata(string.Empty));

        public string SaveTemporaryPath
        {
            get 
            {
                string strTmp = (string)this.GetValue(SaveTemporaryPathProperty);
                if (String.IsNullOrEmpty(strTmp)) return "";

                // directory must be ended with a character '\\'
                if (!strTmp.EndsWith("\\")) strTmp += "\\";
                return strTmp;
            }
            set
            {
                string strTmp = value;
                if (String.IsNullOrEmpty(strTmp)) return;

                // directory must be ended with a character '\\'
                if (!strTmp.EndsWith("\\")) strTmp += "\\";

                this.SetValue(SaveTemporaryPathProperty, strTmp);
            } 
        }

        // This is for a relative path. 
        // If you add two more files in a zip file and they are in different directory paths,
        // you should know a base root path to create entry folder path in a zip.
        // for example,
        // first file's real path is d:\abcd\goodjob.txt
        // second file's real path is d:\abcd\folder\goodjob.txt
        // then the local root path must be d:\abcd\
        // and first file's relative path is goodjob.txt
        // lastly, second file's relative path is folder\goodjob.txt
        public static readonly DependencyProperty LocalRootPathProperty =
            DependencyProperty.Register("LocalRootPath", typeof(string), 
                      typeof(MainWindow), new UIPropertyMetadata(string.Empty));

        public string LocalRootPath
        {
            get { return (string)this.GetValue(LocalRootPathProperty); }
            set
            {
                string strTmp = value;
                if (String.IsNullOrEmpty(strTmp)) return;

                // url directory must be ended with a character '/'
                if (!strTmp.EndsWith("\\")) strTmp += "\\";

                this.SetValue(LocalRootPathProperty, strTmp);
            } 
        }

        public MainWindow()
        {
            InitializeComponent();

            // default values
            ServerRootPath = "ftp://192.168.0.32/";
            KeyDirectory = "SITE1/";
            UserID = "young";

            SaveTemporaryPath = System.IO.Path.GetDirectoryName
                      (Process.GetCurrentProcess().MainModule.FileName);
            LocalRootPath = "";
        }

        private void btnConnect_Click(object sender, RoutedEventArgs e)
        {
            //lvFiles.Items.Clear();

            string url = txtServerRoot.Text;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
            {
                using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                {
                    string html = reader.ReadToEnd();
                    Regex regex = new Regex("<A HREF=\".*\">(?<name>.*)</A>");
                    MatchCollection matches = regex.Matches(html);
                    if (matches.Count > 0)
                    {
                        foreach (Match match in matches)
                        {
                            if (match.Success)
                            {
                                //lvFiles.Items.Add(match.Groups["name"]);
                            }
                        }
                    }
                }
            }

            Console.ReadLine();
        }

        private void btnDel_Click(object sender, RoutedEventArgs e)
        {
            if (dgToUploadFiles.SelectedItems.Count <= 0) return;

            List<UploadFileInfo> lstRemove = new List<UploadFileInfo>();
            lstRemove.AddRange(dgToUploadFiles.SelectedItems.Cast<UploadFileInfo>().ToList());

            foreach (UploadFileInfo fileInfo in lstRemove)
                dgToUploadFiles.Items.Remove(fileInfo);
        }

        private String GetXmlNomalizedString(XmlDocument doc, Encoding encoding)
        {
            try
            {
                XmlWriterSettings settings = new XmlWriterSettings
                {
                    Indent = true,
                    IndentChars = "  ",
                    NewLineChars = "\r\n",
                    NewLineHandling = NewLineHandling.Replace,
                    Encoding = encoding    // if you need to create the BOM, 
                             // change like this 'new UTF8Encoding(false)' instead of 'encoding'
                };
                using (var ms = new MemoryStream())
                using (var writer = XmlWriter.Create(ms, settings))
                {
                    try
                    {
                        doc.Save(writer);
                        var xmlString = encoding.GetString(ms.ToArray());
                        return xmlString;
                    }
                    catch (Exception e)
                    {
                        MessageBox.Show(e.ToString());
                        return doc.OuterXml;
                    }
                }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
                return "";
            }
        }

        private void dgToUploadFiles_Drop(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
                if (files != null)
                {
                    foreach (String strFullFilePath in files)
                    {
                        // if this file already exists in this DataGrid
                        IEnumerable<UploadFileInfo> existedItem = 
                             dgToUploadFiles.Items.Cast<UploadFileInfo>().Where
                                     (item => item.FullPathDesc == strFullFilePath);
                        if (existedItem.Count() > 0) continue;

                        if ((Directory.Exists(strFullFilePath) || File.Exists(strFullFilePath)) &&
                            !String.IsNullOrEmpty(strFullFilePath))
                        {
                            String strDirPath = System.IO.Path.GetDirectoryName(strFullFilePath);
                            if (!String.IsNullOrEmpty(LocalRootPath))
                            {
                                if (!LocalRootPath.StartsWith(strDirPath) && 
                                                !strDirPath.StartsWith(LocalRootPath))
                                {
                                    // All file's paths should be looking in the same direction.
                                    MessageBox.Show(
                                        String.Format("[Drop Files] this file '{0}' 
                                                   is not having the same direction.",
                                        strFullFilePath));
                                    break;
                                }
                                else 
                                {
                                    // what's the parent directory? let's check on this
                                    if (strDirPath.Length < LocalRootPath.Length) 
                                                         LocalRootPath = strDirPath;
                                }
                            }
                            else
                                LocalRootPath = strDirPath;
                            
                            FileInfo fs = new FileInfo(strFullFilePath);
                            if (fs != null)
                            {
                                Int64 lLength = fs.Length;
                                DateTime dtLast = fs.LastWriteTime;

                                UploadFileInfo fileInfo = new UploadFileInfo
                                             (strFullFilePath, lLength, dtLast);
                                dgToUploadFiles.Items.Add(fileInfo);
                            }
                        }
                    }
                }
            }
        }

        private void btnSaveAndUpload_Click(object sender, RoutedEventArgs e)
        {
            if(String.IsNullOrEmpty(KeyDirectory))
            {
                MessageBox.Show("[Save and Archive] input your key directory name");
                return;
            }

            List<UploadFileInfo> lstUploadFiles = new List<UploadFileInfo>();

            if (dgToUploadFiles.Items.Count > 0)
            {
                try
                {
                    XmlDocument xReqDoc = new XmlDocument();

                    // declare XML
                    XmlDeclaration xmlDescNode = xReqDoc.CreateXmlDeclaration("1.0", "UTF-8", "yes");
                    xReqDoc.AppendChild(xmlDescNode);
                    {
                        // create root node
                        XmlElement rootNode = xReqDoc.CreateElement("", "upload_root", "");
                        rootNode.SetAttribute("version", "1");
                        rootNode.SetAttribute("update", DateTime.Now.ToString("yyyyMMddHHmmss"));
                        {
                            // create File node per one item
                            for (int i = 0; i < dgToUploadFiles.Items.Count; i++)
                            {
                                UploadFileInfo fileInfo = dgToUploadFiles.Items[i] as UploadFileInfo;
                                if (fileInfo == null) continue;

                                String strFullFilePath = fileInfo.FullPathDesc;
                                if (!String.IsNullOrEmpty(strFullFilePath))
                                {
                                    FileInfo fs = new FileInfo(strFullFilePath);
                                    if (fs != null)
                                    {
                                        Int64 lLength = fs.Length;
                                        DateTime dtLast = fs.LastWriteTime;

                                        // that's when the relative path is generated
                                        fileInfo.CreateXml(ref xReqDoc, ref rootNode, LocalRootPath);
                                        lstUploadFiles.Add(fileInfo);
                                    }
                                }
                            }
                        }
                        xReqDoc.AppendChild(rootNode);
                    }
                
                    String strXmlData = GetXmlNomalizedString(xReqDoc, Encoding.UTF8);
                    String strTmpDir = String.Format(
                        "{0}UpdateTemporary\\{1}\\", 
                        SaveTemporaryPath.Replace("/", "\\"),
                        KeyDirectory.Replace("/", "\\"));

                    if (!Directory.Exists(strTmpDir)) Directory.CreateDirectory(strTmpDir);

                    String strZipPath = String.Format(
                        "{0}UpdateArchive.zip",
                        strTmpDir,
                        DateTime.Now.ToString("yyyyMMddHHmmss"));
                    using (FileStream zipToOpen = new FileStream(strZipPath, FileMode.Create))
                    {
                        using (ZipArchive archive = new ZipArchive(zipToOpen, ZipArchiveMode.Create))
                        {
                            // put file into the zip
                            foreach (UploadFileInfo fileInfo in lstUploadFiles)
                            {
                                archive.CreateEntryFromFile(
                                    fileInfo.FullPathDesc,
                                    fileInfo.RelativePath.Replace(@"\", "/"), 
                                    CompressionLevel.Fastest);
                            }
                        }
                    }

                    // after making the zip file, start upload
                    if (MessageBox.Show("Do you want to upload this zip file 
                         to ftp server?", "", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
                    {
                        Upload(strXmlData, strZipPath);
                    }
                    else
                    {
                        FileStream fs = new FileStream(
                            String.Format("{0}UpdateList.xml", strTmpDir),
                            FileMode.Create, 
                            FileAccess.Write);

                        using (StreamWriter writer = new StreamWriter(fs, Encoding.UTF8))
                        {
                            // write XML content
                            writer.Write(strXmlData);
                        }

                        fs.Close();
                        fs.Dispose();

                        // show directory
                        Process.Start(strTmpDir);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("[Save and Archive] " + ex.Message);
                }
            }
            else
            {
                MessageBox.Show("[Save and Archive] there are no files to make archive");
            }
        }

        private bool IsExistedFolderInFTP(String strServerPath, out String strErr)
        {
            strErr = "";

            FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(strServerPath);
            ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
            ftpRequest.Credentials = new NetworkCredential(UserID, txtPassword.Password);
            try
            {
                using (var result = (FtpWebResponse)ftpRequest.GetResponse())
                {
                    result.Close(); //directory already existed
                    return true;
                }
            }
            catch (WebException e)
            {
                FtpWebResponse response = (FtpWebResponse)e.Response;
                if (response.StatusCode != FtpStatusCode.ActionNotTakenFileUnavailable)
                {
                    // not in case it does not exist
                    strErr = e.ToString();
                }
            }

            return false;
        }

        private bool MakeFolderInFTP(String strServerPath, out String strErr)
        {
            strErr = "";

            FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(strServerPath);
            ftpRequest.Method = WebRequestMethods.Ftp.MakeDirectory;
            ftpRequest.Credentials = new NetworkCredential(UserID, txtPassword.Password);
            try
            {
                using (var result = (FtpWebResponse)ftpRequest.GetResponse())
                {
                    result.Close(); //making directory is success
                    return true;
                }
            }
            catch (WebException e)
            {
                strErr = e.ToString();
            }

            return false;
        }

        private bool UpdateXmlFileData(String strServerPath, string strXmlData, out String strErr)
        {
            strErr = "";

            string updateFileURL = String.Format("{0}UpdateList.xml", strServerPath);            
            try
            {
                Uri uri = new Uri(updateFileURL);

                FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(updateFileURL);
                ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
                ftpRequest.Credentials = new NetworkCredential(UserID, txtPassword.Password);

                ftpRequest.Proxy = null;
                ftpRequest.UsePassive = false;
                ftpRequest.UseBinary = true;
                ftpRequest.KeepAlive = false;

                Thread.Sleep(200);

                Stream requestStream = ftpRequest.GetRequestStream();
                byte[] buffer = new byte[2048];

                byte[] byteXmlData = Encoding.UTF8.GetBytes(strXmlData);
                requestStream.Write(byteXmlData, 0, byteXmlData.Length);
                requestStream.Close();

                FtpWebResponse uploadResponse = (FtpWebResponse)ftpRequest.GetResponse();

                if (uploadResponse != null) uploadResponse.Close();
                if (requestStream != null) requestStream.Close();

                return true;
            }
            catch (Exception e)
            {
                strErr = e.ToString();
            }

            return false;
        }

        public void Upload(string strXmlData, string uploadfile)
        {
            if(String.IsNullOrEmpty(UserID) || String.IsNullOrEmpty(txtPassword.Password))
            {
                MessageBox.Show("[Upload] " + "you must input your id and password");
                return;
            }
            
            String strErr;               

            // create directories. you should create a directory one by one
            string[] aryToMakeDirs = KeyDirectory.Replace('\\', '/').Split
                          (new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);

            string strServerPath = ServerRootPath;
            foreach(String strToMakeDir in aryToMakeDirs)
            {
                strServerPath += strToMakeDir + "/";

                // check whether directory already exists in server
                bool isExisted = IsExistedFolderInFTP(strServerPath, out strErr);
                if (!isExisted && String.IsNullOrEmpty(strErr))
                {
                    if (!MakeFolderInFTP(strServerPath, out strErr))
                    {
                        MessageBox.Show("[Upload] " + strErr);
                        return;
                    }
                }
                else if (!isExisted)
                {
                    MessageBox.Show("[Upload] " + strErr);
                    return;
                }
            }

            // start XML file
            if(UpdateXmlFileData(strServerPath, strXmlData, out strErr))
            {
                // start upload
                string updateFileURL = String.Format(
                    "{0}{1}",
                    strServerPath,
                    System.IO.Path.GetFileName(uploadfile));

                try
                {
                    Uri uri = new Uri(updateFileURL);

                    FileInfo fInfo = new FileInfo(uploadfile);
                    if (fInfo.Exists)
                    {                    
                        FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(updateFileURL);
                        ftpRequest.Method = WebRequestMethods.Ftp.UploadFile;
                        ftpRequest.Credentials = new NetworkCredential(UserID, txtPassword.Password);

                        ftpRequest.Proxy = null;
                        ftpRequest.UsePassive = false;
                        ftpRequest.UseBinary = true;
                        ftpRequest.KeepAlive = false;

                        Thread.Sleep(200);

                        Stream requestStream = ftpRequest.GetRequestStream();
                        FileStream resultFileStream = new FileStream(uploadfile, FileMode.Open);
                        byte[] buffer = new byte[2048];
                        Int64 lngTotalFileDataBlock = fInfo.Length;

                        int bytesRead;

                        while (true)
                        {
                            bytesRead = resultFileStream.Read(buffer, 0, buffer.Length);

                            if (bytesRead == 0)
                            {
                                break;
                            }

                            requestStream.Write(buffer, 0, bytesRead);
                        }

                        requestStream.Close();

                        FtpWebResponse uploadResponse = (FtpWebResponse)ftpRequest.GetResponse();

                        if (uploadResponse != null) uploadResponse.Close();

                        if (resultFileStream != null) resultFileStream.Close();

                        if (requestStream != null) requestStream.Close();

                        MessageBox.Show("[Upload] success");                    
                    }
                    else
                    {
                        MessageBox.Show("[Upload] zip file is not existed");
                    }
                }
                catch (Exception e)
                {
                    MessageBox.Show("[Upload] " + e.ToString());
                }
            }
            else
            {
                MessageBox.Show("[Upload] " + strErr);
            }
        }
    }
}

If you follow me, you will know that you must create 'UploadFileInfo' class. It is right under here.

This class is one that has its file information. When creating XML file, it will generate its information to XML string on its own.

C#
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;

namespace NewSoftwareFileUploader
{
    public class UploadFileInfo
    {
        private string strFullPath;
        public String FullPathDesc { get { return strFullPath; } }

        public string RelativePath { get; set; }

        private long lLength;
        public String LengthDesc { get { return lLength.ToString(); } }

        private DateTime dtLastWriteTime;
        public String LastWriteTimeDesc { get { return dtLastWriteTime.ToString(); } }

        private UploadFileInfo() 
        {
            strFullPath = "";
            RelativePath = "";

            lLength = -1;
            dtLastWriteTime = new DateTime(0);
        }

        public UploadFileInfo(string path, long len, DateTime dt)
        {
            strFullPath = path;
            lLength = len;
            dtLastWriteTime = dt;
        }

        public void CreateXml(ref XmlDocument xReqDoc, ref XmlElement rootNode, String strRootPath)
        {
            XmlElement fileNode = xReqDoc.CreateElement("", "file", "");
            {
                XmlElement pathNode = xReqDoc.CreateElement("", "path", "");
                {
                    RelativePath = FullPathDesc.Replace(strRootPath, "");
                    pathNode.InnerText = RelativePath;
                }
                fileNode.AppendChild(pathNode);

                XmlElement sizeNode = xReqDoc.CreateElement("", "size", "");
                {
                    sizeNode.InnerText = LengthDesc;
                }
                fileNode.AppendChild(sizeNode);

                XmlElement datetimeNode = xReqDoc.CreateElement("", "datetime", "");
                {
                    datetimeNode.InnerText = LastWriteTimeDesc;
                }
                fileNode.AppendChild(datetimeNode);
            }
            rootNode.AppendChild(fileNode);
        }
    }
}

Points of Interest

The reason why I'm creating file information to XML file is because it is easy to read from the web server.

After setting web server by IIS, if your FTP server URL and web server URL located to the same location. You can use the 'WebClient' which is offered by .NET.

History

  • 2/18/2019: First update

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)