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

  360 Iggy Galarza	2011-03-09
      Refactored Product MakeChanges notification.
      Added command-line shell project.

    added:
      WexCmd/
      WexCmd/Program.cs
      WexCmd/WexCmd.csproj
      WexCmd/app.config
    modified:
      ProductCacheUpdate/Program.cs
      WexInstaller.Core/InstallerConfiguration.cs
      WexInstaller.Core/Product.cs
      WexInstaller.Core/ProductManager.cs
      WexInstaller/Controls/RemoveAllPage.cs
      WexInstaller/InstallWizard/InstallProgressPanel.cs
      WexInstaller/InstallWizard/InstallType.cs
      WexInstaller/InstallWizard/LicenseAgreement.cs
      WexInstaller/Program.cs
      WexInstaller/RemovePanels/RemoveProgress.cs
      installer-vs2010.sln
=== modified file 'ProductCacheUpdate/Program.cs'
--- a/ProductCacheUpdate/Program.cs	2011-03-02 22:27:21 +0000
+++ b/ProductCacheUpdate/Program.cs	2011-03-10 03:08:26 +0000
@@ -77,8 +77,10 @@ namespace ProductCacheUpdate
             // 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()
@@ -86,6 +88,7 @@ namespace ProductCacheUpdate
               .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
@@ -109,6 +112,11 @@ namespace ProductCacheUpdate
                     }
                 }
 
+                if (msiPreferredPlatform != null)
+                {
+                    use_x64 = (msiPreferredPlatform != "win32");
+                }
+
                 myMSIs = new Dictionary<string, MSIPackage>();
                 PopulateMSIList(msiCacheDir);
 
@@ -155,7 +163,7 @@ namespace ProductCacheUpdate
 
                     if (myMSIs.Count > 0)
                     {
-                        outStream.WriteLine("        <Component Id=\"Products\" Guid=\"88D9D419-FCCB-4B4B-881E-FAE4D29C81B9\" Permanent=\"yes\">");
+                        outStream.WriteLine("        <Component Id=\"Products\" Guid=\"\">");
 
                         foreach (string key in myMSIs.Keys)
                         {
@@ -201,7 +209,6 @@ namespace ProductCacheUpdate
                     outStream.Close();
                 }
 
-                //Console.ReadLine();
             }
             catch (OptionException)
             {

=== added directory 'WexCmd'
=== added file 'WexCmd/Program.cs'
--- a/WexCmd/Program.cs	1970-01-01 00:00:00 +0000
+++ b/WexCmd/Program.cs	2011-03-10 03:08:26 +0000
@@ -0,0 +1,399 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Net;
+using System.Text;
+using System.Threading;
+using Mono.Options;
+using WexInstaller.Core;
+
+
+namespace WexCmd
+{
+    class Program
+    {
+        static List<string> productDownloadList = null;
+        static List<string> productInstallList = null;
+        static ManualResetEvent consoleOutput = new ManualResetEvent(true);
+        static ManualResetEvent msiDBLock = new ManualResetEvent(true);
+
+        static void ShowHelp(OptionSet option_set, string message)
+        {
+            Console.Error.WriteLine();
+            Console.Error.WriteLine(message);
+            Console.Error.WriteLine("Usage: WexCmd.exe -action=install");
+            option_set.WriteOptionDescriptions(Console.Error);
+
+            Console.WriteLine("Press Enter to continue.");
+            Console.ReadLine();
+            Environment.Exit(-1);
+        }
+
+        // Update Manifest.
+        static void GetProductUpdates()
+        {
+            // Hook up the Console for correct output.
+            ProductManager.DownloadManifest();
+            // Wait for downloads to complete
+        }
+
+        // Downloads and event handlers.
+        static void ProductDownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
+        {
+            Product p = (sender as Product);
+            if (p == null)
+                return;
+            int updateRow = productInstallList.IndexOf(p.Name);
+
+            if (consoleOutput.WaitOne(1000))
+            {
+                consoleOutput.Reset();
+                Console.SetCursorPosition(0, updateRow);
+                Console.WriteLine(String.Format("{0} - {1} : Download {2}% complete", updateRow, p.Name, e.ProgressPercentage));
+                consoleOutput.Set();
+            }
+        }
+
+        static void ProductDownloadCompleted(object sender, AsyncCompletedEventArgs e)
+        {
+            Product p = sender as Product;
+            if (p == null)
+                return;
+
+            lock (productDownloadList)
+            {
+                productDownloadList.Remove(p.Name);
+            }
+        }
+
+        static void ProductDownload()
+        {
+            foreach (string downloadProduct in productDownloadList)
+            {
+                Product p = ProductManager.GetProductById(downloadProduct);
+
+                p.DownloadProductProgressChanged += new DownloadProductProgressHandler(ProductDownloadProgressChanged);
+                p.DownloadProductCompleted += new DownloadProductCompleteHandler(ProductDownloadCompleted);
+                p.Download();
+            }
+
+            // Wait for all downloads to complete.
+            while (productDownloadList.Count > 0)
+            {
+                Thread.SpinWait(1000);
+            }
+        }
+
+        // Installs and event handlers.
+      /*
+        static void ProductInstallProgressChanged(object sender, ChainedInstallerEventArgs e)
+        {
+            Product p = (sender as Product);
+
+            switch (e.Action)
+            {
+                case ChainedInstallerAction.StartInstallation:
+                    break;
+                case ChainedInstallerAction.HandleActionData:
+                    break;
+                case ChainedInstallerAction.HandleActionStart:
+                    break;
+                case ChainedInstallerAction.ProgressSetRange:
+                    break;
+                case ChainedInstallerAction.ProgressSetStep:
+                    break;
+                case ChainedInstallerAction.ProgressSetPosition:
+                    int currentIndex = productInstallList.IndexOf(p.Name);
+                    if (consoleOutput.WaitOne(1000))
+                    {
+                        consoleOutput.Reset();
+                        Console.SetCursorPosition(0, currentIndex);
+                        Console.WriteLine(String.Format("{0} - {1} : Installing {2} % Complete.", currentIndex, p.Name, e.ProgressPosition));
+                        consoleOutput.Set();
+                    }
+                    break;
+                case ChainedInstallerAction.ProgressSingleStep:
+                    break;
+                case ChainedInstallerAction.EndInstallation:
+                    break;
+                case ChainedInstallerAction.FinalAction:
+                    // Free the main thread.
+                    msiDBLock.Set();
+                    break;
+                case ChainedInstallerAction.LogEvent:
+                    break;
+            }
+        }
+      */
+        static void ProductInstallProgressChanged(object sender, ProductMSIActionProgressEventArgs pe)
+        {
+          Product p = (sender as Product);
+
+          int currentIndex = productInstallList.IndexOf(p.Name);
+          if (consoleOutput.WaitOne(1000))
+          {
+            consoleOutput.Reset();
+            Console.SetCursorPosition(0, currentIndex);
+            Console.WriteLine(String.Format("{0} - {1} : Installing {2} % Complete.", currentIndex, p.Name, pe.ProgressPercentage));
+            consoleOutput.Set();
+          }
+        }
+
+        static void ProductInstallCompleted(object sender, ProductMSIActionCompletedEventArgs p)
+        {
+          // Free the main thread.
+          msiDBLock.Set();
+        }
+
+        static void ProductInstall()
+        {
+            if (msiDBLock.WaitOne(1000))
+            {
+                foreach (string installProduct in productInstallList)
+                {
+                    Product p = ProductManager.GetProductById(installProduct);
+
+                    if (p.CurrentState == ProductState.WebRemote ||
+                      p.CurrentState == ProductState.DownloadStarted ||
+                      p.CurrentState == ProductState.DownloadMirrorSelection ||
+                      p.CurrentState == ProductState.DownloadInProgress ||
+                      p.CurrentState == ProductState.InstallInProgress ||
+                      p.CurrentState == ProductState.UpdateInProgress ||
+                      p.CurrentState == ProductState.RemoveInProgress)
+                    {
+                        continue;
+                    }
+                    if (p.CurrentState != ProductState.DownloadSuccess &&
+                      p.CurrentState != ProductState.FoundLocal &&
+                      p.CurrentState != ProductState.WillPerformUpgrade &&
+                      p.CurrentState != ProductState.CurrentlyInstalled)
+                    {
+                        continue;
+                    }
+
+                    msiDBLock.Reset();
+                    //p.ProductInstallationProgressChanged += new ProductInstallationActionEventHandler(ProductInstallProgressChanged);
+                    p.ProductMSIActionProgressChanged += new ProductMSIActionProgressHandler(ProductInstallProgressChanged);
+                    p.ProductMSIActionCompleted += new ProductMSIActionCompleteHandler(ProductInstallCompleted);
+                    p.MakeChanges();
+                    break;
+                }
+            }
+
+            // Wait for the installs to finish.
+            bool finishedInstalls = false;
+            do
+            {
+                finishedInstalls = msiDBLock.WaitOne(10000);
+                if (finishedInstalls)
+                {
+                    if (consoleOutput.WaitOne(1000))
+                    {
+                        consoleOutput.Reset();
+                        Console.WriteLine("Finished all installations");
+                        consoleOutput.Set();
+                        break;
+                    }
+                }
+            } while (!finishedInstalls);
+        }
+
+        // Install action helpers.
+        static void SetCustomSetupTypeDetails(List<string> products)
+        {
+            foreach (string product in products)
+            {
+                // Parse the option:value pair
+                int dividerIndex = product.IndexOf(':');
+                string productName = String.Empty;
+                string[] features = null;
+
+                if (dividerIndex > 0)
+                {
+                    productName = product.Substring(0, dividerIndex);
+                    features = product.Substring(dividerIndex + 1).Split(',');
+                }
+                else
+                    productName = product;
+
+                foreach (CatalogProduct catalogProduct in ProductManager.ActiveCatalog.Products)
+                {
+                    if (catalogProduct.ProductId.ToLower() == productName)
+                    {
+                        catalogProduct.ReferencedProduct.ProposedInstalled = true;
+
+                        if (features != null)
+                        {
+                            foreach (string feature in features)
+                            {
+                                foreach (ProductFeature pf in catalogProduct.ReferencedProduct.GetProductFeatures())
+                                {
+                                    if (pf.Name.ToLower() == feature)
+                                    {
+                                        pf.ProposedInstalled = true;
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+                        else
+                        {
+                            foreach (ProductFeature pf in catalogProduct.ReferencedProduct.GetProductFeatures())
+                            {
+                                pf.ProposedInstalled = true;
+                                break;
+                            }
+                        }
+                        break;
+                    }
+                }
+            }
+        }
+
+        static void ProcessInstallArguments(string type, List<string> products)
+        {
+            if (type == null)
+            {
+                type = "Custom";
+            }
+
+            if (type == "Custom")
+            {
+                if (products == null || products.Count == 0)
+                    throw new OptionException("Custom setup type requies at least one product argument.", "product");
+            }
+
+            // Convert text setup type.
+            SetupType argType = null;
+            foreach (SetupType st in ProductManager.ActiveCatalog.SetupTypes)
+            {
+                if (st.Name == type)
+                {
+                    argType = st;
+                    break;
+                }
+            }
+            if (argType == null)
+                throw new OptionException("Invalid type argument supplied.", "type");
+
+            // Clear all the default settings.
+            // Set the defaults according to the install type.
+            ProductManager.SetGlobalProposedInstalled(false);
+            foreach (CatalogProduct product in ProductManager.ActiveCatalog.Products)
+            {
+                product.ReferencedProduct.ProposedInstalled = argType.Includes(product);
+            }
+
+            // If Custom install type, set the Features.
+            if (type == "Custom")
+            {
+                SetCustomSetupTypeDetails(products);
+            }
+
+            if (productInstallList == null)
+                productInstallList = new List<string>();
+            else
+                productInstallList.Clear();
+
+            if (productDownloadList == null)
+                productDownloadList = new List<string>();
+            else
+                productDownloadList.Clear();
+
+            foreach (CatalogProduct product in ProductManager.ActiveCatalog.Products)
+            {
+                if (product.ReferencedProduct.ProposedInstalled == true)
+                {
+                    productInstallList.Add(product.ReferencedProduct.Name);
+                    Console.WriteLine(String.Format("{0} - {1} : ", productInstallList.Count, productInstallList[productInstallList.Count - 1]));
+
+                    if (!product.ReferencedProduct.FoundLocal)
+                        productDownloadList.Add(product.ReferencedProduct.Name);
+                }
+            }
+        }
+
+        // Main entry point.
+        static void Main(string[] args)
+        {
+            // Options
+            bool help = false;
+            //bool verbose = false;
+            bool check_for_updates = false;
+            string action = null;
+            string catalog = null;
+            string type = null;
+            List<string> products = new List<string>();
+
+            OptionSet userOptions = new OptionSet()
+              .Add("?|help|h", "Prints out the options.", option => help = option != null)
+              //.Add("v|verbose", "Enables verbose output", option => verbose = option != null)
+              .Add("u|updates", "Check for new products before performing action. Skipped by default.", option => check_for_updates = option != null)
+              .Add("a|action=", "Action to be performed.", option => action = option)
+              .Add("p|product:", "Product/Feature list element", option => products.Add(option))
+              .Add("c|catalog:", "Set default catalog.", option => catalog = option)
+              .Add("t|type:", "Set default install type.", option => type = option);
+
+            try
+            {
+                List<string> extraArgs = userOptions.Parse(args);
+
+                if (help)
+                    ShowHelp(userOptions, "Example");
+
+                if (action == null)
+                    throw new OptionException("Error: No action specified.", "action");
+
+                InstallerConfiguration.Load();
+
+                switch (action.ToLower())
+                {
+                    case "install":
+                        if (catalog != null)
+                        {
+                            ProductManager.DefaultCatalog = catalog;
+                        }
+                        ProductManager.Load();
+
+                        if (ProductManager.ActiveCatalog == null)
+                            ProductManager.ActiveCatalog = ProductManager.Catalogs[0];
+
+                        // Update the manifest.
+                        if (check_for_updates)
+                            GetProductUpdates();
+
+                        ProcessInstallArguments(type, products);
+
+                        // Download any missing products.
+                        ProductDownload();
+
+                        // Default installation directory
+                        InstallerConfiguration.ProposedInstallationPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
+
+                        // Do actual installation.
+                        ProductInstall();
+                        break;
+                    case "remove":
+                        break;
+                    case "upgrade":
+                        break;
+                    case "list":
+                        break;
+                    case "status":
+                        break;
+                    default:
+                        throw new OptionException("Error: No action recognized.", "action");
+                }
+
+                InstallerConfiguration.Save();
+            }
+            catch (OptionException oe)
+            {
+                ShowHelp(userOptions, oe.Message);
+            }
+
+            Console.WriteLine("Press Enter to continue.");
+            Console.ReadLine();
+        }
+    }
+}

=== added file 'WexCmd/WexCmd.csproj'
--- a/WexCmd/WexCmd.csproj	1970-01-01 00:00:00 +0000
+++ b/WexCmd/WexCmd.csproj	2011-03-10 03:08:26 +0000
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{92E2DA5A-2AA4-4475-A20A-910661A55A78}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>WexCmd</RootNamespace>
+    <AssemblyName>WexCmd</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\WexInstaller.Core\WexInstaller.Core.csproj">
+      <Project>{64664A39-D6C5-4842-A879-BDD915DDDCCF}</Project>
+      <Name>WexInstaller.Core</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="app.config" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file

=== added file 'WexCmd/app.config'
--- a/WexCmd/app.config	1970-01-01 00:00:00 +0000
+++ b/WexCmd/app.config	2011-03-10 03:08:26 +0000
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<configuration>
+<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>

=== modified file 'WexInstaller.Core/InstallerConfiguration.cs'
--- a/WexInstaller.Core/InstallerConfiguration.cs	2011-03-02 15:58:16 +0000
+++ b/WexInstaller.Core/InstallerConfiguration.cs	2011-03-10 03:08:26 +0000
@@ -9,7 +9,7 @@ using System.Runtime.InteropServices;
 using System.Diagnostics;
 using System.Net;
 
-namespace WexInstaller
+namespace WexInstaller.Core
 {
     public sealed class InstallerConfiguration
     {

=== modified file 'WexInstaller.Core/Product.cs'
--- a/WexInstaller.Core/Product.cs	2011-03-08 11:10:55 +0000
+++ b/WexInstaller.Core/Product.cs	2011-03-10 03:08:26 +0000
@@ -10,7 +10,28 @@ using System.Xml.Serialization;
 
 namespace WexInstaller.Core
 {
-  public delegate void ProductInstationActionEventHandler(object sender, ChainedInstallerEventArgs c);
+  public class ProductMSIActionProgressEventArgs : ProgressChangedEventArgs
+  {
+    public ProductMSIActionProgressEventArgs(int progressPercentage, object userToken)
+      : base(progressPercentage, userToken)
+    {
+    }
+
+    public string Message { get; set; }
+  }
+  public class ProductMSIActionCompletedEventArgs : AsyncCompletedEventArgs
+  {
+    public ProductMSIActionCompletedEventArgs(Exception error, bool cancelled, object userState)
+      : base(error, cancelled, userState)
+    {
+    }
+
+    public int ExitCode { get; set; }
+  }
+
+  public delegate void ProductMSIActionProgressHandler(object sender, ProductMSIActionProgressEventArgs pe);
+  public delegate void ProductMSIActionCompleteHandler(object sender, ProductMSIActionCompletedEventArgs pe);
+
   public delegate void DownloadProductProgressHandler(object sender, DownloadProgressChangedEventArgs de);
   public delegate void DownloadProductCompleteHandler(object sender, AsyncCompletedEventArgs ae);
 
@@ -22,6 +43,19 @@ namespace WexInstaller.Core
     private WebClient webClient;
     private BackgroundWorker backgroundWorker;
     private bool proposedInstalled;
+    private bool useCurrentlyInstalledPackage;
+
+    private int start, stop, installStep, installPos, overall_progress;
+
+    private FileVersionInfo msiVersion;
+
+    #region Events
+    public event DownloadProductCompleteHandler DownloadProductCompleted;
+    public event DownloadProductProgressHandler DownloadProductProgressChanged;
+
+    public event ProductMSIActionProgressHandler ProductMSIActionProgressChanged;
+    public event ProductMSIActionCompleteHandler ProductMSIActionCompleted;
+    #endregion
 
     public List<Package> Packages { get; set; }
 
@@ -138,7 +172,6 @@ namespace WexInstaller.Core
     [XmlIgnore]
     private Queue<string> MirrorList { get; set; }
 
-    private bool useCurrentlyInstalledPackage;
     [XmlIgnore]
     public bool UseCurrentlyInstalledPackage 
     {
@@ -195,20 +228,22 @@ namespace WexInstaller.Core
     }
 
     // MSI Installation in a background worker thread.
-    public event ProductInstationActionEventHandler ProductInstallationProgressChanged;
-
-    protected void DoInstallationProgressChange(ChainedInstallerEventArgs c)
-    {
-      if (ProductInstallationProgressChanged != null)
-        ProductInstallationProgressChanged(this, c);
-    }
-
     private void ChainedInstallerUpdated(object sender, ChainedInstallerEventArgs c)
     {
       if (backgroundWorker != null)
         backgroundWorker.ReportProgress(0, c);
     }
 
+    private void SetPosition(int newPos)
+    {
+      installPos = newPos;
+      float stagePos = (float)installPos / (float)(stop - start);
+      int progress = (int)(50.0f * stagePos);
+      if (overall_progress >= 50)
+        progress += 50;
+      overall_progress = Math.Max(overall_progress, progress);
+    }
+
     private void ExecuteMSI(PackageParameters parameters)
     {
       Debug.Assert(backgroundWorker == null) ;
@@ -265,10 +300,12 @@ namespace WexInstaller.Core
       backgroundWorker.Dispose();
       backgroundWorker = null;
 
-      ChainedInstallerEventArgs c = new ChainedInstallerEventArgs();
-      c.Action = ChainedInstallerAction.FinalAction;
-      c.ExitCode = (uint) Convert.ToInt32(e.Result);
-      DoInstallationProgressChange(c);
+      if (ProductMSIActionCompleted != null)
+      {
+        ProductMSIActionCompletedEventArgs p = new ProductMSIActionCompletedEventArgs(null, false, null);
+        p.ExitCode = Convert.ToInt32(e.Result);
+        ProductMSIActionCompleted(this, p);
+      }
 
       return;
     }
@@ -278,44 +315,64 @@ namespace WexInstaller.Core
       if (e.ProgressPercentage == 0)
       {
         ChainedInstallerEventArgs c = e.UserState as ChainedInstallerEventArgs;
+
+        string message = String.Empty;
         switch (c.Action)
         {
           case ChainedInstallerAction.StartInstallation:
-            InstallActionLog.AppendLine(c.Message);
+            message = c.Message;
+
             if (CurrentState == ProductState.InstallStarted ||
-              CurrentState == ProductState.UpdateStarted ||
-              CurrentState == ProductState.RemoveStarted)
-              CurrentState += 1;
-            break;
-          case ChainedInstallerAction.HandleActionData:
-            InstallActionLog.AppendLine(c.Message);
-            break;
-          case ChainedInstallerAction.HandleActionStart:
-            InstallActionLog.AppendLine(c.Message);
+                CurrentState == ProductState.UpdateStarted ||
+                CurrentState == ProductState.RemoveStarted)
+                CurrentState += 1;
+
+            start = stop = installStep = installPos = overall_progress = 0;
             break;
           case ChainedInstallerAction.ProgressSetRange:
-            InstallActionLog.AppendLine(String.Format("Min: {0} Max: {1}", c.ProgressMin.ToString(), c.ProgressMax.ToString()));
+            message = String.Format("Min: {0} Max: {1}", c.ProgressMin.ToString(), c.ProgressMax.ToString());
+
+            start = c.ProgressMin;
+            stop = c.ProgressMax;
+            installStep = 1;
+            installPos = 0;
+            if (overall_progress > 0)
+              overall_progress = 50;
             break;
           case ChainedInstallerAction.ProgressSetStep:
-            InstallActionLog.AppendLine(String.Format("Step: {0}", c.ProgressStep.ToString()));
+            message = String.Format("Step: {0}", c.ProgressStep.ToString());
+
+            installStep = c.ProgressStep;
             break;
           case ChainedInstallerAction.ProgressSetPosition:
-            InstallActionLog.AppendLine(String.Format("Position: {0}", c.ProgressPosition.ToString()));
+            message = String.Format("Position: {0}", c.ProgressPosition.ToString());
+
+            if (c.ProgressPosition != stop || installPos != 0)
+            {
+              SetPosition(c.ProgressPosition);
+            }
             break;
           case ChainedInstallerAction.ProgressSingleStep:
-            InstallActionLog.AppendLine("DoStep");
+            message = "DoStep";
+
+            SetPosition(installPos + installStep);
             break;
           case ChainedInstallerAction.EndInstallation:
-            InstallActionLog.AppendLine(c.Message);
-            break;
           case ChainedInstallerAction.LogEvent:
-            InstallActionLog.AppendLine(c.Message);
-            break;
           case ChainedInstallerAction.TerminateUI:
-            InstallActionLog.AppendLine(c.Message);
+          case ChainedInstallerAction.HandleActionData:

+          case ChainedInstallerAction.HandleActionStart:
+            message = c.Message;
             break;
         }
-        DoInstallationProgressChange(c);
+        InstallActionLog.AppendLine(message);
+
+        if (ProductMSIActionProgressChanged != null)
+        {
+          ProductMSIActionProgressEventArgs p = new ProductMSIActionProgressEventArgs(overall_progress, c);
+          p.Message = message;
+          ProductMSIActionProgressChanged(this, p);
+        }
       }
     }
 
@@ -416,7 +473,6 @@ namespace WexInstaller.Core
       return (status == MSIEnumError.Success) ? productInfo.ToString() : String.Empty;
     }
 
-    private FileVersionInfo msiVersion;
     private bool PopulateRelatePackageFeatures(Package targetPackage)
     {
       bool FoundInstalledPackage = false;
@@ -677,10 +733,6 @@ namespace WexInstaller.Core
       }
     }
 
-    public event DownloadProductCompleteHandler DownloadProductCompleted;
-
-    public event DownloadProductProgressHandler DownloadProductProgressChanged;
-
     private void DownloadProductComplete(object sender, AsyncCompletedEventArgs e)
     {
       if (e.Cancelled == false && e.Error == null)
@@ -824,7 +876,6 @@ namespace WexInstaller.Core
             controller.Owner = this;
         loadedController = true;
     }
-
   }
 
   public enum ProductState

=== modified file 'WexInstaller.Core/ProductManager.cs'
--- a/WexInstaller.Core/ProductManager.cs	2011-03-09 12:51:33 +0000
+++ b/WexInstaller.Core/ProductManager.cs	2011-03-10 03:08:26 +0000
@@ -31,6 +31,7 @@ namespace WexInstaller.Core
     public static bool ProductsInstalled { get; private set; }
     public static bool ProductsUpgrade { get; private set; }
     public static ProductCatalog ActiveCatalog { get; set; }
+    public static string DefaultCatalog { get; set; }
 
     private static ProductManifest ObjectifyManifest(string fileName)
     {
@@ -309,5 +310,12 @@ namespace WexInstaller.Core
       return wc.IsBusy;
     }
 
+    public static void SetGlobalProposedInstalled(bool proposedInstalled)
+    {
+      // turn off installation of all products as we are redoing it here
+      foreach (ProductCategory cat in ProductManager.ProductCategories)
+        foreach (Product p in cat.Products)
+          p.ProposedInstalled = proposedInstalled;
+    }
   }
 }

=== modified file 'WexInstaller/Controls/RemoveAllPage.cs'
--- a/WexInstaller/Controls/RemoveAllPage.cs	2011-02-07 23:27:02 +0000
+++ b/WexInstaller/Controls/RemoveAllPage.cs	2011-03-10 03:08:26 +0000
@@ -16,8 +16,6 @@ namespace WexInstaller
         Font titleFont = System.Drawing.SystemFonts.CaptionFont;
 
         ListViewItem removingItem;
-        int start, stop, installStep, installPos;
-        int overall_progress;
 
         private AutoResetEvent clearedToProceed;
 
@@ -51,82 +49,35 @@ namespace WexInstaller
             (this.ParentForm as MainForm).GoBack();
         }
 
-        private void ProductInstallationProgressChanged(object sender, ChainedInstallerEventArgs c)
+        private void ProductInstallProgressChanged(object sender, ProductMSIActionProgressEventArgs pe)
         {
-            switch (c.Action)
-            {
-                case ChainedInstallerAction.StartInstallation:
-                    overall_progress = 0;
-                    detailedLog.AppendText(String.Format("Beginning removal of {0}.{1}", (sender as Product).Title, Environment.NewLine));
-                    detailedLog.AppendText(String.Format("{0}{1}", c.Message, Environment.NewLine));
-                    break;
-                case ChainedInstallerAction.HandleActionData:
-                    detailedLog.AppendText(String.Format("{0}{1}", c.Message, Environment.NewLine));
-                    break;
-                case ChainedInstallerAction.HandleActionStart:
-                    detailedLog.AppendText(String.Format("{0}{1}", c.Message, Environment.NewLine));
-                    break;
-                case ChainedInstallerAction.ProgressSetRange:
-                    detailedLog.AppendText(String.Format("Min: {0} Max: {1}{2}", c.ProgressMin.ToString(), c.ProgressMax.ToString(), Environment.NewLine));
-                    start = c.ProgressMin;
-                    stop = c.ProgressMax;
-                    installStep = 1;
-                    installPos = 0;
-                    if (overall_progress > 0)
-                        overall_progress = 50;
-                    break;
-                case ChainedInstallerAction.ProgressSetStep:
-                    //detailedLog.AppendText(String.Format("Step: {0}{1}", c.ProgressStep.ToString(), Environment.NewLine));
-                    installStep = c.ProgressStep;
-                    break;
-                case ChainedInstallerAction.ProgressSetPosition:
-                    //detailedLog.AppendText(String.Format("Position: {0}{1}", c.ProgressPosition.ToString(), Environment.NewLine));
-                    if (c.ProgressPosition == stop && installPos == 0) return;
-                    SetPosition(c.ProgressPosition);
-                    break;
-                case ChainedInstallerAction.ProgressSingleStep:
-                    SetPosition(installPos + installStep);
-                    break;
-                case ChainedInstallerAction.EndInstallation:
-                    detailedLog.AppendText(String.Format("{0}{1}", c.Message, Environment.NewLine));
-                    break;
-                case ChainedInstallerAction.LogEvent:
-                    detailedLog.AppendText(String.Format("{0}{1}", c.Message, Environment.NewLine));
-                    break;
-                case ChainedInstallerAction.FinalAction:
-                    if (c.ExitCode != 0)
-                    {
-                        detailedLog.AppendText(String.Format("The product {0} failed to remove successfully.{1}", (sender as Product).Title, Environment.NewLine));
-                    }
-                    else
-                    {
-                        detailedLog.AppendText(String.Format("The product {0} was successfully removed.{1}", (sender as Product).Title, Environment.NewLine));
-                    }
-                    detailedLog.AppendText(Environment.NewLine);
-
-                    clearedToProceed.Set();
-
-                    if (removingItem.Index == productList.Items.Count - 1)
-                    {
-                        closeButton.Enabled = true;
-                        closeButton.Visible = true;
-
-                        cancelBtn.Enabled = false;
-                        cancelBtn.Visible = false;
-                    }
-                    break;
-            }
-        }
-
-        private void SetPosition(int newPos)
-        {
-            installPos = newPos;
-            float stagePos = (float)installPos / (float)(stop - start);
-            int progress = (int)(50.0f * stagePos);
-            if (overall_progress >= 50)
-                progress += 50;
-            overall_progress = Math.Max(overall_progress, progress);
-            removingItem.SubItems[1].Text = String.Format(Resources.StatusPercentage, overall_progress);
+          detailedLog.AppendText(String.Format("Beginning removal of {0}.{1}", (sender as Product).Title, Environment.NewLine));
+          detailedLog.AppendText(String.Format("{0}{1}", pe.Message, Environment.NewLine));
+          removingItem.SubItems[1].Text = String.Format(Resources.StatusPercentage, pe.ProgressPercentage);
+        }
+
+        private void ProductInstallCompleted(object sender, ProductMSIActionCompletedEventArgs pe)
+        {
+          if (pe.ExitCode != 0)
+          {
+            detailedLog.AppendText(String.Format("The product {0} failed to remove successfully.{1}", (sender as Product).Title, Environment.NewLine));
+          }
+          else
+          {
+            detailedLog.AppendText(String.Format("The product {0} was successfully removed.{1}", (sender as Product).Title, Environment.NewLine));
+          }
+          detailedLog.AppendText(Environment.NewLine);
+
+          clearedToProceed.Set();
+
+          if (removingItem.Index == productList.Items.Count - 1)
+          {
+            closeButton.Enabled = true;
+            closeButton.Visible = true;
+
+            cancelBtn.Enabled = false;
+            cancelBtn.Visible = false;
+          }
         }
 
         private void startButton_Click(object sender, EventArgs e)
@@ -161,7 +112,8 @@ namespace WexInstaller
                                 {
                                     clearedToProceed.Reset();
                                     removingItem = item;
-                                    p.ProductInstallationProgressChanged += new ProductInstationActionEventHandler(ProductInstallationProgressChanged);
+                                    p.ProductMSIActionProgressChanged +=new ProductMSIActionProgressHandler(ProductInstallProgressChanged);
+                                    p.ProductMSIActionCompleted += new ProductMSIActionCompleteHandler(ProductInstallCompleted);
                                     p.Remove();
                                     totalRemaining--;
                                     break;

=== modified file 'WexInstaller/InstallWizard/InstallProgressPanel.cs'
--- a/WexInstaller/InstallWizard/InstallProgressPanel.cs	2011-03-08 11:10:55 +0000
+++ b/WexInstaller/InstallWizard/InstallProgressPanel.cs	2011-03-10 03:08:26 +0000
@@ -27,8 +27,6 @@ namespace WexInstaller
     private int downloadErrorCount;
 
     ListViewItem installingItem;
-    int start, stop, installStep, installPos;
-    int overall_progress;
     private bool showingDetails;
 
     enum InstallProgressState : int
@@ -387,7 +385,8 @@ namespace WexInstaller
           continue;
         }
         installingItem = item;
-        p.ProductInstallationProgressChanged += new ProductInstationActionEventHandler(ProductInstallationProgressChanged);
+        p.ProductMSIActionProgressChanged += new ProductMSIActionProgressHandler(ProductMSIActionProgressChanged);
+        p.ProductMSIActionCompleted += new ProductMSIActionCompleteHandler(ProductMSIActionCompleted);
         p.MakeChanges();
         break;
       }
@@ -406,93 +405,54 @@ namespace WexInstaller
       finished = true;
     }
 
-    private void ProductInstallationProgressChanged(object sender, ChainedInstallerEventArgs e)
+    private void ProductMSIActionProgressChanged(object sender, ProductMSIActionProgressEventArgs pe)
     {
       Product p = (sender as Product);
       ListViewItem item = productList.Items.Find(p.Name, false)[0];
       Debug.Assert(item != null);
 
-      switch (e.Action)
+      AddToDetailsText(item.Index, pe.Message);
+
+      lock (installingItem)
       {
-        case ChainedInstallerAction.StartInstallation:
-          overall_progress = 0;
-          AddToDetailsText(item.Index, String.Format("Installation of product '{0}'start.", p.Name));
-          AddToDetailsText(item.Index, e.Message);
-          lock (installingItem)
-          {
-              installingItem.StateImageIndex = (int)InstallProgressState.Installing;
-              installingItem.SubItems[2].Text = GetProductStateString(p.CurrentState);
-          }
-          break;
-        case ChainedInstallerAction.HandleActionData:
-          AddToDetailsText(item.Index, e.Message);
-          break;
-        case ChainedInstallerAction.HandleActionStart:
-          AddToDetailsText(item.Index, e.Message);
-          break;
-        case ChainedInstallerAction.ProgressSetRange:
-          start = e.ProgressMin;
-          stop = e.ProgressMax;
-          installStep = 1;
-          installPos = 0;
-          if (overall_progress > 0)
-              overall_progress = 50;
-          AddToDetailsText(item.Index, String.Format("Min: {0} Max: {1}", e.ProgressMin.ToString(), e.ProgressMax.ToString()));
-          break;
-        case ChainedInstallerAction.ProgressSetStep:
-          installStep = e.ProgressStep;
-          break;
-        case ChainedInstallerAction.ProgressSetPosition:
-          if (e.ProgressPosition == stop && installPos == 0) return;
-          SetPosition(e.ProgressPosition);
-          break;
-        case ChainedInstallerAction.ProgressSingleStep:
-          SetPosition(installPos + installStep);
-          break;
-        case ChainedInstallerAction.EndInstallation:
-          AddToDetailsText(item.Index, e.Message);
-          break;
-        case ChainedInstallerAction.FinalAction:
-          AddToDetailsText(item.Index, "Final actions.");
-          lock (installingItem)
-          {
-              installingItem.StateImageIndex = (int)InstallProgressState.Ok;
-              installingItem.SubItems[2].Text = GetProductStateString(p.CurrentState);
-              installingItem.SubItems[3].Text = String.Empty;
-          }
-          AddToDetailsText(item.Index, installingItem.SubItems[2].Text);
-          if (p.Controller != null)
-          {
-              installedProductsNeedConfig = true;
-              p.Controller.PostAction();
-          }
-          lock (this)
-          {
-            leftToInstall--;
-            if (leftToInstall > 0)
-              BeginInvoke(new MethodInvoker(InstallNextPackage));
-            else
-              InstallationFinished();
-          }
-          break;
-        case ChainedInstallerAction.LogEvent:
-          AddToDetailsText(item.Index, e.Message);
-          break;
+        if (pe.ProgressPercentage == 0)
+        {
+            installingItem.StateImageIndex = (int)InstallProgressState.Installing;
+            installingItem.SubItems[2].Text = GetProductStateString(p.CurrentState);
+        }
+        installingItem.SubItems[3].Text = String.Format(Resources.StatusPercentage, pe.ProgressPercentage);
       }
+
     }
 
-    private void SetPosition(int newPos)
+    private void ProductMSIActionCompleted(object sender, ProductMSIActionCompletedEventArgs pe)
     {
-        installPos = newPos;
-        float stagePos = (float)installPos / (float)(stop - start);
-        int progress = (int)(50.0f * stagePos);
-        if (overall_progress >= 50)
-            progress += 50;
-        overall_progress = Math.Max(overall_progress, progress);
-        lock (installingItem)
-        {
-            installingItem.SubItems[3].Text = String.Format(Resources.StatusPercentage, overall_progress);
-        }
+      Product p = (sender as Product);
+      ListViewItem item = productList.Items.Find(p.Name, false)[0];
+      Debug.Assert(item != null);
+
+      AddToDetailsText(item.Index, "Final actions.");
+
+      lock (installingItem)
+      {
+        installingItem.StateImageIndex = (int)InstallProgressState.Ok;
+        installingItem.SubItems[2].Text = GetProductStateString(p.CurrentState);
+        installingItem.SubItems[3].Text = String.Empty;

+      }
+      AddToDetailsText(item.Index, installingItem.SubItems[2].Text);
+      if (p.Controller != null)
+      {
+        installedProductsNeedConfig = true;
+        p.Controller.PostAction();
+      }
+      lock (this)
+      {
+        leftToInstall--;
+        if (leftToInstall > 0)
+          BeginInvoke(new MethodInvoker(InstallNextPackage));
+        else
+          InstallationFinished();
+      }
     }
 
     #region Event handling

=== modified file 'WexInstaller/InstallWizard/InstallType.cs'
--- a/WexInstaller/InstallWizard/InstallType.cs	2011-02-07 21:39:59 +0000
+++ b/WexInstaller/InstallWizard/InstallType.cs	2011-03-10 03:08:26 +0000
@@ -76,9 +76,7 @@ namespace WexInstaller
         public override bool Next()
         {
             // turn off installation of all products as we are redoing it here
-            foreach (ProductCategory cat in ProductManager.ProductCategories)
-                foreach (Product p in cat.Products)
-                    p.ProposedInstalled = false;
+            ProductManager.SetGlobalProposedInstalled(false);
 
             foreach (CatalogProduct product in catalog.Products)
             {

=== modified file 'WexInstaller/InstallWizard/LicenseAgreement.cs'
--- a/WexInstaller/InstallWizard/LicenseAgreement.cs	2011-02-28 17:24:37 +0000
+++ b/WexInstaller/InstallWizard/LicenseAgreement.cs	2011-03-10 03:08:26 +0000
@@ -4,6 +4,8 @@ using System.ComponentModel;
 using System.Drawing;
 using System.Text;
 using System.Windows.Forms;
+
+using WexInstaller.Core;
 using WexInstaller.Properties;
 
 namespace WexInstaller

=== modified file 'WexInstaller/Program.cs'
--- a/WexInstaller/Program.cs	2011-02-02 15:20:17 +0000
+++ b/WexInstaller/Program.cs	2011-03-10 03:08:26 +0000
@@ -28,6 +28,18 @@ namespace WexInstaller
 
             Logger.LogInformation("Loading product manifest");
             ProductManager.Load();
+
+            Logger.LogInformation("Setting default catalog.");
+            string[] args = Environment.GetCommandLineArgs();
+            if (args.Length > 2)
+            {
+                ProductManager.DefaultCatalog = args[1]; // this should be the default catalog name
+            }
+            else
+            {
+                ProductManager.DefaultCatalog = null;
+            }
+
             Application.Run(new MainForm());
 
             InstallerConfiguration.Save();

=== modified file 'WexInstaller/RemovePanels/RemoveProgress.cs'
--- a/WexInstaller/RemovePanels/RemoveProgress.cs	2011-03-04 17:09:14 +0000
+++ b/WexInstaller/RemovePanels/RemoveProgress.cs	2011-03-10 03:08:26 +0000
@@ -13,8 +13,6 @@ namespace WexInstaller
     Font titleFont = System.Drawing.SystemFonts.CaptionFont;
 
     ListViewItem removingItem;
-    int start, stop, installStep, installPos;
-    int overall_progress;
 
     private bool nextOk;
     private bool backOk;
@@ -30,67 +28,21 @@ namespace WexInstaller
       executed = false;
     }
 
-    private void ProductInstallationProgressChanged(object sender, ChainedInstallerEventArgs c)
+    private void ProductInstallProgressChanged(object sender, ProductMSIActionProgressEventArgs pe)
     {
-      switch (c.Action)
-      {
-        case ChainedInstallerAction.StartInstallation:
-          overall_progress = 0;
-          detailedLog.AppendText(String.Format("Beginning removal of {0}.{1}", (sender as Product).Title, Environment.NewLine));
-          detailedLog.AppendText(String.Format("{0}{1}", c.Message, Environment.NewLine));
-          break;
-        case ChainedInstallerAction.HandleActionData:
-          detailedLog.AppendText(String.Format("{0}{1}", c.Message, Environment.NewLine));
-          break;
-        case ChainedInstallerAction.HandleActionStart:
-          detailedLog.AppendText(String.Format("{0}{1}", c.Message, Environment.NewLine));
-          break;
-        case ChainedInstallerAction.ProgressSetRange:
-          detailedLog.AppendText(String.Format("Min: {0} Max: {1}{2}", c.ProgressMin.ToString(), c.ProgressMax.ToString(), Environment.NewLine));
-          start = c.ProgressMin;
-          stop = c.ProgressMax;
-          installStep = 1;
-          installPos = 0;
-          if (overall_progress > 0)
-            overall_progress = 50;
-          break;
-        case ChainedInstallerAction.ProgressSetStep:
-          //detailedLog.AppendText(String.Format("Step: {0}{1}", c.ProgressStep.ToString(), Environment.NewLine));
-          installStep = c.ProgressStep;
-          break;
-        case ChainedInstallerAction.ProgressSetPosition:
-          //detailedLog.AppendText(String.Format("Position: {0}{1}", c.ProgressPosition.ToString(), Environment.NewLine));
-          if (c.ProgressPosition == stop && installPos == 0) return;
-          SetPosition(c.ProgressPosition);
-          break;
-        case ChainedInstallerAction.ProgressSingleStep:
-          SetPosition(installPos + installStep);
-          break;
-        case ChainedInstallerAction.EndInstallation:
-          detailedLog.AppendText(String.Format("{0}{1}", c.Message, Environment.NewLine));
-          break;
-        case ChainedInstallerAction.LogEvent:
-          detailedLog.AppendText(String.Format("{0}{1}", c.Message, Environment.NewLine));
-          break;
-        case ChainedInstallerAction.FinalAction:
-          Product p = (sender as Product);
-          string logText = (c.ExitCode != 0) ? Resources.RemovalFailedText : Resources.RemovalSucceededText;
-          detailedLog.AppendText(String.Format(logText, p.Title, Environment.NewLine));
-
-          BeginInvoke(new MethodInvoker(RemoveNextPackage));
-          break;
-      }
+      if (pe.ProgressPercentage == 0)
+        detailedLog.AppendText(String.Format("Beginning removal of {0}.{1}", (sender as Product).Title, Environment.NewLine));
+      detailedLog.AppendText(String.Format("{0}{1}", pe.Message, Environment.NewLine));
+      removingItem.SubItems[2].Text = String.Format(Resources.StatusPercentage, pe.ProgressPercentage);
     }
 
-    private void SetPosition(int newPos)
+    private void ProductInstallCompleted(object sender, ProductMSIActionCompletedEventArgs pe)
     {
-      installPos = newPos;
-      float stagePos = (float)installPos / (float)(stop - start);
-      int progress = (int)(50.0f * stagePos);
-      if (overall_progress >= 50)
-          progress += 50;
-      overall_progress = Math.Max(overall_progress, progress);
-      removingItem.SubItems[2].Text = String.Format(Resources.StatusPercentage, overall_progress);
+      Product p = (sender as Product);
+      string logText = (pe.ExitCode != 0) ? Resources.RemovalFailedText : Resources.RemovalSucceededText;
+      detailedLog.AppendText(String.Format(logText, p.Title, Environment.NewLine));
+
+      BeginInvoke(new MethodInvoker(RemoveNextPackage));
     }
 
     public override void Activate()
@@ -171,7 +123,8 @@ namespace WexInstaller
             p.CurrentState == ProductState.CurrentlyInstalled)
         {
           removingItem = item;
-          p.ProductInstallationProgressChanged += new ProductInstationActionEventHandler(ProductInstallationProgressChanged);
+          p.ProductMSIActionProgressChanged += new ProductMSIActionProgressHandler(ProductInstallProgressChanged);
+          p.ProductMSIActionCompleted += new ProductMSIActionCompleteHandler(ProductInstallCompleted);
           p.Remove();
           break;
         }

=== modified file 'installer-vs2010.sln'
--- a/installer-vs2010.sln	2011-03-09 12:51:33 +0000
+++ b/installer-vs2010.sln	2011-03-10 03:08:26 +0000
@@ -38,6 +38,8 @@ Project("{930C7802-8A8C-48F9-8165-68863B
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProductCacheUpdate", "ProductCacheUpdate\ProductCacheUpdate.csproj", "{7A3B910F-491E-4B61-8A57-358785CD51B6}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WexCmd", "WexCmd\WexCmd.csproj", "{92E2DA5A-2AA4-4475-A20A-910661A55A78}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -207,6 +209,18 @@ Global
 		{7A3B910F-491E-4B61-8A57-358785CD51B6}.Release|Win32.ActiveCfg = Release|x86
 		{7A3B910F-491E-4B61-8A57-358785CD51B6}.Release|x86.ActiveCfg = Release|x86
 		{7A3B910F-491E-4B61-8A57-358785CD51B6}.Release|x86.Build.0 = Release|x86
+		{92E2DA5A-2AA4-4475-A20A-910661A55A78}.Debug|Any CPU.ActiveCfg = Debug|x86
+		{92E2DA5A-2AA4-4475-A20A-910661A55A78}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
+		{92E2DA5A-2AA4-4475-A20A-910661A55A78}.Debug|Mixed Platforms.Build.0 = Debug|x86
+		{92E2DA5A-2AA4-4475-A20A-910661A55A78}.Debug|Win32.ActiveCfg = Debug|x86
+		{92E2DA5A-2AA4-4475-A20A-910661A55A78}.Debug|x86.ActiveCfg = Debug|x86
+		{92E2DA5A-2AA4-4475-A20A-910661A55A78}.Debug|x86.Build.0 = Debug|x86
+		{92E2DA5A-2AA4-4475-A20A-910661A55A78}.Release|Any CPU.ActiveCfg = Release|x86
+		{92E2DA5A-2AA4-4475-A20A-910661A55A78}.Release|Mixed Platforms.ActiveCfg = Release|x86
+		{92E2DA5A-2AA4-4475-A20A-910661A55A78}.Release|Mixed Platforms.Build.0 = Release|x86
+		{92E2DA5A-2AA4-4475-A20A-910661A55A78}.Release|Win32.ActiveCfg = Release|x86
+		{92E2DA5A-2AA4-4475-A20A-910661A55A78}.Release|x86.ActiveCfg = Release|x86
+		{92E2DA5A-2AA4-4475-A20A-910661A55A78}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

Attachment: [text/bzr-bundle] bzr/iggy@mysql.com-20110310030826-5gj94yhytiqr3nfj.bundle
Thread
bzr commit into wex-installer-1.0 branch (iggy:360) Iggy Galarza10 Mar