List:Commits« Previous MessageNext Message »
From:Iggy Galarza Date:March 23 2011 12:27pm
Subject:bzr commit into wex-installer-1.0 branch (iggy:379)
View as plain text  
#At file:///C:/src/bzr.mysql/wex/installer/ based on revid:mike.lischke@stripped

  379 Iggy Galarza	2011-03-23
      ProductCacheUpdate - Include 64-bit packages in the WiX fragment.

    modified:
      ProductCacheUpdate/Program.cs
=== modified file 'ProductCacheUpdate/Program.cs'
--- a/ProductCacheUpdate/Program.cs	2011-03-10 03:08:26 +0000
+++ b/ProductCacheUpdate/Program.cs	2011-03-23 12:27:08 +0000
@@ -13,374 +13,402 @@ using WexInstaller.Core;
 
 namespace ProductCacheUpdate
 {
-    public class ConsolePoint
+  public class ConsolePoint
+  {
+    public int Top { get; set; }
+    public int Left { get; set; }
+    public ConsolePoint(int top, int left)
     {
-        public int Top { get; set; }
-        public int Left { get; set; }
-        public ConsolePoint(int top, int left)
-        {
-            Top = top;
-            Left = left;
-        }
+      Top = top;
+      Left = left;
     }
-    public class MSIPackage
-    {
-        public Version Version { get; set; }
-        public String FileMask { get; set; }
-        public String ProductName { get { return FileMask.Substring(0, FileMask.IndexOf("{0}")); } }
-        public String ProductFamily { get { return Version.ToString(2); } }
-        public WebClient wc { get; private set; }
-        public ConsolePoint cp { get; set; }
+  }
+  public class MSIPackage
+  {
+    public Version Version { get; set; }
+    public String FileMask { get; set; }
+    public String ProductName { get { return FileMask.Substring(0, FileMask.IndexOf("{0}")); } }
+    public String ProductFamily { get { return Version.ToString(2); } }
+    public WebClient WC { get; private set; }
+    public ConsolePoint CP { get; set; }
+    public bool Has64bitTwin { get; set; }
 
-        private void SetDefaults(string fileMask, Version version)
-        {
-            FileMask = fileMask;
-            Version = version;
-            wc = new WebClient();
-        }
-
-        public MSIPackage()
-        {
-            SetDefaults(String.Empty, new Version("0.0"));
-        }
-        public MSIPackage(string fileMask)
-        {
-            SetDefaults(fileMask, new Version("0.0"));
-        }
-        public MSIPackage(Version version)
-        {
-            SetDefaults(String.Empty, version);
-        }
-        public MSIPackage(string fileMask, Version version)
-        {
-            SetDefaults(fileMask, version);
-        }
+    private void SetDefaults(string fileMask, Version version)
+    {
+      FileMask = fileMask;
+      Version = version;
+      WC = new WebClient();
+      Has64bitTwin = false;
     }
 
-    class Program
+    public MSIPackage()
     {
-        static AutoResetEvent consoleHandle = new AutoResetEvent(true);
-        static Dictionary<string, MSIPackage> myMSIs = null;
-
-        static void ShowHelp(OptionSet option_set, string message)
-        {
-            Console.Error.WriteLine(message);
-            option_set.WriteOptionDescriptions(Console.Error);
-            Environment.Exit(-1);
-        }
-
-        static void Main(string[] args)
-        {
-            // Required parameters
-            string msiCacheDir = null;
-
-            // Optional parameters
-            bool help = false;
-            bool skip_updates = false;
-            bool use_x64 = false;
-            string wixFrgamentFile = null;
-            string msiProductFamily = null;
-            string msiPreferredPlatform = null;
-
-            // Parse our command line args
-            OptionSet theOptionSet = new OptionSet()
-              .Add("?|help|h", "Prints out the options.", option => help = option != null)
-              .Add("s|skip_update", "Does not attempt to find or download new MSIs.", option => skip_updates = option != null)
-              .Add("w:|wixfrag:", "Create a WiX Fragment.", option => wixFrgamentFile = option)
-              .Add("f:|family:", "Displays the latest MSI in a family.", option => msiProductFamily = option)
-              .Add("p=|platform=", "Favor MSIs of type win32 or x64", option => msiPreferredPlatform = option)
-              .Add("cachedir=|cache=", "MSI Cache location", option => msiCacheDir = option);
-
-            try
-            {
-                theOptionSet.Parse(args);
-
-                if (help)
-                {
-                    ShowHelp(theOptionSet, "Option description");
-                }
-
-                if (msiCacheDir == null)
-                {
-                    ShowHelp(theOptionSet, "Must supply cache directory.");
-                }
-                else
-                {
-                    if (!msiCacheDir.EndsWith("\\"))
-                    {
-                        msiCacheDir += "\\";
-                    }
-                }
+      SetDefaults(String.Empty, new Version("0.0"));
+    }
+    public MSIPackage(string fileMask)
+    {
+      SetDefaults(fileMask, new Version("0.0"));
+    }
+    public MSIPackage(Version version)
+    {
+      SetDefaults(String.Empty, version);
+    }
+    public MSIPackage(string fileMask, Version version)
+    {
+      SetDefaults(fileMask, version);
+    }
+  }
 
-                if (msiPreferredPlatform != null)
-                {
-                    use_x64 = (msiPreferredPlatform != "win32");
-                }
+  class Program
+  {
+    static ManualResetEvent consoleHandle = new ManualResetEvent(true);
+    static Dictionary<string, MSIPackage> myMSIs = null;
 
-                myMSIs = new Dictionary<string, MSIPackage>();
-                PopulateMSIList(msiCacheDir);
+    static void ShowHelp(OptionSet option_set, string message)
+    {
+      Console.Error.WriteLine(message);
+      option_set.WriteOptionDescriptions(Console.Error);
+      Environment.Exit(-1);
+    }
 
-                if (!skip_updates)
-                {
-                    int updates = SearchForMSIUpdates();
-                    if (updates > 0)
-                    {
-                        if (Console.CursorTop <= updates)
-                            Console.SetCursorPosition(0, updates + 1);
-                        Console.WriteLine(String.Format("Downloaded {0} update(s).", updates.ToString()));
-                        
-                        // The files are downloaded to the working directory and then moved into the cache dir when the download is complete.
-                        string[] files = Directory.GetFiles(".", "*.msi");
-                        foreach (string file in files)
-                        {
-                            try
-                            {
-                                File.Move(file, msiCacheDir + file);
-                            }
-                            catch
-                            {
-                                // Disk error?
-                            }
-                        }
-                    }
-                }
+    static void Main(string[] args)
+    {
+      // Required parameters
+      string msiCacheDir = null;
 
-                if (msiProductFamily != null)
-                {
-                    if (myMSIs.ContainsKey(msiProductFamily))
-                        Console.WriteLine(String.Format(myMSIs[msiProductFamily].FileMask, myMSIs[msiProductFamily].Version.ToString()));
-                }
+      // Optional parameters
+      bool help = false;
+      bool skip_updates = false;
+      //bool use_x64 = false;
+      string wixFrgamentFile = null;
+      string msiProductFamily = null;
+      //string msiPreferredPlatform = null;
 
-                if (wixFrgamentFile != null)
-                {
-                    // Write the output.
-                    StreamWriter outStream = new StreamWriter(wixFrgamentFile, false);
-                    outStream.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
-                    outStream.WriteLine("<Wix xmlns=\"http://schemas.microsoft.com/wix/2006/wi\">");
-                    outStream.WriteLine("  <Fragment>");
-                    outStream.WriteLine("    <DirectoryRef Id=\"UniversalInstaller\">");
-                    outStream.WriteLine("      <Directory Id=\"ProductCache\" Name=\"Product Cache\">");
-
-                    if (myMSIs.Count > 0)
-                    {
-                        outStream.WriteLine("        <Component Id=\"Products\" Guid=\"\">");
-
-                        foreach (string key in myMSIs.Keys)
-                        {
-                            string fileName = String.Format(myMSIs[key].FileMask, myMSIs[key].Version.ToString());
-                            // This seems contrived but for the sake of testing I'll try to keep the output in line with known good.
-                            string wixID = key.Replace("mysql-", "");
-                            if (wixID.Length == 3)
-                            {
-                                wixID = "server_" + wixID;
-                            }
-                            wixID = wixID.Replace(".", "");
-                            wixID = wixID.Replace("-", "_");
-                            wixID = wixID.Replace("++", "pp");
-
-                            bool includeInFragment = true;
-
-                            if (msiProductFamily != null)
-                            {
-                                if (wixID.StartsWith("server") || wixID.StartsWith("examples"))
-                                {
-                                    includeInFragment = (msiProductFamily.Substring(msiProductFamily.LastIndexOf('-') + 1).Replace(".", "") == wixID.Substring(wixID.LastIndexOf('_') + 1));
-                                }
-                            }
-
-                            if (includeInFragment)
-                                outStream.WriteLine(String.Format("          <File Id=\"{0}\" Name=\"{1}\" Source=\"{2}\"/>",
-                                                                  wixID, fileName, msiCacheDir + fileName));
-                        }
-                    }
-                    else
-                    {
-                        // Write the WEB fragment.
-                        outStream.WriteLine("        <Component Id=\"Products\" Guid=\"\">");
-                        outStream.WriteLine("          <CreateFolder/>");
-                    }
-
-                    outStream.WriteLine("        </Component>");
-                    outStream.WriteLine("      </Directory>");
-                    outStream.WriteLine("    </DirectoryRef>");
-                    outStream.WriteLine("  </Fragment>");
-                    outStream.WriteLine("</Wix>");
+      // Parse our command line args
+      OptionSet theOptionSet = new OptionSet()
+        .Add("?|help|h", "Prints out the options.", option => help = option != null)
+        .Add("s|skip_update", "Does not attempt to find or download new MSIs.", option => skip_updates = option != null)
+        .Add("w:|wixfrag:", "Create a WiX Fragment.", option => wixFrgamentFile = option)
+        .Add("f:|family:", "Displays the latest MSI in a family.", option => msiProductFamily = option)
+        .Add("cachedir=|cache=", "MSI Cache location", option => msiCacheDir = option);
 
-                    outStream.Close();
-                }
+      try
+      {
+        theOptionSet.Parse(args);
 
-            }
-            catch (OptionException)
-            {
-                ShowHelp(theOptionSet, "Wrong syntax:");
-            }
+        if (help)
+        {
+          ShowHelp(theOptionSet, "Option description");
         }
 
-        static string GetProperty(string msiFile, string property)
+        if (msiCacheDir == null)
         {
-            using (Database d = new Database(msiFile, OpenDatabase.ReadOnly))
-            {
-                string sql = String.Format("SELECT * FROM `Property` WHERE `Property`.`Property` = '{0}'", property);
-                View view = d.OpenView(sql);
-                view.Execute();
-                Record record = view.Fetch();
-                if (record == null) return String.Empty;
-                return record.GetString(2);
-            }
+          ShowHelp(theOptionSet, "Must supply cache directory.");
         }
-
-        static void PopulateMSIList(string cacheDirectory)
+        else
         {
-            // Open Product Cache directory and get a list of files 
-            string[] files = Directory.GetFiles(cacheDirectory, "*.msi");
-            foreach (string file in files)
-            {
-                MSIPackage thisPackage = new MSIPackage(new Version(GetProperty(file, "ProductVersion")));
-                string thisFileName = file.Substring(file.LastIndexOf('\\') + 1);
-                string thisVersionText = thisPackage.Version.ToString();
-
-                thisPackage.FileMask = thisFileName.Substring(0, thisFileName.IndexOf(thisVersionText));
-                thisPackage.FileMask += "{0}";
-                thisPackage.FileMask += thisFileName.Substring(thisFileName.IndexOf(thisVersionText) + thisVersionText.Length);
-
-                if (myMSIs.ContainsKey(thisPackage.ProductName + thisPackage.ProductFamily))
-                {
-                    // Check to see if this file has a higher version.
-                    if (myMSIs[thisPackage.ProductName + thisPackage.ProductFamily].Version < thisPackage.Version)
-                    {
-                        myMSIs[thisPackage.ProductName + thisPackage.ProductFamily] = thisPackage;
-                    }
-                }
-                else
-                {
-                    myMSIs.Add(thisPackage.ProductName + thisPackage.ProductFamily, thisPackage);
-                }
-            }
+          if (!msiCacheDir.EndsWith("\\"))
+          {
+            msiCacheDir += "\\";
+          }
         }
 
-        static void DownloadMSIComplete(object sender, AsyncCompletedEventArgs e)
+        myMSIs = new Dictionary<string, MSIPackage>();
+        PopulateMSIList(msiCacheDir);
+
+        if (!skip_updates)
         {
-            MSIPackage pack = (e.UserState as MSIPackage);
-            if (!(e.Cancelled == false && e.Error == null))
+          int updates = SearchForMSIUpdates();
+          if (updates > 0)
+          {
+            if (Console.CursorTop <= updates)
+                Console.SetCursorPosition(0, updates + 1);
+            Console.WriteLine(String.Format("Downloaded {0} update(s).", updates.ToString()));
+                        
+            // The files are downloaded to the working directory and then moved into the cache dir when the download is complete.
+            string[] files = Directory.GetFiles(".", "*.msi");
+            foreach (string file in files)
             {
-                pack.Version = new Version(pack.Version.Major, pack.Version.Minor, pack.Version.Build - 1);
+              try
+              {
+                File.Move(file, msiCacheDir + file);
+              }
+              catch
+              {
+                // Disk error?
+              }
             }
+          }
         }
 
-        static void DownloadMSIProgressChanged(object sender, DownloadProgressChangedEventArgs e)
+        if (msiProductFamily != null)
         {
-            if (consoleHandle.WaitOne(1000))
-            {
-                consoleHandle.Reset();
-                MSIPackage pack = (e.UserState as MSIPackage);
-                Console.SetCursorPosition(pack.cp.Left, pack.cp.Top);
-                Console.WriteLine( String.Format("{0}%", e.ProgressPercentage.ToString()));
-                consoleHandle.Set();
-            }
+          if (myMSIs.ContainsKey(msiProductFamily))
+          {
+            String alteredFileMask = myMSIs[msiProductFamily].FileMask;
+            alteredFileMask = alteredFileMask.Remove(alteredFileMask.IndexOf("win32"), "-win32".Length);
+            String output = String.Format(alteredFileMask, myMSIs[msiProductFamily].Version.ToString());
+            Console.WriteLine(output);
+          }
         }
 
-        static int SearchForMSIUpdates()
+        if (wixFrgamentFile != null)
         {
-            int totalDownloads = 0;
+          // Write the output.
+          StreamWriter outStream = new StreamWriter(wixFrgamentFile, false);
+          outStream.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+          outStream.WriteLine("<Wix xmlns=\"http://schemas.microsoft.com/wix/2006/wi\">");
+          outStream.WriteLine("  <Fragment>");
+          outStream.WriteLine("    <DirectoryRef Id=\"UniversalInstaller\">");
+          outStream.WriteLine("      <Directory Id=\"ProductCache\" Name=\"Product Cache\">");
+
+          if (myMSIs.Count > 0)
+          {
+            outStream.WriteLine("        <Component Id=\"Products\" Guid=\"\">");
 
-            // Attempt to download newer version of the existing files.
             foreach (string key in myMSIs.Keys)
             {
-                Version nextVersion = new Version(myMSIs[key].Version.Major,
-                                                  myMSIs[key].Version.Minor,
-                                                  myMSIs[key].Version.Build + 1);
-                string nextFileName = String.Format(myMSIs[key].FileMask, nextVersion.ToString());
-                Queue<string> possibleMirrors = ProcessMirrorList(nextFileName);
-
-                foreach (string address in possibleMirrors)
-                {
-                    Uri mirror = new Uri(address);
-                    try
-                    {
-                        if (consoleHandle.WaitOne(1000))
-                        {
-                            consoleHandle.Reset();
-                            Console.SetCursorPosition(0, totalDownloads);
-                            Console.Write(String.Format("Downloading {0}: ", nextFileName));
-                            myMSIs[key].cp = new ConsolePoint(Console.CursorTop, Console.CursorLeft);
-                            Console.WriteLine("|");
-                            consoleHandle.Set();
-
-                            myMSIs[key].Version = nextVersion;
-                            myMSIs[key].wc.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadMSIComplete);
-                            myMSIs[key].wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadMSIProgressChanged);
-                            //myMSIs[key].wc.DownloadFileAsync(mirror, String.Format("{0}{1}", cacheDirectory, nextFileName), myMSIs[key]);
-                            myMSIs[key].wc.DownloadFileAsync(mirror, nextFileName, myMSIs[key]);
-                            totalDownloads += 1;
-                        }
-                        break;
-                    }
-                    catch (Exception)
-                    {
-                        // Likely some disk error.
-                    }
+              string fileName = String.Format(myMSIs[key].FileMask, myMSIs[key].Version.ToString());
+              // This seems contrived but for the sake of testing I'll try to keep the output in line with known good.
+              string wixID = key.Replace("mysql-", "");
+              if (wixID.Length == 3)
+              {
+                wixID = "server_x86_" + wixID;
+              }
+              wixID = wixID.Replace(".", "");
+              wixID = wixID.Replace("-", "_");
+              wixID = wixID.Replace("++", "pp");
+
+              bool includeInFragment = true;
+
+              if (msiProductFamily != null)
+              {
+                if (wixID.StartsWith("server") || wixID.StartsWith("examples"))
+                {
+                  includeInFragment = (msiProductFamily.Substring(msiProductFamily.LastIndexOf('-') + 1).Replace(".", "") == wixID.Substring(wixID.LastIndexOf('_') + 1));
+                }
+              }
+
+              if (includeInFragment)
+              {
+                outStream.WriteLine(String.Format("          <File Id=\"{0}\" Name=\"{1}\" Source=\"{2}\"/>",
+                                                  wixID, fileName, msiCacheDir + fileName));
+                if (myMSIs[key].Has64bitTwin)
+                {
+                  wixID = wixID.Replace("x86", "x64");
+                  fileName = fileName.Replace("win32", "winx64");
+                  outStream.WriteLine(String.Format("          <File Id=\"{0}\" Name=\"{1}\" Source=\"{2}\"/>",
+                                                    wixID, fileName, msiCacheDir + fileName));
                 }
+              }
+
 
-                possibleMirrors.Clear();
             }
+          }
+          else
+          {
+            // Write the WEB fragment.
+            outStream.WriteLine("        <Component Id=\"Products\" Guid=\"\">");
+            outStream.WriteLine("          <CreateFolder/>");
+          }
+
+          outStream.WriteLine("        </Component>");
+          outStream.WriteLine("      </Directory>");
+          outStream.WriteLine("    </DirectoryRef>");
+          outStream.WriteLine("  </Fragment>");
+          outStream.WriteLine("</Wix>");
+
+          outStream.Close();
+        }
+
+      }
+      catch (OptionException)
+      {
+        ShowHelp(theOptionSet, "Wrong syntax:");
+      }
+    }
 
-            // Wait for all downloads to complete.
-            bool allDownloadsFinished = true;
-            do
-            {
-                allDownloadsFinished = true;
-                foreach (MSIPackage msi in myMSIs.Values)
-                {
-                    allDownloadsFinished &= !msi.wc.IsBusy;
-                }
-            } while (!allDownloadsFinished);
+    static string GetProperty(string msiFile, string property)
+    {
+      using (Database d = new Database(msiFile, OpenDatabase.ReadOnly))
+      {
+        string sql = String.Format("SELECT * FROM `Property` WHERE `Property`.`Property` = '{0}'", property);
+        View view = d.OpenView(sql);
+        view.Execute();
+        Record record = view.Fetch();
+        if (record == null) return String.Empty;
+        return record.GetString(2);
+      }
+    }
 
-            return totalDownloads;
+    static void PopulateMSIList(string cacheDirectory)
+    {
+      // Open Product Cache directory and get a list of files 
+      string[] files = Directory.GetFiles(cacheDirectory, "*.msi");
+      foreach (string file in files)
+      {
+        MSIPackage thisPackage = new MSIPackage(new Version(GetProperty(file, "ProductVersion")));
+        string thisFileName = file.Substring(file.LastIndexOf('\\') + 1);
+        string thisVersionText = thisPackage.Version.ToString();
+
+        thisPackage.FileMask = thisFileName.Substring(0, thisFileName.IndexOf(thisVersionText));
+        thisPackage.FileMask += "{0}";
+        thisPackage.FileMask += thisFileName.Substring(thisFileName.IndexOf(thisVersionText) + thisVersionText.Length);
+        thisPackage.Has64bitTwin = thisFileName.Contains("x64");
+
+        if (myMSIs.ContainsKey(thisPackage.ProductName + thisPackage.ProductFamily))
+        {
+          // Check to see if this file has a higher version.
+          if (myMSIs[thisPackage.ProductName + thisPackage.ProductFamily].Version < thisPackage.Version)
+          {
+            myMSIs[thisPackage.ProductName + thisPackage.ProductFamily] = thisPackage;
+          }
+          // Two instances of the same version indicates 32 and 64 bit versions.
+          else if (myMSIs[thisPackage.ProductName + thisPackage.ProductFamily].Version == thisPackage.Version)
+          {
+            if (thisPackage.Has64bitTwin)
+            {
+              // Keep the 32-bit package and indicate the 64-bit package exists.
+              myMSIs[thisPackage.ProductName + thisPackage.ProductFamily].Has64bitTwin = true;
+            }
+            else
+            {
+              // Replace the 64-bit package with the 32-bit version and indicate that a 64-bit package exists.
+              thisPackage.Has64bitTwin = true;
+              myMSIs[thisPackage.ProductName + thisPackage.ProductFamily] = thisPackage;
+            }
+          }
         }
-
-        static Queue<string> ProcessMirrorList(string fileName)
+        else
         {
-            Uri mirrorUri = new Uri(String.Format("http://dev.mysql.com/downloads/get_mirror.php?filename={0}", fileName));
-            WebClient wc = new WebClient();
-            String mirrorList = wc.DownloadString(mirrorUri);
-            mirrorList = Regex.Replace(mirrorList, "<ip", "<IP");
-            mirrorList = Regex.Replace(mirrorList, "ip>", "IP>");
-
-            Queue<string> MirrorList = new Queue<string>();
+          myMSIs.Add(thisPackage.ProductName + thisPackage.ProductFamily, thisPackage);
+        }
+      }
+    }
 
-            // Parse the mirror list here.
-            XmlRootAttribute thisRequest = new XmlRootAttribute("request");
-            XmlSerializer s = new XmlSerializer(typeof(WexInstaller.IP[]), thisRequest);
-            TextReader w = new StringReader(mirrorList);
-            WexInstaller.IP[] httpMirrors = (WexInstaller.IP[])s.Deserialize(w);
-            if (httpMirrors.Length > 0)
-            {
-                Queue<string> altMirrorList = new Queue<string>();
+    static void DownloadMSIComplete(object sender, AsyncCompletedEventArgs e)
+    {
+      MSIPackage pack = (e.UserState as MSIPackage);
+      if (!(e.Cancelled == false && e.Error == null))
+      {
+        pack.Version = new Version(pack.Version.Major, pack.Version.Minor, pack.Version.Build - 1);
+      }
+    }
 
-                foreach (WexInstaller.Mirror m in httpMirrors[0].Mirrors)
-                {
-                    if (m.Primary == "1")
-                    {
-                        if (m.Http_Url != null)
-                            MirrorList.Enqueue(m.Http_Url);
-                    }
-                    else
-                    {
-                        if (m.Http_Url != null)
-                            altMirrorList.Enqueue(m.Http_Url);
-                    }
-                }
+    static void DownloadMSIProgressChanged(object sender, DownloadProgressChangedEventArgs e)
+    {
+      if (consoleHandle.WaitOne(1000))
+      {
+        consoleHandle.Reset();
+        MSIPackage pack = (e.UserState as MSIPackage);
+        Console.SetCursorPosition(pack.CP.Left, pack.CP.Top);
+        Console.WriteLine( String.Format("{0}%", e.ProgressPercentage.ToString()));
+        consoleHandle.Set();
+      }
+    }
 
-                foreach (string m in altMirrorList)
-                {
-                    MirrorList.Enqueue(m);
-                }
+    static int SearchForMSIUpdates()
+    {
+      int totalDownloads = 0;
 
-                if (String.IsNullOrEmpty(httpMirrors[0].Archive) == false)
-                    MirrorList.Enqueue(httpMirrors[0].Archive);
+      // Attempt to download newer version of the existing files.
+      foreach (string key in myMSIs.Keys)
+      {
+        Version nextVersion = new Version(myMSIs[key].Version.Major,
+                                          myMSIs[key].Version.Minor,
+                                          myMSIs[key].Version.Build + 1);
+        string nextFileName = String.Format(myMSIs[key].FileMask, nextVersion.ToString());
+        Queue<string> possibleMirrors = ProcessMirrorList(nextFileName);
+
+        foreach (string address in possibleMirrors)
+        {
+          Uri mirror = new Uri(address);
+          try
+          {
+            if (consoleHandle.WaitOne(1000))
+            {
+              consoleHandle.Reset();
+              Console.SetCursorPosition(0, totalDownloads);
+              Console.Write(String.Format("Downloading {0}: ", nextFileName));
+              myMSIs[key].CP = new ConsolePoint(Console.CursorTop, Console.CursorLeft);
+              Console.WriteLine("|");
+              consoleHandle.Set();
+
+              myMSIs[key].Version = nextVersion;
+              myMSIs[key].WC.DownloadFileCompleted += new AsyncCompletedEventHandler(DownloadMSIComplete);
+              myMSIs[key].WC.DownloadProgressChanged += new DownloadProgressChangedEventHandler(DownloadMSIProgressChanged);
+              //myMSIs[key].wc.DownloadFileAsync(mirror, String.Format("{0}{1}", cacheDirectory, nextFileName), myMSIs[key]);
+              myMSIs[key].WC.DownloadFileAsync(mirror, nextFileName, myMSIs[key]);
+              totalDownloads += 1;
             }
+            break;
+          }
+          catch (Exception)
+          {
+            // Likely some disk error.
+          }
+        }
+
+        possibleMirrors.Clear();
+      }
 
-            return MirrorList;
+      // Wait for all downloads to complete.
+      bool allDownloadsFinished = true;
+      do
+      {
+        allDownloadsFinished = true;
+        foreach (MSIPackage msi in myMSIs.Values)
+        {
+          allDownloadsFinished &= !msi.WC.IsBusy;
         }
+      } while (!allDownloadsFinished);
+
+      return totalDownloads;
+    }
+
+    static Queue<string> ProcessMirrorList(string fileName)
+    {
+      Uri mirrorUri = new Uri(String.Format("http://dev.mysql.com/downloads/get_mirror.php?filename={0}", fileName));
+      WebClient wc = new WebClient();
+      String mirrorList = wc.DownloadString(mirrorUri);
+      mirrorList = Regex.Replace(mirrorList, "<ip", "<IP");
+      mirrorList = Regex.Replace(mirrorList, "ip>", "IP>");
+
+      Queue<string> MirrorList = new Queue<string>();
+
+      // Parse the mirror list here.
+      XmlRootAttribute thisRequest = new XmlRootAttribute("request");
+      XmlSerializer s = new XmlSerializer(typeof(WexInstaller.IP[]), thisRequest);
+      TextReader w = new StringReader(mirrorList);
+      WexInstaller.IP[] httpMirrors = (WexInstaller.IP[])s.Deserialize(w);
+      if (httpMirrors.Length > 0)
+      {
+        Queue<string> altMirrorList = new Queue<string>();
+
+        foreach (WexInstaller.Mirror m in httpMirrors[0].Mirrors)
+        {
+          if (m.Primary == "1")
+          {
+            if (m.Http_Url != null)
+              MirrorList.Enqueue(m.Http_Url);
+          }
+          else
+          {
+            if (m.Http_Url != null)
+              altMirrorList.Enqueue(m.Http_Url);
+          }
+        }
+
+        foreach (string m in altMirrorList)
+        {
+          MirrorList.Enqueue(m);
+        }
+
+        if (String.IsNullOrEmpty(httpMirrors[0].Archive) == false)
+          MirrorList.Enqueue(httpMirrors[0].Archive);
+      }
+
+      return MirrorList;
     }
+  }
 }


Attachment: [text/bzr-bundle] bzr/iggy@mysql.com-20110323122708-2lprhwlczsrs2srr.bundle
Thread
bzr commit into wex-installer-1.0 branch (iggy:379) Iggy Galarza23 Mar