From b645ddc2c1386c1199ca1e7790201d7a5ab6627b Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Wed, 22 May 2019 00:54:09 -0700 Subject: Integrate latest changes to tuple definitions --- .../ConvertTuplesFixture.cs | 747 +++++++++++++-------- 1 file changed, 455 insertions(+), 292 deletions(-) (limited to 'src/test') diff --git a/src/test/WixToolsetTest.Converters.Tupleizer/ConvertTuplesFixture.cs b/src/test/WixToolsetTest.Converters.Tupleizer/ConvertTuplesFixture.cs index ae33d6b1..9b1fa4cf 100644 --- a/src/test/WixToolsetTest.Converters.Tupleizer/ConvertTuplesFixture.cs +++ b/src/test/WixToolsetTest.Converters.Tupleizer/ConvertTuplesFixture.cs @@ -3,6 +3,7 @@ namespace WixToolsetTest.Converters.Tupleizer { using System; + using System.Collections.Generic; using System.IO; using System.Linq; using WixBuildTools.TestSupport; @@ -42,350 +43,512 @@ namespace WixToolsetTest.Converters.Tupleizer intermediate = Intermediate.Load(wixiplFile); + var wixMediaByDiskId = IndexWixMediaTableByDiskId(output); + // Dump to text for easy diffing, with some massaging to keep v3 and v4 diffable. // var tables = output.Tables.Cast(); var wix3Dump = tables .SelectMany(table => table.Rows.Cast() - .Select(row => RowToString(row))) + .SelectMany(row => RowToStrings(row, wixMediaByDiskId))) + .Where(s => !String.IsNullOrEmpty(s)) + .OrderBy(s => s) .ToArray(); var tuples = intermediate.Sections.SelectMany(s => s.Tuples); - var wix4Dump = tuples.Select(tuple => TupleToString(tuple)).ToArray(); + var wix4Dump = tuples + .SelectMany(tuple => TupleToStrings(tuple)) + .OrderBy(s => s) + .ToArray(); +#if false Assert.Equal(wix3Dump, wix4Dump); +#else // useful when you want to diff the outputs with another diff tool. + var wix3TextDump = String.Join(Environment.NewLine, wix3Dump); + var wix4TextDump = String.Join(Environment.NewLine, wix4Dump); - // Useful when you want to diff the outputs with another diff tool... - // - //var wix3TextDump = String.Join(Environment.NewLine, wix3Dump.OrderBy(val => val)); - //var wix4TextDump = String.Join(Environment.NewLine, wix4Dump.OrderBy(val => val)); - //Assert.Equal(wix3TextDump, wix4TextDump); + File.WriteAllText(Path.Combine(Path.GetTempPath(), "~3.txt"), wix3TextDump); + File.WriteAllText(Path.Combine(Path.GetTempPath(), "~4.txt"), wix4TextDump); + + Assert.Equal(wix3TextDump, wix4TextDump); +#endif } } - private static string RowToString(Wix3.Row row) + private static Dictionary IndexWixMediaTableByDiskId(Wix3.Output output) { - var fields = String.Join(",", row.Fields.Select(field => field.Data?.ToString())); + var wixMediaByDiskId = new Dictionary(); + var wixMediaTable = output.Tables["WixMedia"]; - // Massage output to match WiX v3 rows and v4 tuples. - // - switch (row.Table.Name) + if (wixMediaTable != null) { - case "File": - var fieldValues = row.Fields.Take(7).Select(field => field.Data?.ToString()).ToArray(); - if (fieldValues[3] == null) - { - // "Somebody" sometimes writes out a null field even when the column definition says - // it's non-nullable. Not naming names or anything. (SWID tags.) - fieldValues[3] = "0"; - } - fields = String.Join(",", fieldValues); - break; - case "WixFile": - fields = String.Join(",", row.Fields.Take(8).Select(field => field.Data?.ToString())); - break; + foreach (Wix3.WixMediaRow row in wixMediaTable.Rows) + { + wixMediaByDiskId.Add((int)row[0], row); + } } - return $"{row.Table.Name},{fields}"; + return wixMediaByDiskId; } - private static string TupleToString(WixToolset.Data.IntermediateTuple tuple) + private static IEnumerable RowToStrings(Wix3.Row row, Dictionary wixMediaByDiskId) { - var fields = String.Join(",", tuple.Fields.Select(field => field?.AsString())); + string fields = null; - switch (tuple.Definition.Name) + // Massage output to match WiX v3 rows and v4 tuples. + // + switch (row.Table.Name) { - // Massage output to match WiX v3 rows and v4 tuples. - // - case "Component": - { - var componentTuple = (ComponentTuple)tuple; - var attributes = ComponentLocation.Either == componentTuple.Location ? WindowsInstallerConstants.MsidbComponentAttributesOptional : 0; - attributes |= ComponentLocation.SourceOnly == componentTuple.Location ? WindowsInstallerConstants.MsidbComponentAttributesSourceOnly : 0; - attributes |= ComponentKeyPathType.Registry == componentTuple.KeyPathType ? WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath : 0; - attributes |= ComponentKeyPathType.OdbcDataSource == componentTuple.KeyPathType ? WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource : 0; - attributes |= componentTuple.DisableRegistryReflection ? WindowsInstallerConstants.MsidbComponentAttributesDisableRegistryReflection : 0; - attributes |= componentTuple.NeverOverwrite ? WindowsInstallerConstants.MsidbComponentAttributesNeverOverwrite : 0; - attributes |= componentTuple.Permanent ? WindowsInstallerConstants.MsidbComponentAttributesPermanent : 0; - attributes |= componentTuple.SharedDllRefCount ? WindowsInstallerConstants.MsidbComponentAttributesSharedDllRefCount : 0; - attributes |= componentTuple.Shared ? WindowsInstallerConstants.MsidbComponentAttributesShared : 0; - attributes |= componentTuple.Transitive ? WindowsInstallerConstants.MsidbComponentAttributesTransitive : 0; - attributes |= componentTuple.UninstallWhenSuperseded ? WindowsInstallerConstants.MsidbComponentAttributes64bit : 0; - attributes |= componentTuple.Win64 ? WindowsInstallerConstants.MsidbComponentAttributes64bit : 0; - - fields = String.Join(",", - componentTuple.ComponentId, - componentTuple.Directory_, - attributes.ToString(), - componentTuple.Condition, - componentTuple.KeyPath - ); - break; - } - case "CustomAction": + case "Directory": + var dirs = SplitDefaultDir((string)row[2]); + fields = String.Join(",", row[0], row[1], dirs[0], dirs[1], dirs[2], dirs[3]); + break; + case "File": + { + var fieldValues = row.Fields.Take(7).Select(SafeConvertField).ToArray(); + if (fieldValues[3] == null) { - var customActionTuple = (CustomActionTuple)tuple; - var type = customActionTuple.Win64 ? WindowsInstallerConstants.MsidbCustomActionType64BitScript : 0; - type |= customActionTuple.TSAware ? WindowsInstallerConstants.MsidbCustomActionTypeTSAware : 0; - type |= customActionTuple.Impersonate ? 0 : WindowsInstallerConstants.MsidbCustomActionTypeNoImpersonate; - type |= customActionTuple.IgnoreResult ? WindowsInstallerConstants.MsidbCustomActionTypeContinue : 0; - type |= customActionTuple.Hidden ? WindowsInstallerConstants.MsidbCustomActionTypeHideTarget : 0; - type |= customActionTuple.Async ? WindowsInstallerConstants.MsidbCustomActionTypeAsync : 0; - type |= CustomActionExecutionType.FirstSequence == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeFirstSequence : 0; - type |= CustomActionExecutionType.OncePerProcess == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeOncePerProcess : 0; - type |= CustomActionExecutionType.ClientRepeat == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeClientRepeat : 0; - type |= CustomActionExecutionType.Deferred == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeInScript : 0; - type |= CustomActionExecutionType.Rollback == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeInScript | WindowsInstallerConstants.MsidbCustomActionTypeRollback : 0; - type |= CustomActionExecutionType.Commit == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeInScript | WindowsInstallerConstants.MsidbCustomActionTypeCommit : 0; - type |= CustomActionSourceType.File == customActionTuple.SourceType ? WindowsInstallerConstants.MsidbCustomActionTypeSourceFile : 0; - type |= CustomActionSourceType.Directory == customActionTuple.SourceType ? WindowsInstallerConstants.MsidbCustomActionTypeDirectory : 0; - type |= CustomActionSourceType.Property == customActionTuple.SourceType ? WindowsInstallerConstants.MsidbCustomActionTypeProperty : 0; - type |= CustomActionTargetType.Dll == customActionTuple.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeDll : 0; - type |= CustomActionTargetType.Exe == customActionTuple.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeExe : 0; - type |= CustomActionTargetType.TextData == customActionTuple.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeTextData : 0; - type |= CustomActionTargetType.JScript == customActionTuple.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeJScript : 0; - type |= CustomActionTargetType.VBScript == customActionTuple.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeVBScript : 0; - - fields = String.Join(",", - type.ToString(), - customActionTuple.Source, - customActionTuple.Target, - customActionTuple.PatchUninstall ? WindowsInstallerConstants.MsidbCustomActionTypePatchUninstall.ToString() : null - ); - break; + // "Somebody" sometimes writes out a null field even when the column definition says + // it's non-nullable. Not naming names or anything. (SWID tags.) + fieldValues[3] = "0"; } - case "Feature": - { - var featureTuple = (FeatureTuple)tuple; - var attributes = featureTuple.DisallowAbsent ? WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent : 0; - attributes |= featureTuple.DisallowAdvertise ? WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise : 0; - attributes |= FeatureInstallDefault.FollowParent == featureTuple.InstallDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFollowParent : 0; - attributes |= FeatureInstallDefault.Source == featureTuple.InstallDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFavorSource : 0; - attributes |= FeatureTypicalDefault.Advertise == featureTuple.TypicalDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise : 0; - - fields = String.Join(",", - featureTuple.Feature_Parent, - featureTuple.Title, - featureTuple.Description, - featureTuple.Display.ToString(), - featureTuple.Level.ToString(), - featureTuple.Directory_, - attributes.ToString()); - break; - } - case "File": + fields = String.Join(",", fieldValues); + break; + } + case "Media": + var compression = wixMediaByDiskId.TryGetValue((int)row[0], out var wixMedia) ? (CompressionLevel?)Enum.Parse(typeof(CompressionLevel), SafeConvertField(wixMedia.Fields[1]), true) : null; + + fields = String.Join(",", row.Fields.Select(SafeConvertField)); + fields = String.Join(",", fields, (int?)compression, SafeConvertField(wixMedia?.Fields[2])); + break; + case "RegLocator": + var type = (int)row[4]; + fields = String.Join(",", row[0], row[1], row[2], row[3], type & 0xF, (type & 0x10) == 0x10); + break; + case "RemoveFile": + var attributes = (int)row[4]; + var onInstall = (attributes & 1) == 1 ? (bool?)true : null; + var onUninstall = (attributes & 2) == 2 ? (bool?)true : null; + fields = String.Join(",", row.Fields.Take(4).Select(SafeConvertField)); + fields = String.Join(",", fields, onInstall, onUninstall); + break; + case "Shortcut": + var split = ((string)row[2]).Split('|'); + var afterName = String.Join(",", row.Fields.Skip(3).Select(SafeConvertField)); + fields = String.Join(",", row[0], row[1], split.Length > 1 ? split[1] : split[0], split.Length > 1 ? split[0] : String.Empty, afterName); + break; + case "WixAction": + var table = (int)SequenceStringToSequenceTable(row[0]); + fields = String.Join(",", table, row[1], row[2], row[3], row[4], row[5], row[6]); + break; + case "WixFile": + { + var fieldValues = row.Fields.Take(10).Select(SafeConvertField).ToArray(); + if (fieldValues[8] == null) { - var fileTuple = (FileTuple)tuple; - fields = String.Join(",", - fileTuple.Component_, - fileTuple.LongFileName, - fileTuple.FileSize.ToString(), - fileTuple.Version, - fileTuple.Language, - ((fileTuple.ReadOnly ? WindowsInstallerConstants.MsidbFileAttributesReadOnly : 0) - | (fileTuple.Hidden ? WindowsInstallerConstants.MsidbFileAttributesHidden : 0) - | (fileTuple.System ? WindowsInstallerConstants.MsidbFileAttributesSystem : 0) - | (fileTuple.Vital ? WindowsInstallerConstants.MsidbFileAttributesVital : 0) - | (fileTuple.Checksum ? WindowsInstallerConstants.MsidbFileAttributesChecksum : 0) - | ((fileTuple.Compressed.HasValue && fileTuple.Compressed.Value) ? WindowsInstallerConstants.MsidbFileAttributesCompressed : 0) - | ((fileTuple.Compressed.HasValue && !fileTuple.Compressed.Value) ? WindowsInstallerConstants.MsidbFileAttributesNoncompressed : 0)) - .ToString()); - break; + // "Somebody" sometimes writes out a null field even when the column definition says + // it's non-nullable. Not naming names or anything. (SWID tags.) + fieldValues[8] = "0"; } + fields = String.Join(",", fieldValues); + break; + } + case "WixMedia": + break; + default: + fields = String.Join(",", row.Fields.Select(SafeConvertField)); + break; + } - case "Registry": - { - var registryTuple = (RegistryTuple)tuple; - var value = registryTuple.Value; - - switch (registryTuple.ValueType) - { - case RegistryValueType.Binary: - value = String.Concat("#x", value); - break; - case RegistryValueType.Expandable: - value = String.Concat("#%", value); - break; - case RegistryValueType.Integer: - value = String.Concat("#", value); - break; - case RegistryValueType.MultiString: - switch (registryTuple.ValueAction) - { - case RegistryValueActionType.Append: - value = String.Concat("[~]", value); - break; - case RegistryValueActionType.Prepend: - value = String.Concat(value, "[~]"); - break; - case RegistryValueActionType.Write: - default: - if (null != value && -1 == value.IndexOf("[~]", StringComparison.Ordinal)) - { - value = String.Concat("[~]", value, "[~]"); - } - break; - } - break; - case RegistryValueType.String: - // escape the leading '#' character for string registry keys - if (null != value && value.StartsWith("#", StringComparison.Ordinal)) - { - value = String.Concat("#", value); - } - break; - } + if (fields != null) + { + yield return $"{row.Table.Name}:{fields}"; + } + } - fields = String.Join(",", - ((int)registryTuple.Root).ToString(), - registryTuple.Key, - registryTuple.Name, - value, - registryTuple.Component_ - ); - break; - } + private static IEnumerable TupleToStrings(IntermediateTuple tuple) + { + string fields; + switch (tuple.Definition.Name) + { + // Massage output to match WiX v3 rows and v4 tuples. + // + case "Component": + { + var componentTuple = (ComponentTuple)tuple; + var attributes = ComponentLocation.Either == componentTuple.Location ? WindowsInstallerConstants.MsidbComponentAttributesOptional : 0; + attributes |= ComponentLocation.SourceOnly == componentTuple.Location ? WindowsInstallerConstants.MsidbComponentAttributesSourceOnly : 0; + attributes |= ComponentKeyPathType.Registry == componentTuple.KeyPathType ? WindowsInstallerConstants.MsidbComponentAttributesRegistryKeyPath : 0; + attributes |= ComponentKeyPathType.OdbcDataSource == componentTuple.KeyPathType ? WindowsInstallerConstants.MsidbComponentAttributesODBCDataSource : 0; + attributes |= componentTuple.DisableRegistryReflection ? WindowsInstallerConstants.MsidbComponentAttributesDisableRegistryReflection : 0; + attributes |= componentTuple.NeverOverwrite ? WindowsInstallerConstants.MsidbComponentAttributesNeverOverwrite : 0; + attributes |= componentTuple.Permanent ? WindowsInstallerConstants.MsidbComponentAttributesPermanent : 0; + attributes |= componentTuple.SharedDllRefCount ? WindowsInstallerConstants.MsidbComponentAttributesSharedDllRefCount : 0; + attributes |= componentTuple.Shared ? WindowsInstallerConstants.MsidbComponentAttributesShared : 0; + attributes |= componentTuple.Transitive ? WindowsInstallerConstants.MsidbComponentAttributesTransitive : 0; + attributes |= componentTuple.UninstallWhenSuperseded ? WindowsInstallerConstants.MsidbComponentAttributes64bit : 0; + attributes |= componentTuple.Win64 ? WindowsInstallerConstants.MsidbComponentAttributes64bit : 0; + + fields = String.Join(",", + componentTuple.ComponentId, + componentTuple.DirectoryRef, + attributes.ToString(), + componentTuple.Condition, + componentTuple.KeyPath + ); + break; + } + case "CustomAction": + { + var customActionTuple = (CustomActionTuple)tuple; + var type = customActionTuple.Win64 ? WindowsInstallerConstants.MsidbCustomActionType64BitScript : 0; + type |= customActionTuple.TSAware ? WindowsInstallerConstants.MsidbCustomActionTypeTSAware : 0; + type |= customActionTuple.Impersonate ? 0 : WindowsInstallerConstants.MsidbCustomActionTypeNoImpersonate; + type |= customActionTuple.IgnoreResult ? WindowsInstallerConstants.MsidbCustomActionTypeContinue : 0; + type |= customActionTuple.Hidden ? WindowsInstallerConstants.MsidbCustomActionTypeHideTarget : 0; + type |= customActionTuple.Async ? WindowsInstallerConstants.MsidbCustomActionTypeAsync : 0; + type |= CustomActionExecutionType.FirstSequence == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeFirstSequence : 0; + type |= CustomActionExecutionType.OncePerProcess == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeOncePerProcess : 0; + type |= CustomActionExecutionType.ClientRepeat == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeClientRepeat : 0; + type |= CustomActionExecutionType.Deferred == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeInScript : 0; + type |= CustomActionExecutionType.Rollback == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeInScript | WindowsInstallerConstants.MsidbCustomActionTypeRollback : 0; + type |= CustomActionExecutionType.Commit == customActionTuple.ExecutionType ? WindowsInstallerConstants.MsidbCustomActionTypeInScript | WindowsInstallerConstants.MsidbCustomActionTypeCommit : 0; + type |= CustomActionSourceType.File == customActionTuple.SourceType ? WindowsInstallerConstants.MsidbCustomActionTypeSourceFile : 0; + type |= CustomActionSourceType.Directory == customActionTuple.SourceType ? WindowsInstallerConstants.MsidbCustomActionTypeDirectory : 0; + type |= CustomActionSourceType.Property == customActionTuple.SourceType ? WindowsInstallerConstants.MsidbCustomActionTypeProperty : 0; + type |= CustomActionTargetType.Dll == customActionTuple.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeDll : 0; + type |= CustomActionTargetType.Exe == customActionTuple.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeExe : 0; + type |= CustomActionTargetType.TextData == customActionTuple.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeTextData : 0; + type |= CustomActionTargetType.JScript == customActionTuple.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeJScript : 0; + type |= CustomActionTargetType.VBScript == customActionTuple.TargetType ? WindowsInstallerConstants.MsidbCustomActionTypeVBScript : 0; + + fields = String.Join(",", + type.ToString(), + customActionTuple.Source, + customActionTuple.Target, + customActionTuple.PatchUninstall ? WindowsInstallerConstants.MsidbCustomActionTypePatchUninstall.ToString() : null + ); + break; + } + case "Directory": + { + var directoryTuple = (DirectoryTuple)tuple; - case "RemoveRegistry": + if (!String.IsNullOrEmpty(directoryTuple.ComponentGuidGenerationSeed)) { - var removeRegistryTuple = (RemoveRegistryTuple)tuple; - fields = String.Join(",", - ((int)removeRegistryTuple.Root).ToString(), - removeRegistryTuple.Key, - removeRegistryTuple.Name, - removeRegistryTuple.Component_ - ); - break; + yield return $"WixDirectory:{directoryTuple.Id.Id},{directoryTuple.ComponentGuidGenerationSeed}"; } - case "ServiceControl": - { - var serviceControlTuple = (ServiceControlTuple)tuple; - - var events = serviceControlTuple.InstallRemove ? WindowsInstallerConstants.MsidbServiceControlEventDelete : 0; - events |= serviceControlTuple.UninstallRemove ? WindowsInstallerConstants.MsidbServiceControlEventUninstallDelete : 0; - events |= serviceControlTuple.InstallStart ? WindowsInstallerConstants.MsidbServiceControlEventStart : 0; - events |= serviceControlTuple.UninstallStart ? WindowsInstallerConstants.MsidbServiceControlEventUninstallStart : 0; - events |= serviceControlTuple.InstallStop ? WindowsInstallerConstants.MsidbServiceControlEventStop : 0; - events |= serviceControlTuple.UninstallStop ? WindowsInstallerConstants.MsidbServiceControlEventUninstallStop : 0; - - fields = String.Join(",", - serviceControlTuple.Name, - events.ToString(), - serviceControlTuple.Arguments, - serviceControlTuple.Wait == true ? "1" : "0", - serviceControlTuple.Component_ - ); - break; - } + fields = String.Join(",", directoryTuple.ParentDirectoryRef, directoryTuple.Name, directoryTuple.ShortName, directoryTuple.SourceName, directoryTuple.SourceShortName); + break; + } + case "Feature": + { + var featureTuple = (FeatureTuple)tuple; + var attributes = featureTuple.DisallowAbsent ? WindowsInstallerConstants.MsidbFeatureAttributesUIDisallowAbsent : 0; + attributes |= featureTuple.DisallowAdvertise ? WindowsInstallerConstants.MsidbFeatureAttributesDisallowAdvertise : 0; + attributes |= FeatureInstallDefault.FollowParent == featureTuple.InstallDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFollowParent : 0; + attributes |= FeatureInstallDefault.Source == featureTuple.InstallDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFavorSource : 0; + attributes |= FeatureTypicalDefault.Advertise == featureTuple.TypicalDefault ? WindowsInstallerConstants.MsidbFeatureAttributesFavorAdvertise : 0; + + fields = String.Join(",", + featureTuple.ParentFeatureRef, + featureTuple.Title, + featureTuple.Description, + featureTuple.Display.ToString(), + featureTuple.Level.ToString(), + featureTuple.DirectoryRef, + attributes.ToString()); + break; + } + case "File": + { + var fileTuple = (FileTuple)tuple; - case "ServiceInstall": + if (fileTuple.BindPath != null) { - var serviceInstallTuple = (ServiceInstallTuple)tuple; - - var errorControl = (int)serviceInstallTuple.ErrorControl; - errorControl |= serviceInstallTuple.Vital ? WindowsInstallerConstants.MsidbServiceInstallErrorControlVital : 0; - - var serviceType = (int)serviceInstallTuple.ServiceType; - serviceType |= serviceInstallTuple.Interactive ? WindowsInstallerConstants.MsidbServiceInstallInteractive : 0; - - fields = String.Join(",", - serviceInstallTuple.Name, - serviceInstallTuple.DisplayName, - serviceType.ToString(), - ((int)serviceInstallTuple.StartType).ToString(), - errorControl.ToString(), - serviceInstallTuple.LoadOrderGroup, - serviceInstallTuple.Dependencies, - serviceInstallTuple.StartName, - serviceInstallTuple.Password, - serviceInstallTuple.Arguments, - serviceInstallTuple.Component_, - serviceInstallTuple.Description - ); - break; + yield return $"BindImage:{fileTuple.Id.Id},{fileTuple.BindPath}"; } - case "Upgrade": + if (fileTuple.FontTitle != null) { - var upgradeTuple = (UpgradeTuple)tuple; - - var attributes = upgradeTuple.MigrateFeatures ? WindowsInstallerConstants.MsidbUpgradeAttributesMigrateFeatures : 0; - attributes |= upgradeTuple.OnlyDetect ? WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect : 0; - attributes |= upgradeTuple.IgnoreRemoveFailures ? WindowsInstallerConstants.MsidbUpgradeAttributesIgnoreRemoveFailure : 0; - attributes |= upgradeTuple.VersionMinInclusive ? WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive : 0; - attributes |= upgradeTuple.VersionMaxInclusive ? WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive : 0; - attributes |= upgradeTuple.ExcludeLanguages ? WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive : 0; - - fields = String.Join(",", - upgradeTuple.VersionMin, - upgradeTuple.VersionMax, - upgradeTuple.Language, - attributes.ToString(), - upgradeTuple.Remove, - upgradeTuple.ActionProperty - ); - break; + yield return $"Font:{fileTuple.Id.Id},{fileTuple.FontTitle}"; } - case "WixAction": + if (fileTuple.SelfRegCost.HasValue) { - var wixActionTuple = (WixActionTuple)tuple; - fields = String.Join(",", - wixActionTuple.SequenceTable, - wixActionTuple.Action, - wixActionTuple.Condition, - // BUGBUGBUG: AB#2626 - wixActionTuple.Sequence == 0 ? String.Empty : wixActionTuple.Sequence.ToString(), - wixActionTuple.Before, - wixActionTuple.After, - wixActionTuple.Overridable == true ? "1" : "0" - ); - break; + yield return $"SelfReg:{fileTuple.Id.Id},{fileTuple.SelfRegCost}"; } - case "WixComplexReference": - { - var wixComplexReferenceTuple = (WixComplexReferenceTuple)tuple; - fields = String.Join(",", - wixComplexReferenceTuple.Parent, - ((int)wixComplexReferenceTuple.ParentType).ToString(), - wixComplexReferenceTuple.ParentLanguage, - wixComplexReferenceTuple.Child, - ((int)wixComplexReferenceTuple.ChildType).ToString(), - wixComplexReferenceTuple.IsPrimary ? "1" : "0" - ); - break; - } + fields = String.Join(",", + fileTuple.ComponentRef, + fileTuple.Name, + fileTuple.FileSize.ToString(), + fileTuple.Version, + fileTuple.Language, + ((fileTuple.ReadOnly ? WindowsInstallerConstants.MsidbFileAttributesReadOnly : 0) + | (fileTuple.Hidden ? WindowsInstallerConstants.MsidbFileAttributesHidden : 0) + | (fileTuple.System ? WindowsInstallerConstants.MsidbFileAttributesSystem : 0) + | (fileTuple.Vital ? WindowsInstallerConstants.MsidbFileAttributesVital : 0) + | (fileTuple.Checksum ? WindowsInstallerConstants.MsidbFileAttributesChecksum : 0) + | ((fileTuple.Compressed.HasValue && fileTuple.Compressed.Value) ? WindowsInstallerConstants.MsidbFileAttributesCompressed : 0) + | ((fileTuple.Compressed.HasValue && !fileTuple.Compressed.Value) ? WindowsInstallerConstants.MsidbFileAttributesNoncompressed : 0)) + .ToString()); + break; + } - case "WixFile": - { - var wixFileTuple = (WixFileTuple)tuple; - fields = String.Concat( - wixFileTuple.AssemblyType == FileAssemblyType.DotNetAssembly ? "0" : wixFileTuple.AssemblyType == FileAssemblyType.Win32Assembly ? "1" : String.Empty, ",", - String.Join(",", tuple.Fields.Skip(2).Take(6).Select(field => (string)field).ToArray())); - break; - } + case "Media": + fields = String.Join(",", tuple.Fields.Skip(1).Select(SafeConvertField)); + break; + + case "Registry": + { + var registryTuple = (RegistryTuple)tuple; + var value = registryTuple.Value; - case "WixProperty": + switch (registryTuple.ValueType) { - var wixPropertyTuple = (WixPropertyTuple)tuple; - var attributes = 0; - attributes |= wixPropertyTuple.Admin ? 0x1 : 0; - attributes |= wixPropertyTuple.Hidden ? 0x2 : 0; - attributes |= wixPropertyTuple.Secure ? 0x4 : 0; - - fields = String.Join(",", - wixPropertyTuple.Property_, - attributes.ToString() - ); + case RegistryValueType.Binary: + value = String.Concat("#x", value); + break; + case RegistryValueType.Expandable: + value = String.Concat("#%", value); + break; + case RegistryValueType.Integer: + value = String.Concat("#", value); + break; + case RegistryValueType.MultiString: + switch (registryTuple.ValueAction) + { + case RegistryValueActionType.Append: + value = String.Concat("[~]", value); + break; + case RegistryValueActionType.Prepend: + value = String.Concat(value, "[~]"); + break; + case RegistryValueActionType.Write: + default: + if (null != value && -1 == value.IndexOf("[~]", StringComparison.Ordinal)) + { + value = String.Concat("[~]", value, "[~]"); + } + break; + } + break; + case RegistryValueType.String: + // escape the leading '#' character for string registry keys + if (null != value && value.StartsWith("#", StringComparison.Ordinal)) + { + value = String.Concat("#", value); + } break; } + fields = String.Join(",", + ((int)registryTuple.Root).ToString(), + registryTuple.Key, + registryTuple.Name, + value, + registryTuple.ComponentRef + ); + break; + } + + case "RemoveRegistry": + { + var removeRegistryTuple = (RemoveRegistryTuple)tuple; + fields = String.Join(",", + ((int)removeRegistryTuple.Root).ToString(), + removeRegistryTuple.Key, + removeRegistryTuple.Name, + removeRegistryTuple.ComponentRef + ); + break; + } + + case "ServiceControl": + { + var serviceControlTuple = (ServiceControlTuple)tuple; + + var events = serviceControlTuple.InstallRemove ? WindowsInstallerConstants.MsidbServiceControlEventDelete : 0; + events |= serviceControlTuple.UninstallRemove ? WindowsInstallerConstants.MsidbServiceControlEventUninstallDelete : 0; + events |= serviceControlTuple.InstallStart ? WindowsInstallerConstants.MsidbServiceControlEventStart : 0; + events |= serviceControlTuple.UninstallStart ? WindowsInstallerConstants.MsidbServiceControlEventUninstallStart : 0; + events |= serviceControlTuple.InstallStop ? WindowsInstallerConstants.MsidbServiceControlEventStop : 0; + events |= serviceControlTuple.UninstallStop ? WindowsInstallerConstants.MsidbServiceControlEventUninstallStop : 0; + + fields = String.Join(",", + serviceControlTuple.Name, + events.ToString(), + serviceControlTuple.Arguments, + serviceControlTuple.Wait == true ? "1" : "0", + serviceControlTuple.ComponentRef + ); + break; + } + + case "ServiceInstall": + { + var serviceInstallTuple = (ServiceInstallTuple)tuple; + + var errorControl = (int)serviceInstallTuple.ErrorControl; + errorControl |= serviceInstallTuple.Vital ? WindowsInstallerConstants.MsidbServiceInstallErrorControlVital : 0; + + var serviceType = (int)serviceInstallTuple.ServiceType; + serviceType |= serviceInstallTuple.Interactive ? WindowsInstallerConstants.MsidbServiceInstallInteractive : 0; + + fields = String.Join(",", + serviceInstallTuple.Name, + serviceInstallTuple.DisplayName, + serviceType.ToString(), + ((int)serviceInstallTuple.StartType).ToString(), + errorControl.ToString(), + serviceInstallTuple.LoadOrderGroup, + serviceInstallTuple.Dependencies, + serviceInstallTuple.StartName, + serviceInstallTuple.Password, + serviceInstallTuple.Arguments, + serviceInstallTuple.ComponentRef, + serviceInstallTuple.Description + ); + break; + } + + case "Upgrade": + { + var upgradeTuple = (UpgradeTuple)tuple; + + var attributes = upgradeTuple.MigrateFeatures ? WindowsInstallerConstants.MsidbUpgradeAttributesMigrateFeatures : 0; + attributes |= upgradeTuple.OnlyDetect ? WindowsInstallerConstants.MsidbUpgradeAttributesOnlyDetect : 0; + attributes |= upgradeTuple.IgnoreRemoveFailures ? WindowsInstallerConstants.MsidbUpgradeAttributesIgnoreRemoveFailure : 0; + attributes |= upgradeTuple.VersionMinInclusive ? WindowsInstallerConstants.MsidbUpgradeAttributesVersionMinInclusive : 0; + attributes |= upgradeTuple.VersionMaxInclusive ? WindowsInstallerConstants.MsidbUpgradeAttributesVersionMaxInclusive : 0; + attributes |= upgradeTuple.ExcludeLanguages ? WindowsInstallerConstants.MsidbUpgradeAttributesLanguagesExclusive : 0; + + fields = String.Join(",", + upgradeTuple.VersionMin, + upgradeTuple.VersionMax, + upgradeTuple.Language, + attributes.ToString(), + upgradeTuple.Remove, + upgradeTuple.ActionProperty + ); + break; + } + + case "WixAction": + { + var wixActionTuple = (WixActionTuple)tuple; + var data = wixActionTuple.Fields[(int)WixActionTupleFields.SequenceTable].AsObject(); + var sequenceTableAsInt = data is string ? (int)SequenceStringToSequenceTable(data) : (int)wixActionTuple.SequenceTable; + + fields = String.Join(",", + sequenceTableAsInt, + wixActionTuple.Action, + wixActionTuple.Condition, + wixActionTuple.Sequence?.ToString() ?? String.Empty, + wixActionTuple.Before, + wixActionTuple.After, + wixActionTuple.Overridable == true ? "1" : "0" + ); + break; + } + + case "WixComplexReference": + { + var wixComplexReferenceTuple = (WixComplexReferenceTuple)tuple; + fields = String.Join(",", + wixComplexReferenceTuple.Parent, + (int)wixComplexReferenceTuple.ParentType, + wixComplexReferenceTuple.ParentLanguage, + wixComplexReferenceTuple.Child, + (int)wixComplexReferenceTuple.ChildType, + wixComplexReferenceTuple.IsPrimary ? "1" : "0" + ); + break; + } + + case "WixFile": + { + var wixFileTuple = (WixFileTuple)tuple; + fields = String.Concat( + wixFileTuple.AssemblyType == FileAssemblyType.DotNetAssembly ? "0" : wixFileTuple.AssemblyType == FileAssemblyType.Win32Assembly ? "1" : String.Empty, ",", + String.Join(",", tuple.Fields.Skip(1).Take(8).Select(field => (string)field))); + break; + } + + case "WixProperty": + { + var wixPropertyTuple = (WixPropertyTuple)tuple; + var attributes = wixPropertyTuple.Admin ? 0x1 : 0; + attributes |= wixPropertyTuple.Hidden ? 0x2 : 0; + attributes |= wixPropertyTuple.Secure ? 0x4 : 0; + + fields = String.Join(",", + wixPropertyTuple.PropertyRef, + attributes.ToString() + ); + break; + } + + default: + fields = String.Join(",", tuple.Fields.Select(SafeConvertField)); + break; + } + + var name = tuple.Definition.Type == TupleDefinitionType.SummaryInformation ? "_SummaryInformation" : tuple.Definition.Name; + var id = tuple.Id?.Id ?? String.Empty; + fields = String.IsNullOrEmpty(id) ? fields : String.IsNullOrEmpty(fields) ? id : $"{id},{fields}"; + yield return $"{name}:{fields}"; + } + + private static SequenceTable SequenceStringToSequenceTable(object sequenceString) + { + switch (sequenceString) + { + case "AdminExecuteSequence": + return SequenceTable.AdminExecuteSequence; + case "AdminUISequence": + return SequenceTable.AdminUISequence; + case "AdvtExecuteSequence": + return SequenceTable.AdvertiseExecuteSequence; + case "InstallExecuteSequence": + return SequenceTable.InstallExecuteSequence; + case "InstallUISequence": + return SequenceTable.InstallUISequence; + default: + throw new ArgumentException($"Unknown sequence: {sequenceString}"); } + } - var id = tuple.Id == null ? String.Empty : String.Concat(",", tuple.Id.Id); - return $"{tuple.Definition.Name}{id},{fields}"; + private static string SafeConvertField(Wix3.Field field) + { + return field?.Data?.ToString(); + } + + private static string SafeConvertField(IntermediateField field) + { + var data = field.AsObject(); + if (data is IntermediateFieldPathValue path) + { + return path.Path; + } + + return data?.ToString(); + } + + private static string[] SplitDefaultDir(string defaultDir) + { + var split1 = defaultDir.Split(':'); + var targetSplit = split1.Length > 1 ? split1[1].Split('|') : split1[0].Split('|'); + var sourceSplit = split1.Length > 1 ? split1[0].Split('|') : new[] { String.Empty }; + return new[] + { + targetSplit.Length > 1 ? targetSplit[1] : targetSplit[0], + targetSplit.Length > 1 ? targetSplit[0] : String.Empty, + sourceSplit.Length > 1 ? sourceSplit[1] : sourceSplit[0], + sourceSplit.Length > 1 ? sourceSplit[0] : String.Empty + }; } } } -- cgit v1.2.3-55-g6feb