Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using FiftyOne.Foundation.Mobile.Detection;
- using FiftyOne.Foundation.Mobile.Detection.Entities;
- using FiftyOne.Foundation.Mobile.Detection.Factories;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.IO;
- using System.IO.Compression;
- using System.Linq;
- using System.Net;
- using System.Security;
- using System.Security.Cryptography;
- using System.Text;
- using System.Threading.Tasks;
- /*
- * Purpose of this application is to provide an example of how auto update can
- * be used with a custom implementation of the 51Degrees .NET device detection.
- */
- namespace ConsoleApplication1
- {
- class Program
- {
- internal const string AutoUpdateUrl = "https://51degrees.com/Products/Downloads/Premium.aspx";
- internal static string[] licenceKeys = { "YOUR KEY" };
- internal const string tempFile = "C:\\path\\to\\temp.dat";
- internal const string dataFile = "C:\\path\\to\\FOD.dat";
- static void Main(string[] args)
- {
- //Simulate an existing provider.
- Provider p = new Provider(StreamFactory.Create(dataFile));
- Console.Write("Original data file: "+p.DataSet.Name);
- Console.Write(" Published: "+p.DataSet.Published);
- Console.WriteLine(".");
- WebClient client = new WebClient();
- byte[] data = null;
- //Download file.
- Console.Write("Commencing data download.");
- try
- {
- data = client.DownloadData(FullUrl(licenceKeys));
- }
- catch (Exception ex)
- {
- Console.WriteLine("Download failed.");
- }
- Console.WriteLine(" Done.");
- Console.Write("Commencing md5 validation.");
- // Validate the MD5 hash result.
- try
- {
- ValidateMD5(client, data);
- }
- catch (Exception ex)
- {
- Console.WriteLine("md5 validation failed.");
- }
- Console.WriteLine(" Done.");
- //Temporary data set to check try and load data.
- DataSet dataSet = null;
- Console.Write("Commencing data extraction.");
- //Extract data.
- using (var fs = File.Create(tempFile))
- {
- using (var gs = new GZipStream(
- new MemoryStream(data), CompressionMode.Decompress))
- {
- byte[] buffer = new byte[1024 ^ 2];
- int count = 0;
- while ((count = gs.Read(buffer, 0, buffer.Length)) > 0)
- {
- fs.Write(buffer, 0, count);
- }
- }
- }
- Console.WriteLine(" Done.");
- Console.Write("Commencing data check.");
- //Try to test downloaded data.
- dataSet = StreamFactory.Create(tempFile);
- Console.Write(" Dataset: "+dataSet.Name);
- Console.Write(" Published: "+dataSet.Published);
- Console.WriteLine(" Done.");
- //Compare published dates and number of properties to see if it's necessary to update.
- if (dataSet.Published != p.DataSet.Published ||
- dataSet.Properties.Count != p.DataSet.Properties.Count)
- {
- Console.WriteLine("Downloaded file is newer or has more properties, Updating.");
- // Rename the current master file to a temp file so enable the new
- // master file to take it's place and to rollback if there's a problem.
- var temp = String.Format("{0}.tmp", dataFile);
- //Tear down the original provider to release the file.
- Console.Write("Disposing of the current Provider and temporary DataSet to release file locks.");
- p.DataSet.Dispose();
- dataSet.Dispose();
- Console.WriteLine(" Done.");
- //If data file exists move it to temp location.
- Console.Write("Moving existing original data file.");
- if (File.Exists(dataFile))
- File.Move(dataFile, temp);
- Console.WriteLine(" Done.");
- //Copy downloaded data file in place of the existing one.
- Console.Write("Copying the new data file.");
- File.Copy(tempFile, dataFile);
- Console.WriteLine(" Done.");
- //Clean up temporary files.
- Console.Write("Removing temporary data files.");
- if (File.Exists(temp))
- {
- try
- {
- File.Delete(temp);
- } catch (Exception ex) {
- Console.Write(" Failed to delete temp.");
- }
- }
- if (File.Exists(tempFile))
- {
- try
- {
- File.Delete(tempFile);
- }
- catch (Exception ex)
- {
- Console.Write(" Failed to delete temporary downloaded file.");
- }
- }
- Console.WriteLine(" Done.");
- //Create new provider.
- Console.Write("Update finished. Recreating provider.");
- p = new Provider(StreamFactory.Create(dataFile));
- Console.WriteLine(" Done.");
- Console.Write("New file is: "+p.DataSet.Name);
- Console.WriteLine(" Published: "+p.DataSet.Published);
- }
- else
- {
- Console.WriteLine("Update was not required.");
- }
- //Dispose of the dataset.
- p.DataSet.Dispose();
- Console.ReadLine();
- }
- /// <summary>
- /// Used to get the url for data download.
- /// </summary>
- /// <param name="licences">An array of licences to try.</param>
- /// <returns>The full url including all parameters needed to download
- /// the device data file.</returns>
- internal static string FullUrl(string[] licences)
- {
- List<string> parameters = new List<string>();
- parameters.Add(String.Format("LicenseKeys={0}", String.Join("|", licences)));
- parameters.Add(String.Format("Download={0}", bool.TrueString));
- parameters.Add("Type=BinaryV3");
- return String.Format("{0}?{1}",
- AutoUpdateUrl,
- String.Join("&", parameters.ToArray()));
- }
- /// <summary>
- /// Checks the MD5 hash of the data against the expected value.
- /// </summary>
- /// <param name="client"></param>
- /// <param name="data"></param>
- internal static void ValidateMD5(WebClient client, byte[] data)
- {
- // Check the MD5 hash of the data downloaded.
- string mdHash = client.ResponseHeaders["Content-MD5"];
- if (mdHash != GetMd5Hash(data))
- throw new Exception(String.Format(
- "MD5 hash '{0}' validation failure with data downloaded from update URL '{1}'.",
- mdHash,
- client.BaseAddress));
- }
- private static string GetMd5Hash(byte[] value)
- {
- using (MD5 md5Hash = MD5.Create())
- return GetMd5Hash(md5Hash, value);
- }
- private static string GetMd5Hash(MD5 md5Hash, byte[] value)
- {
- if (value == null)
- return String.Empty;
- // Convert the input string to a byte array and compute the hash.
- byte[] data = md5Hash.ComputeHash(value);
- // Create a new Stringbuilder to collect the bytes
- // and create a string.
- StringBuilder sBuilder = new StringBuilder();
- // Loop through each byte of the hashed data
- // and format each one as a hexadecimal string.
- for (int i = 0; i < data.Length; i++)
- {
- sBuilder.Append(data[i].ToString("x2"));
- }
- // Return the hexadecimal string.
- return sBuilder.ToString();
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement