#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 Galarza | 10 Mar |