diff options
| author | Rob Mensching <rob@firegiant.com> | 2021-04-02 14:41:49 -0700 |
|---|---|---|
| committer | Rob Mensching <rob@firegiant.com> | 2021-04-02 14:58:00 -0700 |
| commit | 4449fcc5b8d104817c67135229682c66c3d892ca (patch) | |
| tree | 327f617de2e296ddb4e62c50bf07ec8b5dcf0a3e /src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs | |
| parent | 9cca339473d77c7036035f949239f5231c325968 (diff) | |
| download | wix-4449fcc5b8d104817c67135229682c66c3d892ca.tar.gz wix-4449fcc5b8d104817c67135229682c66c3d892ca.tar.bz2 wix-4449fcc5b8d104817c67135229682c66c3d892ca.zip | |
Enable codepages and languages to be set via .wxl files
Fixes wixtoolset/issues#5801
Diffstat (limited to 'src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs')
| -rw-r--r-- | src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs | 127 |
1 files changed, 71 insertions, 56 deletions
diff --git a/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs b/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs index fb5d7b83..06b51ba1 100644 --- a/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs +++ b/src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs | |||
| @@ -37,7 +37,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 37 | 37 | ||
| 38 | this.CabbingThreadCount = context.CabbingThreadCount; | 38 | this.CabbingThreadCount = context.CabbingThreadCount; |
| 39 | this.CabCachePath = context.CabCachePath; | 39 | this.CabCachePath = context.CabCachePath; |
| 40 | this.Codepage = context.Codepage; | ||
| 41 | this.DefaultCompressionLevel = context.DefaultCompressionLevel; | 40 | this.DefaultCompressionLevel = context.DefaultCompressionLevel; |
| 42 | this.DelayedFields = context.DelayedFields; | 41 | this.DelayedFields = context.DelayedFields; |
| 43 | this.ExpectedEmbeddedFiles = context.ExpectedEmbeddedFiles; | 42 | this.ExpectedEmbeddedFiles = context.ExpectedEmbeddedFiles; |
| @@ -47,6 +46,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 47 | this.OutputPath = context.OutputPath; | 46 | this.OutputPath = context.OutputPath; |
| 48 | this.OutputPdbPath = context.PdbPath; | 47 | this.OutputPdbPath = context.PdbPath; |
| 49 | this.PdbType = context.PdbType; | 48 | this.PdbType = context.PdbType; |
| 49 | this.ResolvedCodepage = context.ResolvedCodepage; | ||
| 50 | this.ResolvedSummaryInformationCodepage = context.ResolvedSummaryInformationCodepage; | ||
| 51 | this.ResolvedLcid = context.ResolvedLcid; | ||
| 50 | this.SuppressLayout = context.SuppressLayout; | 52 | this.SuppressLayout = context.SuppressLayout; |
| 51 | 53 | ||
| 52 | this.SubStorages = subStorages; | 54 | this.SubStorages = subStorages; |
| @@ -67,8 +69,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 67 | 69 | ||
| 68 | private IPathResolver PathResolver { get; } | 70 | private IPathResolver PathResolver { get; } |
| 69 | 71 | ||
| 70 | private int Codepage { get; } | ||
| 71 | |||
| 72 | private int CabbingThreadCount { get; } | 72 | private int CabbingThreadCount { get; } |
| 73 | 73 | ||
| 74 | private string CabCachePath { get; } | 74 | private string CabCachePath { get; } |
| @@ -95,6 +95,12 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 95 | 95 | ||
| 96 | private string OutputPdbPath { get; } | 96 | private string OutputPdbPath { get; } |
| 97 | 97 | ||
| 98 | private int? ResolvedCodepage { get; } | ||
| 99 | |||
| 100 | private int? ResolvedSummaryInformationCodepage { get; } | ||
| 101 | |||
| 102 | private int? ResolvedLcid { get; } | ||
| 103 | |||
| 98 | private bool SuppressAddingValidationRows { get; } | 104 | private bool SuppressAddingValidationRows { get; } |
| 99 | 105 | ||
| 100 | private bool SuppressLayout { get; } | 106 | private bool SuppressLayout { get; } |
| @@ -111,21 +117,22 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 111 | 117 | ||
| 112 | public IBindResult Execute() | 118 | public IBindResult Execute() |
| 113 | { | 119 | { |
| 114 | if (!this.Intermediate.HasLevel(Data.IntermediateLevels.Linked) && !this.Intermediate.HasLevel(Data.IntermediateLevels.Resolved)) | 120 | if (!this.Intermediate.HasLevel(Data.IntermediateLevels.Linked) || !this.Intermediate.HasLevel(Data.IntermediateLevels.Resolved)) |
| 115 | { | 121 | { |
| 116 | this.Messaging.Write(ErrorMessages.IntermediatesMustBeResolved(this.Intermediate.Id)); | 122 | this.Messaging.Write(ErrorMessages.IntermediatesMustBeResolved(this.Intermediate.Id)); |
| 117 | } | 123 | } |
| 118 | 124 | ||
| 119 | var section = this.Intermediate.Sections.Single(); | 125 | var section = this.Intermediate.Sections.Single(); |
| 120 | 126 | ||
| 127 | var packageSymbol = (section.Type == SectionType.Product) ? this.GetSingleSymbol<WixPackageSymbol>(section) : null; | ||
| 128 | var moduleSymbol = (section.Type == SectionType.Module) ? this.GetSingleSymbol<WixModuleSymbol>(section) : null; | ||
| 129 | var patchSymbol = (section.Type == SectionType.Patch) ? this.GetSingleSymbol<WixPatchSymbol>(section) : null; | ||
| 130 | |||
| 121 | var fileTransfers = new List<IFileTransfer>(); | 131 | var fileTransfers = new List<IFileTransfer>(); |
| 122 | var trackedFiles = new List<ITrackedFile>(); | 132 | var trackedFiles = new List<ITrackedFile>(); |
| 123 | 133 | ||
| 124 | var containsMergeModules = false; | 134 | var containsMergeModules = false; |
| 125 | 135 | ||
| 126 | // If there are any fields to resolve later, create the cache to populate during bind. | ||
| 127 | var variableCache = this.DelayedFields.Any() ? new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase) : null; | ||
| 128 | |||
| 129 | // Load standard tables, authored custom tables, and extension custom tables. | 136 | // Load standard tables, authored custom tables, and extension custom tables. |
| 130 | TableDefinitionCollection tableDefinitions; | 137 | TableDefinitionCollection tableDefinitions; |
| 131 | { | 138 | { |
| @@ -135,7 +142,21 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 135 | tableDefinitions = command.TableDefinitions; | 142 | tableDefinitions = command.TableDefinitions; |
| 136 | } | 143 | } |
| 137 | 144 | ||
| 138 | // Process the summary information table before the other tables. | 145 | // Calculate codepage |
| 146 | var codepage = this.CalculateCodepage(packageSymbol, moduleSymbol, patchSymbol); | ||
| 147 | |||
| 148 | // Process properties and create the delayed variable cache if needed. | ||
| 149 | Dictionary<string, string> variableCache = null; | ||
| 150 | string productLanguage = null; | ||
| 151 | { | ||
| 152 | var command = new ProcessPropertiesCommand(section, packageSymbol, this.ResolvedLcid ?? 0, this.DelayedFields.Any(), this.WindowsInstallerBackendHelper); | ||
| 153 | command.Execute(); | ||
| 154 | |||
| 155 | variableCache = command.DelayedVariablesCache; | ||
| 156 | productLanguage = command.ProductLanguage; | ||
| 157 | } | ||
| 158 | |||
| 159 | // Process the summary information table after properties are processed. | ||
| 139 | bool compressed; | 160 | bool compressed; |
| 140 | bool longNames; | 161 | bool longNames; |
| 141 | int installerVersion; | 162 | int installerVersion; |
| @@ -144,7 +165,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 144 | { | 165 | { |
| 145 | var branding = this.ServiceProvider.GetService<IWixBranding>(); | 166 | var branding = this.ServiceProvider.GetService<IWixBranding>(); |
| 146 | 167 | ||
| 147 | var command = new BindSummaryInfoCommand(section, this.WindowsInstallerBackendHelper, branding); | 168 | var command = new BindSummaryInfoCommand(section, this.ResolvedSummaryInformationCodepage, productLanguage, this.WindowsInstallerBackendHelper, branding); |
| 148 | command.Execute(); | 169 | command.Execute(); |
| 149 | 170 | ||
| 150 | compressed = command.Compressed; | 171 | compressed = command.Compressed; |
| @@ -154,49 +175,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 154 | modularizationSuffix = command.ModularizationSuffix; | 175 | modularizationSuffix = command.ModularizationSuffix; |
| 155 | } | 176 | } |
| 156 | 177 | ||
| 157 | // Add binder variables for all properties. | ||
| 158 | if (SectionType.Product == section.Type || variableCache != null) | ||
| 159 | { | ||
| 160 | foreach (var propertyRow in section.Symbols.OfType<PropertySymbol>()) | ||
| 161 | { | ||
| 162 | // Set the ProductCode if it is to be generated. | ||
| 163 | if ("ProductCode".Equals(propertyRow.Id.Id, StringComparison.Ordinal) && "*".Equals(propertyRow.Value, StringComparison.Ordinal)) | ||
| 164 | { | ||
| 165 | propertyRow.Value = this.WindowsInstallerBackendHelper.CreateGuid(); | ||
| 166 | |||
| 167 | #if TODO_PATCHING // Is this still necessary? | ||
| 168 | |||
| 169 | // Update the target ProductCode in any instance transforms. | ||
| 170 | foreach (SubStorage subStorage in this.Output.SubStorages) | ||
| 171 | { | ||
| 172 | Output subStorageOutput = subStorage.Data; | ||
| 173 | if (OutputType.Transform != subStorageOutput.Type) | ||
| 174 | { | ||
| 175 | continue; | ||
| 176 | } | ||
| 177 | |||
| 178 | Table instanceSummaryInformationTable = subStorageOutput.Tables["_SummaryInformation"]; | ||
| 179 | foreach (Row row in instanceSummaryInformationTable.Rows) | ||
| 180 | { | ||
| 181 | if ((int)SummaryInformation.Transform.ProductCodes == row.FieldAsInteger(0)) | ||
| 182 | { | ||
| 183 | row[1] = row.FieldAsString(1).Replace("*", propertyRow.Value); | ||
| 184 | break; | ||
| 185 | } | ||
| 186 | } | ||
| 187 | } | ||
| 188 | #endif | ||
| 189 | } | ||
| 190 | |||
| 191 | // Add the property name and value to the variableCache. | ||
| 192 | if (variableCache != null) | ||
| 193 | { | ||
| 194 | var key = String.Concat("property.", propertyRow.Id.Id); | ||
| 195 | variableCache[key] = propertyRow.Value; | ||
| 196 | } | ||
| 197 | } | ||
| 198 | } | ||
| 199 | |||
| 200 | // Sequence all the actions. | 178 | // Sequence all the actions. |
| 201 | { | 179 | { |
| 202 | var command = new SequenceActionsCommand(this.Messaging, section); | 180 | var command = new SequenceActionsCommand(this.Messaging, section); |
| @@ -415,7 +393,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 415 | // Time to create the WindowsInstallerData object. Try to put as much above here as possible, updating the IR is better. | 393 | // Time to create the WindowsInstallerData object. Try to put as much above here as possible, updating the IR is better. |
| 416 | WindowsInstallerData data; | 394 | WindowsInstallerData data; |
| 417 | { | 395 | { |
| 418 | var command = new CreateWindowsInstallerDataFromIRCommand(this.Messaging, section, tableDefinitions, this.BackendExtensions, this.WindowsInstallerBackendHelper); | 396 | var command = new CreateWindowsInstallerDataFromIRCommand(this.Messaging, section, tableDefinitions, codepage, this.BackendExtensions, this.WindowsInstallerBackendHelper); |
| 419 | data = command.Execute(); | 397 | data = command.Execute(); |
| 420 | } | 398 | } |
| 421 | 399 | ||
| @@ -450,7 +428,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 450 | 428 | ||
| 451 | if (SectionType.Patch == section.Type && this.DeltaBinaryPatch) | 429 | if (SectionType.Patch == section.Type && this.DeltaBinaryPatch) |
| 452 | { | 430 | { |
| 453 | var command = new CreateDeltaPatchesCommand(fileFacades, this.IntermediateFolder, section.Symbols.OfType<WixPatchIdSymbol>().FirstOrDefault()); | 431 | var command = new CreateDeltaPatchesCommand(fileFacades, this.IntermediateFolder, section.Symbols.OfType<WixPatchSymbol>().FirstOrDefault()); |
| 454 | command.Execute(); | 432 | command.Execute(); |
| 455 | } | 433 | } |
| 456 | 434 | ||
| @@ -508,7 +486,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 508 | var trackMsi = this.WindowsInstallerBackendHelper.TrackFile(this.OutputPath, TrackedFileType.Final); | 486 | var trackMsi = this.WindowsInstallerBackendHelper.TrackFile(this.OutputPath, TrackedFileType.Final); |
| 509 | trackedFiles.Add(trackMsi); | 487 | trackedFiles.Add(trackMsi); |
| 510 | 488 | ||
| 511 | var command = new GenerateDatabaseCommand(this.Messaging, this.WindowsInstallerBackendHelper, this.FileSystemManager, data, trackMsi.Path, tableDefinitions, this.IntermediateFolder, this.Codepage, keepAddedColumns: false, this.SuppressAddingValidationRows, useSubdirectory: false); | 489 | var command = new GenerateDatabaseCommand(this.Messaging, this.WindowsInstallerBackendHelper, this.FileSystemManager, data, trackMsi.Path, tableDefinitions, this.IntermediateFolder, keepAddedColumns: false, this.SuppressAddingValidationRows, useSubdirectory: false); |
| 512 | command.Execute(); | 490 | command.Execute(); |
| 513 | 491 | ||
| 514 | trackedFiles.AddRange(command.GeneratedTemporaryFiles); | 492 | trackedFiles.AddRange(command.GeneratedTemporaryFiles); |
| @@ -532,7 +510,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 532 | if (this.Messaging.EncounteredError) | 510 | if (this.Messaging.EncounteredError) |
| 533 | { | 511 | { |
| 534 | return null; | 512 | return null; |
| 535 | } | 513 | } |
| 536 | 514 | ||
| 537 | // Validate the output if there are CUBe files and we're not explicitly suppressing validation. | 515 | // Validate the output if there are CUBe files and we're not explicitly suppressing validation. |
| 538 | if (this.CubeFiles != null && !this.SuppressValidation) | 516 | if (this.CubeFiles != null && !this.SuppressValidation) |
| @@ -575,6 +553,43 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
| 575 | return result; | 553 | return result; |
| 576 | } | 554 | } |
| 577 | 555 | ||
| 556 | private int CalculateCodepage(WixPackageSymbol packageSymbol, WixModuleSymbol moduleSymbol, WixPatchSymbol patchSymbol) | ||
| 557 | { | ||
| 558 | var codepage = packageSymbol?.Codepage ?? moduleSymbol?.Codepage ?? patchSymbol?.Codepage; | ||
| 559 | |||
| 560 | if (String.IsNullOrEmpty(codepage)) | ||
| 561 | { | ||
| 562 | codepage = this.ResolvedCodepage?.ToString() ?? "65001"; | ||
| 563 | |||
| 564 | if (packageSymbol != null) | ||
| 565 | { | ||
| 566 | packageSymbol.Codepage = codepage; | ||
| 567 | } | ||
| 568 | else if (moduleSymbol != null) | ||
| 569 | { | ||
| 570 | moduleSymbol.Codepage = codepage; | ||
| 571 | } | ||
| 572 | else if (patchSymbol != null) | ||
| 573 | { | ||
| 574 | patchSymbol.Codepage = codepage; | ||
| 575 | } | ||
| 576 | } | ||
| 577 | |||
| 578 | return this.WindowsInstallerBackendHelper.GetValidCodePage(codepage); | ||
| 579 | } | ||
| 580 | |||
| 581 | private T GetSingleSymbol<T>(IntermediateSection section) where T : IntermediateSymbol | ||
| 582 | { | ||
| 583 | var symbols = section.Symbols.OfType<T>().ToList(); | ||
| 584 | |||
| 585 | if (1 != symbols.Count) | ||
| 586 | { | ||
| 587 | throw new WixException(ErrorMessages.MissingBundleInformation(nameof(T))); | ||
| 588 | } | ||
| 589 | |||
| 590 | return symbols[0]; | ||
| 591 | } | ||
| 592 | |||
| 578 | private WixOutput CreateWixout(List<ITrackedFile> trackedFiles, Intermediate intermediate, WindowsInstallerData data) | 593 | private WixOutput CreateWixout(List<ITrackedFile> trackedFiles, Intermediate intermediate, WindowsInstallerData data) |
| 579 | { | 594 | { |
| 580 | WixOutput wixout; | 595 | WixOutput wixout; |
