Alan
Alan

Reputation: 23

C# Auto Update Program

OK, I am working on a program that will automatically download an update if the versions don't match. The problem now is that it loads the info from an XML file, but it doesn't download the files specified.

Any suggestions to improve the code are welcome as well!

Here is the complete source code:

http://www.mediafire.com/?44d9mcuhde9fv3e

http://www.virustotal.com/file-scan/report.html?id=178ab584fd87fd84b6fd77f872d9fd08795f5e3957aa8fe7eee03e1fa9440e74-1309401561

Thanks in advance for the help!

EDIT The File to download, specified in Program.cs does not download and the program gets stuck at

currentFile = string.Empty;
                label1.Text = "Preparing to download file(s)...";
                Thread t = new Thread(new ThreadStart(DownloadFiles)); // Making a new thread because I prefer downloading 1 file at a time
                t.Start();

and it start the "Thread t".

Code that seems to be making problems:

UpdateForm.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.NetworkInformation;
using System.Net;
using System.IO;
using System.Threading;
using System.Diagnostics;
using System.Xml;
using System.Xml.Linq;
using System.Runtime.InteropServices;

namespace LauncherBeta1
{
    public partial class UpdateForm : Form
    {
        const int MF_BYPOSITION = 0x400;
        [DllImport("User32")]
        private static extern int RemoveMenu(IntPtr hMenu, int nPosition, int wFlags);
        [DllImport("User32")]
        private static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
        [DllImport("User32")]
        private static extern int GetMenuItemCount(IntPtr hWnd);



        private static WebClient webClient = new WebClient();
        internal static List<Uri> uriFiles = new List<Uri>();
        internal static Uri uriChangelog = null;
        private static long fileSize = 0, fileBytesDownloaded = 0;
        private static Stopwatch fileDownloadElapsed = new Stopwatch();
        bool updateComplete = false, fileComplete = false;
        string currentFile = string.Empty, labelText = string.Empty;
        int progbarValue = 0, KBps = 0;

        public UpdateForm()
        {
            IntPtr hMenu = GetSystemMenu(this.Handle, false);
            int menuItemCount = GetMenuItemCount(hMenu);
            RemoveMenu(hMenu, menuItemCount - 1, MF_BYPOSITION);

            InitializeComponent();

            XmlDocument xdoc = new XmlDocument();
            xdoc.Load("http://raiderz.daregamer.com/updates/app_version.xml");
            XmlNode xNodeVer = xdoc.DocumentElement.SelectSingleNode("Version");
            FileVersionInfo fileVer = FileVersionInfo.GetVersionInfo(AppDomain.CurrentDomain.BaseDirectory + "lua5.1.dll");
            int ver_app = Convert.ToInt32(fileVer.FileVersion.ToString());
            int ver_xml = Convert.ToInt32(xNodeVer);

            if (ver_xml == ver_app)
            {
                Application.Run(new Form1());
                Environment.Exit(0);
            }
            else
            {
                if (ver_xml < ver_app || ver_xml > ver_app)
                {
                    if (uriChangelog != null)
                    {
                        label1.Text = "Status: Downloading changelog...";
                        try
                        {
                            string log = webClient.DownloadString(uriChangelog);
                            log = log.Replace("\n", Environment.NewLine);
                            txtboxChangelog.Text = log;
                        }
                        catch (WebException ex) { }
                    }
                    foreach (Uri uri in uriFiles)
                    {
                        string uriPath = uri.OriginalString;
                        currentFile = uriPath.Substring(uriPath.LastIndexOf('/') + 1);
                        if (File.Exists(currentFile))
                        {
                            label1.Text = "Status: Deleting " + currentFile;
                            File.Delete(currentFile);
                        }
                    }
                    currentFile = string.Empty;
                    label1.Text = "Preparing to download file(s)...";
                    Thread t = new Thread(new ThreadStart(DownloadFiles)); // Making a new thread because I prefer downloading 1 file at a time
                    t.Start();
                }
                else
                {
                    //MessageBox.Show("Client is up to date!");
                    Application.Run(new Form1());
                    Environment.Exit(0);
                }
            }
        }

        private void DownloadFiles()
        {

            foreach (Uri uri in uriFiles)
            {
                try
                {
                    fileComplete = false;
                    fileDownloadElapsed.Reset();
                    fileDownloadElapsed.Start();
                    string uriPath = uri.OriginalString;
                    currentFile = uriPath.Substring(uriPath.LastIndexOf('/') + 1);
                    webClient.DownloadFileAsync(uri, currentFile);
                    webClient.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadFileCompleted);
                    webClient.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadProgressChanged);
                    while (!fileComplete) { Thread.Sleep(1000); }
                }
                catch { continue; }
            }
            currentFile = string.Empty;
            updateComplete = true;
        }

        void DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            progbarValue = e.ProgressPercentage;
            fileSize = e.TotalBytesToReceive / 1024;
            fileBytesDownloaded = e.BytesReceived / 1024;
            if (fileBytesDownloaded > 0 && fileDownloadElapsed.ElapsedMilliseconds > 1000)
            {
                KBps = (int)(fileBytesDownloaded / (fileDownloadElapsed.ElapsedMilliseconds / 1000));
            }
            labelText = "Status: Downloading " + currentFile +
                        "\n" + fileBytesDownloaded + " KB / " + fileSize + " KB - " + KBps + " KB/s";
        }

        void DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            progbarValue = 0;
            fileComplete = true;
        }

        /// <summary>
        /// Returns file size (Kb) of a Uri
        /// </summary>
        /// <param name="uri"></param>
        /// <returns></returns>
        private long GetFileSize(Uri uri)
        {
            try
            {
                WebRequest webRequest = HttpWebRequest.Create(uri);
                using (WebResponse response = webRequest.GetResponse())
                {
                    long size = response.ContentLength;
                    return size / 1024;
                }
            }
            catch { return 1; }
        }

        private void timerMultiPurpose_Tick(object sender, EventArgs e)
        {
            if (updateComplete == true)
            {
                updateComplete = false;
                label1.Text = "Status: Complete";
                progressBar1.Value = 0;
                MessageBox.Show("Update complete!!");
                Application.Run(new Form1());
                Environment.Exit(0);
            }
            else
            {
                progressBar1.Value = progbarValue;
                label1.Text = labelText;
            }
        }

        private void UI_FormClosing(object sender, FormClosingEventArgs e)
        {
            Environment.Exit(0);
        }
    }
}

Relevant code from Program.cs:

    System.Threading.Thread.Sleep(1000); // Give the calling application time to exit
    XmlDocument xdoc = new XmlDocument();
    xdoc.Load("http://raiderz.daregamer.com/updates/app_version.xml");
    XmlNode xNodeVer = xdoc.DocumentElement.SelectSingleNode("Loc");
    string ver_xml = Convert.ToString(xNodeVer);


        args = new string[2];
        args[0] = "Changelog=http://raiderz.daregamer.com/updates/changelog.txt";
        args[1] = "URIs=" + ver_xml;
        if (args.Length == 0)
        {
            MessageBox.Show("Can not run program without parameters", "Error");
            return;
        }

        try
        {
            foreach (string arg in args)
            {
                if (arg.StartsWith("URIs="))
                {
                    string[] uris = arg.Substring(arg.IndexOf('=') + 1).Split(';');
                    foreach (string uri in uris)
                    {
                        if (uri.Length > 0)
                        {
                            UpdateForm.uriFiles.Add(new Uri(uri));
                        }
                    }
                }
                else if (arg.StartsWith("Changelog="))
                {
                    UpdateForm.uriChangelog = new Uri(arg.Substring(arg.IndexOf('=') + 1));
                }
            }
        }
        catch { MessageBox.Show("Missing or faulty parameter(s)", "Error"); }

Upvotes: 0

Views: 1400

Answers (1)

Pat
Pat

Reputation: 5282

I've not downloaded or reviewed your code, but if this is all C# based and on the v2.0 framework or higher you may want to check in to using ClickOnce. It will handle much of the auto updating for you and even allow users to continue using the program if they are offline and unable to connect to your update server.

Upvotes: 1

Related Questions