#At file:///D:/Work/MySQL/installer/ based on revid:iggy@stripped
376 Mike Lischke 2011-03-21
- ManifestUpdater: improved RE to search files.
. Manfiest template: changed mysql documentation to match our current file name (this is temporary anyway).
- Re-enabled OS architecture check.
- FeatureBox: fixed display and handling for (partially) installed products (i.e. you cannot uncheck a product with installed features). Set and unset hidden features if at least one or no feature of a product is installed.
- InstallProgress: fixed counting of remaining products, it is now also correct when re-entering the page.
modified:
ManifestUpdater/Program.cs
Setup/manifest-base.xml
WexInstaller.Core/Win32.cs
WexInstaller/Controls/FeatureBox.cs
WexInstaller/Controls/FeatureTreeView.cs
WexInstaller/InstallWizard/InstallProgressPanel.cs
=== modified file 'ManifestUpdater/Program.cs'
=== modified file 'ManifestUpdater/Program.cs'
--- a/ManifestUpdater/Program.cs 2011-03-18 10:29:04 +0000
+++ b/ManifestUpdater/Program.cs 2011-03-21 16:38:32 +0000
@@ -69,10 +69,17 @@
/// <returns>The found file with the latest version or null if none could be found.</returns>
static string FindLatestVersion(string fileName)
{
- // Names adhere to the pattern mysql-([a-zA-Z\+]+-)*[0-9]\.[0-9]\.[0-9][0-9]-win(32|x64)\.msi
- // e.g. mysql-5.5.9-win32.msi, or mysql-connector-odbc-5.1.8-winx64.msi.
+ // Package names consist of 4 parts:
+ // 1) starting with the literal mysql-
+ // 2) an optional sequence of words and a dash
+ // 3) a version number (separated by a dot) consisting of at least 2 numbers and at most 4 numbers, where
+ // the 3. and 4. number (if they exist) can have any number of digits.
+ // 4) an ending consisting of an option part for the architecture and the msi extension.
+ // e.g. mysql-5.1.59-win32.msi, or mysql-connector-odbc-5.1.8-winx64.msi, or
+ // mysql-universal-installer-document-bundle-1.0.0.0.msi
+ //
// Extract the architecture and extension part, which forms the end of our search pattern.
- Regex filePattern = new Regex(@"(?<baseName>mysql-([a-zA-Z\+]+-)*\d\.\d\.)(\d)+(?<ending>-win(32|x64)\.msi)$");
+ Regex filePattern = new Regex(@"(?<baseName>mysql-([a-zA-Z\+]+-)*\d\.\d)(\.\d+)*[a-z]?(?<ending>(-win(32|x64))?\.msi)$");
Match match = filePattern.Match(fileName);
string newestFile = null;
if (match.Success)
@@ -86,7 +93,8 @@
foreach (string file in files)
{
Version v = new Version(GetProperty(file, "ProductVersion"));
- if (v <= newestVersion) continue;
+ if (v <= newestVersion)
+ continue;
newestVersion = v;
newestFile = file;
}
@@ -107,6 +115,9 @@
package.FileName = Path.GetFileName(msiFile);
package.ThisVersion = GetProperty(msiFile, "ProductVersion");
package.Id = GetProperty(msiFile, "ProductCode");
+ if (String.IsNullOrEmpty(package.Id))
+ Console.WriteLine(String.Format("Warning: {0} doesn't have a product code",
+ package.FileName));
package.Features.Clear();
SetFeatures(msiFile, package);
}
=== modified file 'Setup/manifest-base.xml'
--- a/Setup/manifest-base.xml 2011-03-18 10:29:04 +0000
+++ b/Setup/manifest-base.xml 2011-03-21 16:38:32 +0000
@@ -19,7 +19,7 @@
<CatalogProduct productId="connector-c-win32" setupTypeFlags="5" />
<CatalogProduct productId="connector-cpp-win32" setupTypeFlags="5" />
<CatalogProduct productId="examples-5.5" setupTypeFlags="5"/>
- <CatalogProduct productId="mysql-documentation-5.5" setupTypeFlags="5"/>
+ <CatalogProduct productId="mysql-universal-installer-document-bundle-1.0.0.0" setupTypeFlags="5"/>
</CatalogProducts>
</ProductCatalog>
<ProductCatalog id="mysql-5.5-winx64-gpl" name="MySQL 5.5" description="MySQL 5.5 Community Edition" commercial="false">
@@ -37,7 +37,7 @@
<CatalogProduct productId="connector-c-winx64" setupTypeFlags="5" />
<CatalogProduct productId="connector-cpp-winx64" setupTypeFlags="5" />
<CatalogProduct productId="examples-5.5" setupTypeFlags="5"/>
- <CatalogProduct productId="mysql-documentation-5.5" setupTypeFlags="5"/>
+ <CatalogProduct productId="mysql-universal-installer-document-bundle-1.0.0.0" setupTypeFlags="5"/>
</CatalogProducts>
</ProductCatalog>
<ProductCatalog id="mysql-5.1-win32-gpl" name="MySQL 5.1" description="MySQL 5.1 Community Edition" commercial="false">
@@ -55,7 +55,7 @@
<CatalogProduct productId="connector-c-win32" setupTypeFlags="5" />
<CatalogProduct productId="connector-cpp-win32" setupTypeFlags="5" />
<CatalogProduct productId="examples-5.1" setupTypeFlags="5"/>
- <CatalogProduct productId="mysql-documentation-5.1" setupTypeFlags="5"/>
+ <CatalogProduct productId="mysql-universal-installer-document-bundle-1.0.0.0" setupTypeFlags="5"/>
</CatalogProducts>
</ProductCatalog>
<ProductCatalog id="mysql-5.1-winx64-gpl" name="MySQL 5.1" description="MySQL 5.1 Community Edition" commercial="false">
@@ -73,7 +73,7 @@
<CatalogProduct productId="connector-c-winx64" setupTypeFlags="5" />
<CatalogProduct productId="connector-cpp-winx64" setupTypeFlags="5" />
<CatalogProduct productId="examples-5.1" setupTypeFlags="5"/>
- <CatalogProduct productId="mysql-documentation-5.1" setupTypeFlags="5"/>
+ <CatalogProduct productId="mysql-universal-installer-document-bundle-1.0.0.0" setupTypeFlags="5"/>
</CatalogProducts>
</ProductCatalog>
</ProductCatalogs>
@@ -150,25 +150,19 @@
</Product>
</ProductCategory>
<ProductCategory name="Documentation" title="Documentation" description="">
- <Product name="mysql-documentation-5.5" title="MySQL Documentation 5.5" description="A collection of popular MySQL Documents" upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
- <Packages>
- <Package type="MSI" arch="Any" filename="mysql-documentation-5.5.msi" id="" thisVersion="">
- </Package>
- </Packages>
- </Product>
- <Product name="mysql-documentation-5.1" title="MySQL Documentation 5.1" description="A collection of popular MySQL Documents" upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
- <Packages>
- <Package type="MSI" arch="Any" filename="mysql-documentation-5.1.msi" id="" thisVersion="">
- </Package>
- </Packages>
- </Product>
- <Product name="examples-5.5" title="Samples and Examples 5.5" description="A collection of examples and sample databases to help a developer get started." upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
+ <Product name="mysql-universal-installer-document-bundle-1.0.0.0" title="MySQL Documentation" description="A collection of popular MySQL Documents" upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
+ <Packages>
+ <Package type="MSI" arch="Any" filename="mysql-universal-installer-document-bundle-1.0.0.0.msi" id="" thisVersion="">
+ </Package>
+ </Packages>
+ </Product>
+ <Product name="examples-5.5" title="Samples and Examples" description="A collection of examples and sample databases to help a developer get started." upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
<Packages>
<Package type="MSI" arch="Any" filename="mysql-examples-5.5.0.msi" id="" thisVersion="">
</Package>
</Packages>
</Product>
- <Product name="examples-5.1" title="Samples and Examples 5.1" description="A collection of examples and sample databases to help a developer get started." upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
+ <Product name="examples-5.1" title="Samples and Examples" description="A collection of examples and sample databases to help a developer get started." upgradeId="" urlBaseDir="http://wb.mysql.com/installer">
<Packages>
<Package type="MSI" arch="Any" filename="mysql-examples-5.1.0.msi" id="" thisVersion="">
</Package>
=== modified file 'WexInstaller.Core/Win32.cs'
--- a/WexInstaller.Core/Win32.cs 2011-03-18 19:10:58 +0000
+++ b/WexInstaller.Core/Win32.cs 2011-03-21 16:38:32 +0000
@@ -3098,7 +3098,6 @@
/// </summary>
public static bool Is64BitOS()
{
- /*
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2", "select * from Win32_OperatingSystem");
foreach (ManagementObject wmi in searcher.Get())
@@ -3111,7 +3110,7 @@
return "64-bit".Equals(architecture);
}
- */
+
return false;
}
=== modified file 'WexInstaller/Controls/FeatureBox.cs'
--- a/WexInstaller/Controls/FeatureBox.cs 2011-03-21 10:02:47 +0000
+++ b/WexInstaller/Controls/FeatureBox.cs 2011-03-21 16:38:32 +0000
@@ -263,9 +263,9 @@
}
else
{
- ProductFeature pf = (e.Node.Tag as ProductFeature);
- if (pf.ProposedInstalled)
- state = CheckBoxState.CheckedNormal;
+ ProductFeature feature = (e.Node.Tag as ProductFeature);
+ state = feature.Installed ? CheckBoxState.CheckedDisabled :
+ feature.ProposedInstalled ? CheckBoxState.CheckedNormal : CheckBoxState.UncheckedNormal;
}
if (CBGlyphSize.IsEmpty)
@@ -303,13 +303,16 @@
}
else
{
- ProductFeature pf = e.Node.Tag as ProductFeature;
- pf.ProposedInstalled = !pf.ProposedInstalled;
+ ProductFeature feature = e.Node.Tag as ProductFeature;
+ if (feature.Installed)
+ return;
+
+ feature.ProposedInstalled = !feature.ProposedInstalled;
// Check if at least one (visible) product feature for the owning product is proposed for installation.
// If so set also all invisible features too. Otherwise remove invisible features from the
// installation list so that the entire product is set to no-installation.
- ProductElement element = pf;
+ ProductElement element = feature;
do
{
element = element.Parent;
@@ -321,9 +324,9 @@
bool anyFeatureInstalled = false;
foreach (TreeNode node in featureList.Nodes)
anyFeatureInstalled |= (node.Tag as ProductFeature).ProposedInstalled;
- foreach (ProductFeature feature in product.GetProductFeatures())
- if (feature.Display == "0") // Invisible feature.
- feature.ProposedInstalled = anyFeatureInstalled;
+ foreach (ProductFeature childFeature in product.GetProductFeatures())
+ if (childFeature.Display == "0") // Invisible feature.
+ childFeature.ProposedInstalled = anyFeatureInstalled;
}
featureList.Invalidate(); // There can be sub features that changed state too, so redraw everything.
=== modified file 'WexInstaller/Controls/FeatureTreeView.cs'
--- a/WexInstaller/Controls/FeatureTreeView.cs 2011-03-21 10:34:56 +0000
+++ b/WexInstaller/Controls/FeatureTreeView.cs 2011-03-21 16:38:32 +0000
@@ -82,7 +82,9 @@
/// <summary>
/// Switches to the next valid check state for the given node applying the state to the
/// represented products and features on the way.
- /// The next valid state for an unchecked or mixed node is checked, otherwise unchecked.
+ /// The next valid state for an unchecked or mixed node is checked, otherwise unchecked (for enabled states).
+ /// If the check state is disabled then it can only be checked (when mixed), though not changed
+ /// if already checked.
/// </summary>
private void SwitchStateForNode(TreeNode node)
{
@@ -112,11 +114,11 @@
/// Switches between the check states that represent the installation proposal.
/// Keep in mind we have 3 states (no installation, partial installation, full installation).
/// If nothing or only a part is proposed for installation yet for that product set all to install.
- /// Otherwise set all to not-install.
+ /// Otherwise set all to not-install, if not already installed.
/// </summary>
private void SwitchStateForProduct(Product p, bool forceInstall)
{
- List<ProductFeature> productFeatures = p.GetProductFeatures();
+ List<ProductFeature> productFeatures = p.GetAllProductFeatures();
bool doInstall;
// Installation is forced if the category to which this product belongs has a mixed
@@ -129,42 +131,74 @@
doInstall = !p.ProposedInstalled;
else
{
- CheckBoxState state = GetStateFromFeatureList(p.GetProductFeatures());
+ CheckBoxState state = GetEnabledEquivalent(GetStateFromFeatureList(productFeatures));
doInstall = (state == CheckBoxState.UncheckedNormal) || (state == CheckBoxState.MixedNormal);
}
}
if (!p.Installed)
p.ProposedInstalled = doInstall;
- foreach (ProductFeature pf in productFeatures)
- pf.ProposedInstalled = doInstall;
+ foreach (ProductFeature feature in productFeatures)
+ if (!feature.Installed)
+ feature.ProposedInstalled = doInstall;
OnProductInstallationProposalChanged(p);
}
+ /// <summary>
+ /// Returns the enabled variant of the given state (if that is disabled).
+ /// </summary>
+ /// <param name="state"></param>
+ /// <returns></returns>
+ private CheckBoxState GetEnabledEquivalent(CheckBoxState state)
+ {
+ switch (state)
+ {
+ case CheckBoxState.CheckedDisabled:
+ return CheckBoxState.CheckedNormal;
+ case CheckBoxState.MixedDisabled:
+ return CheckBoxState.MixedNormal;
+ case CheckBoxState.UncheckedDisabled:
+ return CheckBoxState.UncheckedNormal;
+ default:
+ return state;
+ }
+ }
+
+ /// <summary>
+ /// Used to determine if a given state is one of the disabled states.
+ /// </summary>
+ private bool IsDisabled(CheckBoxState state)
+ {
+ return (state == CheckBoxState.CheckedDisabled || state == CheckBoxState.MixedDisabled ||
+ state == CheckBoxState.UncheckedDisabled);
+ }
+
+ /// <summary>
+ /// Determines and returns the checkbox state for a given node.
+ /// Both product and category nodes are handled here.
+ /// </summary>
private CheckBoxState GetNodeCheckboxState(TreeNode node)
{
- CheckBoxState result = CheckBoxState.MixedHot; // A state we don't use in the UI.
+ CheckBoxState result = CheckBoxState.UncheckedDisabled;
if (node.Tag is Product)
- {
result = GetStateForProduct(node.Tag as Product);
- // If the product is already installed convert the state to its disabled equivalent.
- if ((node.Tag as Product).Installed)
- result = (CheckBoxState)((int)result + 3);
- }
else
{
List<ProductFeature> featureList = new List<ProductFeature>();
+ bool hasInstalledParts = false;
foreach (TreeNode child in node.Nodes)
{
CheckBoxState childState = GetStateForProduct(child.Tag as Product);
- if (result == CheckBoxState.MixedHot)
+ if (childState == CheckBoxState.CheckedDisabled || childState == CheckBoxState.MixedDisabled)
+ hasInstalledParts = true;
+ if (result == CheckBoxState.UncheckedDisabled)
result = childState;
else
- if (result != childState)
+ if (GetEnabledEquivalent(result) != GetEnabledEquivalent(childState))
{
- result = CheckBoxState.MixedNormal;
+ result = hasInstalledParts ? CheckBoxState.MixedDisabled : CheckBoxState.MixedNormal;
break;
}
}
@@ -181,7 +215,7 @@
state = GetStateFromFeatureList(productFeatures);
else
if (p.ProposedInstalled || p.Installed)
- state = CheckBoxState.CheckedNormal;
+ state = p.Installed ? CheckBoxState.CheckedDisabled : CheckBoxState.CheckedNormal;
else
state = CheckBoxState.UncheckedNormal;
@@ -190,19 +224,26 @@
private CheckBoxState GetStateFromFeatureList(List<ProductFeature> featureList)
{
- bool allInstalled = true;
+ bool allToBeInstalled = true;
+ bool anyToBeInstalled = false;
bool anyInstalled = false;
- foreach (ProductFeature f in featureList)
+ foreach (ProductFeature feature in featureList)
{
- allInstalled &= f.ProposedInstalled;
- anyInstalled |= f.ProposedInstalled;
+ allToBeInstalled &= feature.ProposedInstalled;
+ anyToBeInstalled |= feature.ProposedInstalled;
+ anyInstalled |= feature.Installed;
}
- if (allInstalled)
- return CheckBoxState.CheckedNormal;
+ CheckBoxState result = CheckBoxState.UncheckedNormal;
+ if (allToBeInstalled)
+ result = CheckBoxState.CheckedNormal;
+ else
+ if (anyToBeInstalled)
+ result = CheckBoxState.MixedNormal;
+
+ // If any feature is already installed convert the state to its disabled equivalent.
if (anyInstalled)
- return CheckBoxState.MixedNormal;
-
- return CheckBoxState.UncheckedNormal;
+ result = (CheckBoxState)((int)result + 3);
+ return result;
}
private int GetOffset(TreeNode node)
=== modified file 'WexInstaller/InstallWizard/InstallProgressPanel.cs'
--- a/WexInstaller/InstallWizard/InstallProgressPanel.cs 2011-03-21 12:59:48 +0000
+++ b/WexInstaller/InstallWizard/InstallProgressPanel.cs 2011-03-21 16:38:32 +0000
@@ -59,6 +59,7 @@
if (!finished)
{
started = false;
+ nextOk = true;
progressLevels.Clear();
NextButton.Text = Properties.Resources.NextButtonExecuteText;
}
@@ -67,6 +68,7 @@
// installations we have on the way.
productList.Items.Clear();
leftToDownload = 0;
+ leftToInstall = 0;
foreach (ProductCategory pc in ProductManager.ProductCategories)
{
foreach (Product p in pc.Products)
@@ -77,6 +79,9 @@
if (!p.FoundLocal)
leftToDownload++;
+ if (p.CurrentState != ProductState.InstallSuccess && p.CurrentState != ProductState.UpdateSuccess)
+ leftToInstall++;
+
ListViewItem item = new ListViewItem(String.Empty);
item.Name = p.Name;
item.Tag = p;
@@ -93,9 +98,10 @@
}
}
}
- leftToInstall = productList.Items.Count;
- nextOk = leftToInstall > 0;
+ finished = (leftToInstall == 0);
+ if (finished)
+ NextButton.Text = Properties.Resources.NextButtonDefaultText;
base.Activate();
}
@@ -299,6 +305,7 @@
(p.CurrentState == ProductState.DownloadNoMirror))
{
downloadErrorCount++;
+ leftToInstall--;
currentItem.SubItems[4].Text = e.Error.Message;
currentItem.SubItems[3].Text = ListViewWex.LinkMarker + Resources.TryAgainLink + ListViewWex.LinkMarker;
}
@@ -375,29 +382,16 @@
foreach (ListViewItem item in productList.Items)
{
Product p = (Product)item.Tag;
- 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)
- {
- leftToInstall--;
- continue;
- }
- installingItem = item;
- p.ProductMSIActionProgressChanged += new ProductMSIActionProgressHandler(ProductMSIActionProgressChanged);
- p.ProductMSIActionCompleted += new ProductMSIActionCompleteHandler(ProductMSIActionCompleted);
- p.MakeChanges();
- break;
+ if ((p.CurrentState == ProductState.FoundLocal) ||
+ (p.CurrentState == ProductState.WillPerformUpgrade) ||
+ (p.CurrentState == ProductState.CurrentlyInstalled))
+ {
+ installingItem = item;
+ p.ProductMSIActionProgressChanged += new ProductMSIActionProgressHandler(ProductMSIActionProgressChanged);
+ p.ProductMSIActionCompleted += new ProductMSIActionCompleteHandler(ProductMSIActionCompleted);
+ p.MakeChanges();
+ break;
+ }
}
}
@@ -409,9 +403,8 @@
if (installedProductsNeedConfig == false)
(ParentControl as InstallWizardControl).RemoveConfigPages("Configuration");
nextOk = true;
- NextButton.Enabled = true;
-
finished = true;
+ SignalChange();
}
private void ProductMSIActionProgressChanged(object sender, ProductMSIActionProgressEventArgs pe)
Attachment: [text/bzr-bundle] bzr/mike.lischke@oracle.com-20110321163832-tmecgh0rmce8sbac.bundle
| Thread |
|---|
| • bzr commit into wex-installer-1.0 branch (mike.lischke:376) | Mike Lischke | 21 Mar |