Last time we started by defining project tasks and did some preparations (Part 1).
Fetching web page
Usually autoupdate launcher reads from update server one file with latest version info and other data. In our project we will read directory index listing. It is a bit more complicated as needs html parsing, but first issue to solve is same – fetching web page.
Simplest would be to use WebClient.
string html; using (var wc = new WebClient()) // "using" keyword automatically closes WebClient stream on download completed { html = wc.DownloadString(textBoxUrl.Text); }
But as we want also to preset web connection timeout it is better to use HttpWebRequest (see for more info What difference is there between WebClient and HTTPWebRequest classes in .NET?)
var request = (HttpWebRequest)WebRequest.Create(textBoxUrl.Text); request.Timeout = 10000; try { using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { using (Stream stream = response.GetResponseStream()) { var sr = new StreamReader(stream); var content = sr.ReadToEnd(); // handle content here } } } catch (WebException we) { if (we.Status == WebExceptionStatus.Timeout) { MessageBox.Show("Error", "Connection to server timed out", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { MessageBox.Show("Error", we.Message, MessageBoxButtons.OK, MessageBoxIcon.Error); } }
Parsing web response
If all went well we have now server directory listing page downloaded to string content. We use IIS but it might not be the always case, for update server Apache or other web server can be used. It means that index page would not be in very solid format, but may vary. Because of this our approach will be to parse all href (url link) tags. No reason to re-invent the wheel – Microsoft offers solution here: Regular Expression Example: Scanning for HREFs .
For showing links we add on form ListBox. Update files are planned to have zip and xml extensions. Later one is for release version and notes. So this is what we will show on screen. As a result index page parser will be something like this :
private void DumpHRefs(string inputString) { listBox1.Items.Clear(); Match m; string fileName; string fileExtenstion; const string HRefPattern = "href\\s*=\\s*(?:[\"'](?<1>[^\"']*)[\"']|(?<1>\\S+))"; try { m = Regex.Match(inputString, HRefPattern, RegexOptions.IgnoreCase | RegexOptions.Compiled, TimeSpan.FromSeconds(1)); while (m.Success) { fileName = Path.GetFileName(m.Groups[1].ToString()); fileExtenstion = Path.GetExtension(m.Groups[1].ToString()).ToUpper(); if (fileExtenstion == ".XML") { listBox1.Items.Add(fileName); } m = m.NextMatch(); } } catch (RegexMatchTimeoutException) { Console.WriteLine("The matching operation timed out."); } }
And will be attache here
var sr = new StreamReader(stream); var content = sr.ReadToEnd(); // handle content here DumpHRefs(content);
For testing purposes we added some dummy files in update directory:
So far we do not have autoupdate so after clicking on update checking the result is:
Next time’s task is to create local settings file, update release file and check if update is needed.