From 7ad398d455c42bae61f5196c3f2f66aecf9f9a1a Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Tue, 7 Apr 2020 20:06:03 +1000 Subject: Modernize VSExtension. --- .../VisualStudioExtensionFixture.cs | 30 +- src/wixext/Tuples/HelpFileToNamespaceTuple.cs | 55 ++++ src/wixext/Tuples/HelpFileTuple.cs | 95 +++++++ src/wixext/Tuples/HelpFilterToNamespaceTuple.cs | 55 ++++ src/wixext/Tuples/HelpFilterTuple.cs | 55 ++++ src/wixext/Tuples/HelpNamespaceTuple.cs | 63 +++++ src/wixext/Tuples/HelpPluginTuple.cs | 79 ++++++ src/wixext/Tuples/VSTupleDefinitions.cs | 59 ++++ src/wixext/VSCompiler.cs | 305 ++++++++++++--------- src/wixext/VSExtensionData.cs | 12 + src/wixext/VSTableDefinitions.cs | 147 +++++----- .../VSWindowsInstallerBackendBinderExtension.cs | 4 +- 12 files changed, 755 insertions(+), 204 deletions(-) create mode 100644 src/wixext/Tuples/HelpFileToNamespaceTuple.cs create mode 100644 src/wixext/Tuples/HelpFileTuple.cs create mode 100644 src/wixext/Tuples/HelpFilterToNamespaceTuple.cs create mode 100644 src/wixext/Tuples/HelpFilterTuple.cs create mode 100644 src/wixext/Tuples/HelpNamespaceTuple.cs create mode 100644 src/wixext/Tuples/HelpPluginTuple.cs create mode 100644 src/wixext/Tuples/VSTupleDefinitions.cs diff --git a/src/test/WixToolsetTest.VisualStudio/VisualStudioExtensionFixture.cs b/src/test/WixToolsetTest.VisualStudio/VisualStudioExtensionFixture.cs index a980071e..b8800cee 100644 --- a/src/test/WixToolsetTest.VisualStudio/VisualStudioExtensionFixture.cs +++ b/src/test/WixToolsetTest.VisualStudio/VisualStudioExtensionFixture.cs @@ -19,21 +19,21 @@ namespace WixToolsetTest.VisualStudio var results = build.BuildAndQuery(Build, "CustomAction"); Assert.Equal(new[] { - "CustomAction:SetVS2010Vsix\t51\tVS_VSIX_INSTALLER_PATH\t[VS2010_VSIX_INSTALLER_PATH]\t0", - "CustomAction:SetVS2012Vsix\t51\tVS_VSIX_INSTALLER_PATH\t[VS2012_VSIX_INSTALLER_PATH]\t0", - "CustomAction:SetVS2013Vsix\t51\tVS_VSIX_INSTALLER_PATH\t[VS2013_VSIX_INSTALLER_PATH]\t0", - "CustomAction:SetVS2015Vsix\t51\tVS_VSIX_INSTALLER_PATH\t[VS2015_VSIX_INSTALLER_PATH]\t0", - "CustomAction:vimyrEjb_CFhXi3TTLayKNM2w7rvr4\t3122\tVS_VSIX_INSTALLER_PATH\t/q \"[#filzi8nwT8Ta133xcfp7qSIdGdRiC0]\" /admin\t0", - "CustomAction:viuFqqe3R3R3Fh7P05ubFRhqQlCBdQ\t1074\tVS_VSIX_INSTALLER_PATH\t/q \"[#filzi8nwT8Ta133xcfp7qSIdGdRiC0]\"\t0", - "CustomAction:vrmyrEjb_CFhXi3TTLayKNM2w7rvr4\t3442\tVS_VSIX_INSTALLER_PATH\t/q /u:\"ExampleVsix\" /admin\t0", - "CustomAction:vruFqqe3R3R3Fh7P05ubFRhqQlCBdQ\t1394\tVS_VSIX_INSTALLER_PATH\t/q /u:\"ExampleVsix\"\t0", - "CustomAction:VSFindInstances\t257\tVSCA\tFindInstances\t0", - "CustomAction:vumyrEjb_CFhXi3TTLayKNM2w7rvr4\t3186\tVS_VSIX_INSTALLER_PATH\t/q /u:\"ExampleVsix\" /admin\t0", - "CustomAction:vuuFqqe3R3R3Fh7P05ubFRhqQlCBdQ\t1138\tVS_VSIX_INSTALLER_PATH\t/q /u:\"ExampleVsix\"\t0", - "CustomAction:Vwd2012VsixWhenVSAbsent\t51\tVS_VSIX_INSTALLER_PATH\t[VWD2012_VSIX_INSTALL_ROOT]\\Common7\\IDE\\VSIXInstaller.exe\t0", - "CustomAction:Vwd2013VsixWhenVSAbsent\t51\tVS_VSIX_INSTALLER_PATH\t[VWD2013_VSIX_INSTALL_ROOT]\\Common7\\IDE\\VSIXInstaller.exe\t0", - "CustomAction:Vwd2015VsixWhenVSAbsent\t51\tVS_VSIX_INSTALLER_PATH\t[VWD2015_VSIX_INSTALL_ROOT]\\Common7\\IDE\\VSIXInstaller.exe\t0", - }, results.OrderBy(s => s).ToArray()); + "CustomAction:SetVS2010Vsix\t51\tVS_VSIX_INSTALLER_PATH\t[VS2010_VSIX_INSTALLER_PATH]\t", + "CustomAction:SetVS2012Vsix\t51\tVS_VSIX_INSTALLER_PATH\t[VS2012_VSIX_INSTALLER_PATH]\t", + "CustomAction:SetVS2013Vsix\t51\tVS_VSIX_INSTALLER_PATH\t[VS2013_VSIX_INSTALLER_PATH]\t", + "CustomAction:SetVS2015Vsix\t51\tVS_VSIX_INSTALLER_PATH\t[VS2015_VSIX_INSTALLER_PATH]\t", + "CustomAction:vimyrEjb_CFhXi3TTLayKNM2w7rvr4\t3122\tVS_VSIX_INSTALLER_PATH\t/q \"[#filzi8nwT8Ta133xcfp7qSIdGdRiC0]\" /admin\t", + "CustomAction:viuFqqe3R3R3Fh7P05ubFRhqQlCBdQ\t1074\tVS_VSIX_INSTALLER_PATH\t/q \"[#filzi8nwT8Ta133xcfp7qSIdGdRiC0]\"\t", + "CustomAction:vrmyrEjb_CFhXi3TTLayKNM2w7rvr4\t3442\tVS_VSIX_INSTALLER_PATH\t/q /u:\"ExampleVsix\" /admin\t", + "CustomAction:vruFqqe3R3R3Fh7P05ubFRhqQlCBdQ\t1394\tVS_VSIX_INSTALLER_PATH\t/q /u:\"ExampleVsix\"\t", + "CustomAction:VSFindInstances\t257\tVSCA\tFindInstances\t", + "CustomAction:vumyrEjb_CFhXi3TTLayKNM2w7rvr4\t3186\tVS_VSIX_INSTALLER_PATH\t/q /u:\"ExampleVsix\" /admin\t", + "CustomAction:vuuFqqe3R3R3Fh7P05ubFRhqQlCBdQ\t1138\tVS_VSIX_INSTALLER_PATH\t/q /u:\"ExampleVsix\"\t", + "CustomAction:Vwd2012VsixWhenVSAbsent\t51\tVS_VSIX_INSTALLER_PATH\t[VWD2012_VSIX_INSTALL_ROOT]\\Common7\\IDE\\VSIXInstaller.exe\t", + "CustomAction:Vwd2013VsixWhenVSAbsent\t51\tVS_VSIX_INSTALLER_PATH\t[VWD2013_VSIX_INSTALL_ROOT]\\Common7\\IDE\\VSIXInstaller.exe\t", + "CustomAction:Vwd2015VsixWhenVSAbsent\t51\tVS_VSIX_INSTALLER_PATH\t[VWD2015_VSIX_INSTALL_ROOT]\\Common7\\IDE\\VSIXInstaller.exe\t", + }, results); } private static void Build(string[] args) diff --git a/src/wixext/Tuples/HelpFileToNamespaceTuple.cs b/src/wixext/Tuples/HelpFileToNamespaceTuple.cs new file mode 100644 index 00000000..f91dacc1 --- /dev/null +++ b/src/wixext/Tuples/HelpFileToNamespaceTuple.cs @@ -0,0 +1,55 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.VisualStudio +{ + using WixToolset.Data; + using WixToolset.VisualStudio.Tuples; + + public static partial class VSTupleDefinitions + { + public static readonly IntermediateTupleDefinition HelpFileToNamespace = new IntermediateTupleDefinition( + VSTupleDefinitionType.HelpFileToNamespace.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(HelpFileToNamespaceTupleFields.HelpFileRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(HelpFileToNamespaceTupleFields.HelpNamespaceRef), IntermediateFieldType.String), + }, + typeof(HelpFileToNamespaceTuple)); + } +} + +namespace WixToolset.VisualStudio.Tuples +{ + using WixToolset.Data; + + public enum HelpFileToNamespaceTupleFields + { + HelpFileRef, + HelpNamespaceRef, + } + + public class HelpFileToNamespaceTuple : IntermediateTuple + { + public HelpFileToNamespaceTuple() : base(VSTupleDefinitions.HelpFileToNamespace, null, null) + { + } + + public HelpFileToNamespaceTuple(SourceLineNumber sourceLineNumber, Identifier id = null) : base(VSTupleDefinitions.HelpFileToNamespace, sourceLineNumber, id) + { + } + + public IntermediateField this[HelpFileToNamespaceTupleFields index] => this.Fields[(int)index]; + + public string HelpFileRef + { + get => this.Fields[(int)HelpFileToNamespaceTupleFields.HelpFileRef].AsString(); + set => this.Set((int)HelpFileToNamespaceTupleFields.HelpFileRef, value); + } + + public string HelpNamespaceRef + { + get => this.Fields[(int)HelpFileToNamespaceTupleFields.HelpNamespaceRef].AsString(); + set => this.Set((int)HelpFileToNamespaceTupleFields.HelpNamespaceRef, value); + } + } +} \ No newline at end of file diff --git a/src/wixext/Tuples/HelpFileTuple.cs b/src/wixext/Tuples/HelpFileTuple.cs new file mode 100644 index 00000000..9ea5e8e3 --- /dev/null +++ b/src/wixext/Tuples/HelpFileTuple.cs @@ -0,0 +1,95 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.VisualStudio +{ + using WixToolset.Data; + using WixToolset.VisualStudio.Tuples; + + public static partial class VSTupleDefinitions + { + public static readonly IntermediateTupleDefinition HelpFile = new IntermediateTupleDefinition( + VSTupleDefinitionType.HelpFile.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(HelpFileTupleFields.HelpFileName), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(HelpFileTupleFields.LangID), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(HelpFileTupleFields.HxSFileRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(HelpFileTupleFields.HxIFileRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(HelpFileTupleFields.HxQFileRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(HelpFileTupleFields.HxRFileRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(HelpFileTupleFields.SamplesFileRef), IntermediateFieldType.String), + }, + typeof(HelpFileTuple)); + } +} + +namespace WixToolset.VisualStudio.Tuples +{ + using WixToolset.Data; + + public enum HelpFileTupleFields + { + HelpFileName, + LangID, + HxSFileRef, + HxIFileRef, + HxQFileRef, + HxRFileRef, + SamplesFileRef, + } + + public class HelpFileTuple : IntermediateTuple + { + public HelpFileTuple() : base(VSTupleDefinitions.HelpFile, null, null) + { + } + + public HelpFileTuple(SourceLineNumber sourceLineNumber, Identifier id = null) : base(VSTupleDefinitions.HelpFile, sourceLineNumber, id) + { + } + + public IntermediateField this[HelpFileTupleFields index] => this.Fields[(int)index]; + + public string HelpFileName + { + get => this.Fields[(int)HelpFileTupleFields.HelpFileName].AsString(); + set => this.Set((int)HelpFileTupleFields.HelpFileName, value); + } + + public int LangID + { + get => this.Fields[(int)HelpFileTupleFields.LangID].AsNumber(); + set => this.Set((int)HelpFileTupleFields.LangID, value); + } + + public string HxSFileRef + { + get => this.Fields[(int)HelpFileTupleFields.HxSFileRef].AsString(); + set => this.Set((int)HelpFileTupleFields.HxSFileRef, value); + } + + public string HxIFileRef + { + get => this.Fields[(int)HelpFileTupleFields.HxIFileRef].AsString(); + set => this.Set((int)HelpFileTupleFields.HxIFileRef, value); + } + + public string HxQFileRef + { + get => this.Fields[(int)HelpFileTupleFields.HxQFileRef].AsString(); + set => this.Set((int)HelpFileTupleFields.HxQFileRef, value); + } + + public string HxRFileRef + { + get => this.Fields[(int)HelpFileTupleFields.HxRFileRef].AsString(); + set => this.Set((int)HelpFileTupleFields.HxRFileRef, value); + } + + public string SamplesFileRef + { + get => this.Fields[(int)HelpFileTupleFields.SamplesFileRef].AsString(); + set => this.Set((int)HelpFileTupleFields.SamplesFileRef, value); + } + } +} \ No newline at end of file diff --git a/src/wixext/Tuples/HelpFilterToNamespaceTuple.cs b/src/wixext/Tuples/HelpFilterToNamespaceTuple.cs new file mode 100644 index 00000000..c6690d47 --- /dev/null +++ b/src/wixext/Tuples/HelpFilterToNamespaceTuple.cs @@ -0,0 +1,55 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.VisualStudio +{ + using WixToolset.Data; + using WixToolset.VisualStudio.Tuples; + + public static partial class VSTupleDefinitions + { + public static readonly IntermediateTupleDefinition HelpFilterToNamespace = new IntermediateTupleDefinition( + VSTupleDefinitionType.HelpFilterToNamespace.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(HelpFilterToNamespaceTupleFields.HelpFilterRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(HelpFilterToNamespaceTupleFields.HelpNamespaceRef), IntermediateFieldType.String), + }, + typeof(HelpFilterToNamespaceTuple)); + } +} + +namespace WixToolset.VisualStudio.Tuples +{ + using WixToolset.Data; + + public enum HelpFilterToNamespaceTupleFields + { + HelpFilterRef, + HelpNamespaceRef, + } + + public class HelpFilterToNamespaceTuple : IntermediateTuple + { + public HelpFilterToNamespaceTuple() : base(VSTupleDefinitions.HelpFilterToNamespace, null, null) + { + } + + public HelpFilterToNamespaceTuple(SourceLineNumber sourceLineNumber, Identifier id = null) : base(VSTupleDefinitions.HelpFilterToNamespace, sourceLineNumber, id) + { + } + + public IntermediateField this[HelpFilterToNamespaceTupleFields index] => this.Fields[(int)index]; + + public string HelpFilterRef + { + get => this.Fields[(int)HelpFilterToNamespaceTupleFields.HelpFilterRef].AsString(); + set => this.Set((int)HelpFilterToNamespaceTupleFields.HelpFilterRef, value); + } + + public string HelpNamespaceRef + { + get => this.Fields[(int)HelpFilterToNamespaceTupleFields.HelpNamespaceRef].AsString(); + set => this.Set((int)HelpFilterToNamespaceTupleFields.HelpNamespaceRef, value); + } + } +} \ No newline at end of file diff --git a/src/wixext/Tuples/HelpFilterTuple.cs b/src/wixext/Tuples/HelpFilterTuple.cs new file mode 100644 index 00000000..6592defa --- /dev/null +++ b/src/wixext/Tuples/HelpFilterTuple.cs @@ -0,0 +1,55 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.VisualStudio +{ + using WixToolset.Data; + using WixToolset.VisualStudio.Tuples; + + public static partial class VSTupleDefinitions + { + public static readonly IntermediateTupleDefinition HelpFilter = new IntermediateTupleDefinition( + VSTupleDefinitionType.HelpFilter.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(HelpFilterTupleFields.Description), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(HelpFilterTupleFields.QueryString), IntermediateFieldType.String), + }, + typeof(HelpFilterTuple)); + } +} + +namespace WixToolset.VisualStudio.Tuples +{ + using WixToolset.Data; + + public enum HelpFilterTupleFields + { + Description, + QueryString, + } + + public class HelpFilterTuple : IntermediateTuple + { + public HelpFilterTuple() : base(VSTupleDefinitions.HelpFilter, null, null) + { + } + + public HelpFilterTuple(SourceLineNumber sourceLineNumber, Identifier id = null) : base(VSTupleDefinitions.HelpFilter, sourceLineNumber, id) + { + } + + public IntermediateField this[HelpFilterTupleFields index] => this.Fields[(int)index]; + + public string Description + { + get => this.Fields[(int)HelpFilterTupleFields.Description].AsString(); + set => this.Set((int)HelpFilterTupleFields.Description, value); + } + + public string QueryString + { + get => this.Fields[(int)HelpFilterTupleFields.QueryString].AsString(); + set => this.Set((int)HelpFilterTupleFields.QueryString, value); + } + } +} \ No newline at end of file diff --git a/src/wixext/Tuples/HelpNamespaceTuple.cs b/src/wixext/Tuples/HelpNamespaceTuple.cs new file mode 100644 index 00000000..69b471fb --- /dev/null +++ b/src/wixext/Tuples/HelpNamespaceTuple.cs @@ -0,0 +1,63 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.VisualStudio +{ + using WixToolset.Data; + using WixToolset.VisualStudio.Tuples; + + public static partial class VSTupleDefinitions + { + public static readonly IntermediateTupleDefinition HelpNamespace = new IntermediateTupleDefinition( + VSTupleDefinitionType.HelpNamespace.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(HelpNamespaceTupleFields.NamespaceName), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(HelpNamespaceTupleFields.CollectionFileRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(HelpNamespaceTupleFields.Description), IntermediateFieldType.String), + }, + typeof(HelpNamespaceTuple)); + } +} + +namespace WixToolset.VisualStudio.Tuples +{ + using WixToolset.Data; + + public enum HelpNamespaceTupleFields + { + NamespaceName, + CollectionFileRef, + Description, + } + + public class HelpNamespaceTuple : IntermediateTuple + { + public HelpNamespaceTuple() : base(VSTupleDefinitions.HelpNamespace, null, null) + { + } + + public HelpNamespaceTuple(SourceLineNumber sourceLineNumber, Identifier id = null) : base(VSTupleDefinitions.HelpNamespace, sourceLineNumber, id) + { + } + + public IntermediateField this[HelpNamespaceTupleFields index] => this.Fields[(int)index]; + + public string NamespaceName + { + get => this.Fields[(int)HelpNamespaceTupleFields.NamespaceName].AsString(); + set => this.Set((int)HelpNamespaceTupleFields.NamespaceName, value); + } + + public string CollectionFileRef + { + get => this.Fields[(int)HelpNamespaceTupleFields.CollectionFileRef].AsString(); + set => this.Set((int)HelpNamespaceTupleFields.CollectionFileRef, value); + } + + public string Description + { + get => this.Fields[(int)HelpNamespaceTupleFields.Description].AsString(); + set => this.Set((int)HelpNamespaceTupleFields.Description, value); + } + } +} \ No newline at end of file diff --git a/src/wixext/Tuples/HelpPluginTuple.cs b/src/wixext/Tuples/HelpPluginTuple.cs new file mode 100644 index 00000000..5f146199 --- /dev/null +++ b/src/wixext/Tuples/HelpPluginTuple.cs @@ -0,0 +1,79 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.VisualStudio +{ + using WixToolset.Data; + using WixToolset.VisualStudio.Tuples; + + public static partial class VSTupleDefinitions + { + public static readonly IntermediateTupleDefinition HelpPlugin = new IntermediateTupleDefinition( + VSTupleDefinitionType.HelpPlugin.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(HelpPluginTupleFields.HelpNamespaceRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(HelpPluginTupleFields.ParentHelpNamespaceRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(HelpPluginTupleFields.HxTFileRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(HelpPluginTupleFields.HxAFileRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(HelpPluginTupleFields.ParentHxTFileRef), IntermediateFieldType.String), + }, + typeof(HelpPluginTuple)); + } +} + +namespace WixToolset.VisualStudio.Tuples +{ + using WixToolset.Data; + + public enum HelpPluginTupleFields + { + HelpNamespaceRef, + ParentHelpNamespaceRef, + HxTFileRef, + HxAFileRef, + ParentHxTFileRef, + } + + public class HelpPluginTuple : IntermediateTuple + { + public HelpPluginTuple() : base(VSTupleDefinitions.HelpPlugin, null, null) + { + } + + public HelpPluginTuple(SourceLineNumber sourceLineNumber, Identifier id = null) : base(VSTupleDefinitions.HelpPlugin, sourceLineNumber, id) + { + } + + public IntermediateField this[HelpPluginTupleFields index] => this.Fields[(int)index]; + + public string HelpNamespaceRef + { + get => this.Fields[(int)HelpPluginTupleFields.HelpNamespaceRef].AsString(); + set => this.Set((int)HelpPluginTupleFields.HelpNamespaceRef, value); + } + + public string ParentHelpNamespaceRef + { + get => this.Fields[(int)HelpPluginTupleFields.ParentHelpNamespaceRef].AsString(); + set => this.Set((int)HelpPluginTupleFields.ParentHelpNamespaceRef, value); + } + + public string HxTFileRef + { + get => this.Fields[(int)HelpPluginTupleFields.HxTFileRef].AsString(); + set => this.Set((int)HelpPluginTupleFields.HxTFileRef, value); + } + + public string HxAFileRef + { + get => this.Fields[(int)HelpPluginTupleFields.HxAFileRef].AsString(); + set => this.Set((int)HelpPluginTupleFields.HxAFileRef, value); + } + + public string ParentHxTFileRef + { + get => this.Fields[(int)HelpPluginTupleFields.ParentHxTFileRef].AsString(); + set => this.Set((int)HelpPluginTupleFields.ParentHxTFileRef, value); + } + } +} \ No newline at end of file diff --git a/src/wixext/Tuples/VSTupleDefinitions.cs b/src/wixext/Tuples/VSTupleDefinitions.cs new file mode 100644 index 00000000..fadcf808 --- /dev/null +++ b/src/wixext/Tuples/VSTupleDefinitions.cs @@ -0,0 +1,59 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +namespace WixToolset.VisualStudio +{ + using System; + using WixToolset.Data; + + public enum VSTupleDefinitionType + { + HelpFile, + HelpFileToNamespace, + HelpFilter, + HelpFilterToNamespace, + HelpNamespace, + HelpPlugin, + } + + public static partial class VSTupleDefinitions + { + public static readonly Version Version = new Version("4.0.0"); + + public static IntermediateTupleDefinition ByName(string name) + { + if (!Enum.TryParse(name, out VSTupleDefinitionType type)) + { + return null; + } + + return ByType(type); + } + + public static IntermediateTupleDefinition ByType(VSTupleDefinitionType type) + { + switch (type) + { + case VSTupleDefinitionType.HelpFile: + return VSTupleDefinitions.HelpFile; + + case VSTupleDefinitionType.HelpFileToNamespace: + return VSTupleDefinitions.HelpFileToNamespace; + + case VSTupleDefinitionType.HelpFilter: + return VSTupleDefinitions.HelpFilter; + + case VSTupleDefinitionType.HelpFilterToNamespace: + return VSTupleDefinitions.HelpFilterToNamespace; + + case VSTupleDefinitionType.HelpNamespace: + return VSTupleDefinitions.HelpNamespace; + + case VSTupleDefinitionType.HelpPlugin: + return VSTupleDefinitions.HelpPlugin; + + default: + throw new ArgumentOutOfRangeException(nameof(type)); + } + } + } +} diff --git a/src/wixext/VSCompiler.cs b/src/wixext/VSCompiler.cs index ebf7fa59..b9390fea 100644 --- a/src/wixext/VSCompiler.cs +++ b/src/wixext/VSCompiler.cs @@ -4,10 +4,13 @@ namespace WixToolset.VisualStudio { using System; using System.Collections.Generic; + using System.Globalization; using System.Xml.Linq; using WixToolset.Data; + using WixToolset.Data.Tuples; using WixToolset.Data.WindowsInstaller; using WixToolset.Extensibility; + using WixToolset.VisualStudio.Tuples; /// /// The compiler for the WiX Toolset Visual Studio Extension. @@ -79,10 +82,10 @@ namespace WixToolset.VisualStudio private void ParseHelpCollectionRefElement(Intermediate intermediate, IntermediateSection section, XElement element) { - SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); Identifier id = null; - foreach (XAttribute attrib in element.Attributes()) + foreach (var attrib in element.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { @@ -90,7 +93,7 @@ namespace WixToolset.VisualStudio { case "Id": id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "HelpNamespace", id.Id); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, VSTupleDefinitions.HelpNamespace, id.Id); break; default: this.ParseHelper.UnexpectedAttribute(element, attrib); @@ -108,11 +111,10 @@ namespace WixToolset.VisualStudio this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Id")); } - foreach (XElement child in element.Elements()) + foreach (var child in element.Elements()) { if (this.Namespace == child.Name.Namespace) { - SourceLineNumber childSourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(child); switch (child.Name.LocalName) { case "HelpFileRef": @@ -132,13 +134,13 @@ namespace WixToolset.VisualStudio private void ParseHelpCollectionElement(Intermediate intermediate, IntermediateSection section, XElement element, string fileId) { - SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); Identifier id = null; string description = null; string name = null; - YesNoType suppressCAs = YesNoType.No; + var suppressCAs = YesNoType.No; - foreach (XAttribute attrib in element.Attributes()) + foreach (var attrib in element.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { @@ -169,7 +171,7 @@ namespace WixToolset.VisualStudio if (null == id) { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Id")); + id = this.ParseHelper.CreateIdentifier("vshc", fileId, description, name); } if (null == description) @@ -182,7 +184,7 @@ namespace WixToolset.VisualStudio this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name")); } - foreach (XElement child in element.Elements()) + foreach (var child in element.Elements()) { if (this.Namespace == child.Name.Namespace) { @@ -210,31 +212,33 @@ namespace WixToolset.VisualStudio if (!this.Messaging.EncounteredError) { - var row = this.ParseHelper.CreateRow(section, sourceLineNumbers, "HelpNamespace", id); - row.Set(1, name); - row.Set(2, fileId); - row.Set(3, description); + section.AddTuple(new HelpNamespaceTuple(sourceLineNumbers, id) + { + NamespaceName = name, + CollectionFileRef = fileId, + Description = description, + }); if (YesNoType.No == suppressCAs) { - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "CA_RegisterMicrosoftHelp.3643236F_FC70_11D3_A536_0090278A1BB8"); + this.AddReferenceToRegisterMicrosoftHelp(section, sourceLineNumbers); } } } private void ParseHelpFileElement(Intermediate intermediate, IntermediateSection section, XElement element, string fileId) { - SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); Identifier id = null; string name = null; - int language = CompilerConstants.IntegerNotSet; + var language = CompilerConstants.IntegerNotSet; string hxi = null; string hxq = null; string hxr = null; string samples = null; - YesNoType suppressCAs = YesNoType.No; + var suppressCAs = YesNoType.No; - foreach (XAttribute attrib in element.Attributes()) + foreach (var attrib in element.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { @@ -245,11 +249,11 @@ namespace WixToolset.VisualStudio break; case "AttributeIndex": hxr = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "File", hxr); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.File, hxr); break; case "Index": hxi = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "File", hxi); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.File, hxi); break; case "Language": language = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue); @@ -259,11 +263,11 @@ namespace WixToolset.VisualStudio break; case "SampleLocation": samples = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "File", samples); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.File, samples); break; case "Search": hxq = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "File", hxq); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.File, hxq); break; case "SuppressCustomActions": suppressCAs = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib); @@ -281,7 +285,7 @@ namespace WixToolset.VisualStudio if (null == id) { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Id")); + id = this.ParseHelper.CreateIdentifier("vshf", fileId, name, language.ToString(CultureInfo.InvariantCulture.NumberFormat)); } if (null == name) @@ -299,28 +303,30 @@ namespace WixToolset.VisualStudio if (!this.Messaging.EncounteredError) { - var row = this.ParseHelper.CreateRow(section, sourceLineNumbers, "HelpFile", id); - row.Set(1, name); - row.Set(2, language); - row.Set(3, fileId); - row.Set(4, hxi); - row.Set(5, hxq); - row.Set(6, hxr); - row.Set(7, samples); + section.AddTuple(new HelpFileTuple(sourceLineNumbers, id) + { + HelpFileName = name, + LangID = language, + HxSFileRef = fileId, + HxIFileRef = hxi, + HxQFileRef = hxq, + HxRFileRef = hxr, + SamplesFileRef = samples, + }); if (YesNoType.No == suppressCAs) { - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "CA_RegisterMicrosoftHelp.3643236F_FC70_11D3_A536_0090278A1BB8"); + this.AddReferenceToRegisterMicrosoftHelp(section, sourceLineNumbers); } } } private void ParseHelpFileRefElement(Intermediate intermediate, IntermediateSection section, XElement element, Identifier collectionId) { - SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); Identifier id = null; - foreach (XAttribute attrib in element.Attributes()) + foreach (var attrib in element.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { @@ -328,7 +334,7 @@ namespace WixToolset.VisualStudio { case "Id": id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "HelpFile", id.Id); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, VSTupleDefinitions.HelpFile, id.Id); break; default: this.ParseHelper.UnexpectedAttribute(element, attrib); @@ -350,20 +356,23 @@ namespace WixToolset.VisualStudio if (!this.Messaging.EncounteredError) { - var row = this.ParseHelper.CreateRow(section, sourceLineNumbers, "HelpFileToNamespace", id); - row.Set(1, collectionId.Id); + section.AddTuple(new HelpFileToNamespaceTuple(sourceLineNumbers, id) + { + HelpFileRef = id.Id, + HelpNamespaceRef = collectionId.Id, + }); } } private void ParseHelpFilterElement(Intermediate intermediate, IntermediateSection section, XElement element) { - SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); Identifier id = null; string filterDefinition = null; string name = null; - YesNoType suppressCAs = YesNoType.No; + var suppressCAs = YesNoType.No; - foreach (XAttribute attrib in element.Attributes()) + foreach (var attrib in element.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { @@ -394,7 +403,7 @@ namespace WixToolset.VisualStudio if (null == id) { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Id")); + id = this.ParseHelper.CreateIdentifier("hfl", name, filterDefinition); } if (null == name) @@ -406,23 +415,25 @@ namespace WixToolset.VisualStudio if (!this.Messaging.EncounteredError) { - var row = this.ParseHelper.CreateRow(section, sourceLineNumbers, "HelpFilter", id); - row.Set(1, name); - row.Set(2, filterDefinition); + section.AddTuple(new HelpFilterTuple(sourceLineNumbers, id) + { + Description = name, + QueryString = filterDefinition, + }); if (YesNoType.No == suppressCAs) { - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "CA_RegisterMicrosoftHelp.3643236F_FC70_11D3_A536_0090278A1BB8"); + this.AddReferenceToRegisterMicrosoftHelp(section, sourceLineNumbers); } } } private void ParseHelpFilterRefElement(Intermediate intermediate, IntermediateSection section, XElement element, Identifier collectionId) { - SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); Identifier id = null; - foreach (XAttribute attrib in element.Attributes()) + foreach (var attrib in element.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { @@ -430,7 +441,7 @@ namespace WixToolset.VisualStudio { case "Id": id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "HelpFilter", id.Id); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, VSTupleDefinitions.HelpFilter, id.Id); break; default: this.ParseHelper.UnexpectedAttribute(element, attrib); @@ -452,24 +463,25 @@ namespace WixToolset.VisualStudio if (!this.Messaging.EncounteredError) { - var row = this.ParseHelper.CreateRow(section, sourceLineNumbers, "HelpFilterToNamespace", id); - row.Set(1, collectionId.Id); + section.AddTuple(new HelpFilterToNamespaceTuple(sourceLineNumbers, id) + { + HelpFilterRef = id.Id, + HelpNamespaceRef = collectionId.Id, + }); } } private void ParsePlugCollectionIntoElement(Intermediate intermediate, IntermediateSection section, XElement element, Identifier parentId) { - SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); string hxa = null; string hxt = null; string hxtParent = null; string namespaceParent = null; string feature = null; - YesNoType suppressExternalNamespaces = YesNoType.No; - bool pluginVS05 = false; - bool pluginVS08 = false; + var suppressExternalNamespaces = YesNoType.No; - foreach (XAttribute attrib in element.Attributes()) + foreach (var attrib in element.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { @@ -504,8 +516,8 @@ namespace WixToolset.VisualStudio } } - pluginVS05 = namespaceParent.Equals("MS_VSIPCC_v80", StringComparison.Ordinal); - pluginVS08 = namespaceParent.Equals("MS.VSIPCC.v90", StringComparison.Ordinal); + var pluginVS05 = namespaceParent.Equals("MS_VSIPCC_v80", StringComparison.Ordinal); + var pluginVS08 = namespaceParent.Equals("MS.VSIPCC.v90", StringComparison.Ordinal); if (null == namespaceParent) { @@ -521,11 +533,14 @@ namespace WixToolset.VisualStudio if (!this.Messaging.EncounteredError) { - var row = this.ParseHelper.CreateRow(section, sourceLineNumbers, "HelpPlugin", parentId); - row.Set(1, namespaceParent); - row.Set(2, hxt); - row.Set(3, hxa); - row.Set(4, hxtParent); + section.AddTuple(new HelpPluginTuple(sourceLineNumbers, parentId) + { + HelpNamespaceRef = parentId.Id, + ParentHelpNamespaceRef = namespaceParent, + HxTFileRef = hxt, + HxAFileRef = hxa, + ParentHxTFileRef = hxtParent, + }); if (pluginVS05) { @@ -535,7 +550,7 @@ namespace WixToolset.VisualStudio this.ParseHelper.CreateComplexReference(section, sourceLineNumbers, ComplexReferenceParentType.Feature, feature, String.Empty, ComplexReferenceChildType.ComponentGroup, "Help2_VS2005_Namespace_Components", false); // Reference CustomAction since nothing will happen without it - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "CA_HxMerge_VSIPCC_VSCC"); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.CustomAction, "CA_HxMerge_VSIPCC_VSCC"); } } else if (pluginVS08) @@ -546,28 +561,28 @@ namespace WixToolset.VisualStudio this.ParseHelper.CreateComplexReference(section, sourceLineNumbers, ComplexReferenceParentType.Feature, feature, String.Empty, ComplexReferenceChildType.ComponentGroup, "Help2_VS2008_Namespace_Components", false); // Reference CustomAction since nothing will happen without it - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "CA_ScheduleExtHelpPlugin_VSCC_VSIPCC"); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.CustomAction, "CA_ScheduleExtHelpPlugin_VSCC_VSIPCC"); } } else { // Reference the parent namespace to enforce the foreign key relationship - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "HelpNamespace", namespaceParent); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, VSTupleDefinitions.HelpNamespace, namespaceParent); } } } private void ParseVsixPackageElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId, string fileId) { - SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); - string propertyId = "VS_VSIX_INSTALLER_PATH"; + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + var propertyId = "VS_VSIX_INSTALLER_PATH"; string packageId = null; - YesNoType permanent = YesNoType.NotSet; + var permanent = YesNoType.NotSet; string target = null; string targetVersion = null; - YesNoType vital = YesNoType.NotSet; + var vital = YesNoType.NotSet; - foreach (XAttribute attrib in element.Attributes()) + foreach (var attrib in element.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { @@ -664,98 +679,131 @@ namespace WixToolset.VisualStudio if (!this.Messaging.EncounteredError) { // Ensure there is a reference to the AppSearch Property that will find the VsixInstaller.exe. - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "Property", propertyId); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.Property, propertyId); // Ensure there is a reference to the package file (even if we are a child under it). - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "File", fileId); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.File, fileId); - string cmdlinePrefix = "/q "; + var cmdlinePrefix = "/q "; if (!String.IsNullOrEmpty(target)) { cmdlinePrefix = String.Format("{0} /skuName:{1} /skuVersion:{2}", cmdlinePrefix, target, targetVersion); } - string installAfter = "WriteRegistryValues"; // by default, come after the registry key registration. - int installExtraBits = VSCompiler.MsidbCustomActionTypeInScript; + var installAfter = "WriteRegistryValues"; // by default, come after the registry key registration. + + var installNamePerUser = this.ParseHelper.CreateIdentifier("viu", componentId, fileId, "per-user", target, targetVersion); + var installNamePerMachine = this.ParseHelper.CreateIdentifier("vim", componentId, fileId, "per-machine", target, targetVersion); + var installCmdLinePerUser = String.Format("{0} \"[#{1}]\"", cmdlinePrefix, fileId); + var installCmdLinePerMachine = String.Concat(installCmdLinePerUser, " /admin"); + var installConditionPerUser = String.Format("NOT ALLUSERS AND ${0}=3", componentId); // only execute if the Component being installed. + var installConditionPerMachine = String.Format("ALLUSERS AND ${0}=3", componentId); // only execute if the Component being installed. + var installPerUserCA = new CustomActionTuple(sourceLineNumbers, installNamePerUser) + { + ExecutionType = CustomActionExecutionType.Deferred, + Impersonate = true, + }; + var installPerMachineCA = new CustomActionTuple(sourceLineNumbers, installNamePerMachine) + { + ExecutionType = CustomActionExecutionType.Deferred, + Impersonate = false, + }; // If the package is not vital, mark the install action as continue. if (vital == YesNoType.No) { - installExtraBits |= VSCompiler.MsidbCustomActionTypeContinue; + installPerUserCA.IgnoreResult = true; + installPerMachineCA.IgnoreResult = true; } else // the package is vital so ensure there is a rollback action scheduled. { - Identifier rollbackNamePerUser = this.ParseHelper.CreateIdentifier("vru", componentId, fileId, "per-user", target ?? String.Empty, targetVersion ?? String.Empty); - Identifier rollbackNamePerMachine = this.ParseHelper.CreateIdentifier("vrm", componentId, fileId, "per-machine", target ?? String.Empty, targetVersion ?? String.Empty); - string rollbackCmdLinePerUser = String.Concat(cmdlinePrefix, " /u:\"", packageId, "\""); - string rollbackCmdLinePerMachine = String.Concat(rollbackCmdLinePerUser, " /admin"); - int rollbackExtraBitsPerUser = VSCompiler.MsidbCustomActionTypeContinue | VSCompiler.MsidbCustomActionTypeRollback | VSCompiler.MsidbCustomActionTypeInScript; - int rollbackExtraBitsPerMachine = rollbackExtraBitsPerUser | VSCompiler.MsidbCustomActionTypeNoImpersonate; - string rollbackConditionPerUser = String.Format("NOT ALLUSERS AND NOT Installed AND ${0}=2 AND ?{0}>2", componentId); // NOT Installed && Component being installed but not installed already. - string rollbackConditionPerMachine = String.Format("ALLUSERS AND NOT Installed AND ${0}=2 AND ?{0}>2", componentId); // NOT Installed && Component being installed but not installed already. + var rollbackNamePerUser = this.ParseHelper.CreateIdentifier("vru", componentId, fileId, "per-user", target, targetVersion); + var rollbackNamePerMachine = this.ParseHelper.CreateIdentifier("vrm", componentId, fileId, "per-machine", target, targetVersion); + var rollbackCmdLinePerUser = String.Concat(cmdlinePrefix, " /u:\"", packageId, "\""); + var rollbackCmdLinePerMachine = String.Concat(rollbackCmdLinePerUser, " /admin"); + var rollbackConditionPerUser = String.Format("NOT ALLUSERS AND NOT Installed AND ${0}=2 AND ?{0}>2", componentId); // NOT Installed && Component being installed but not installed already. + var rollbackConditionPerMachine = String.Format("ALLUSERS AND NOT Installed AND ${0}=2 AND ?{0}>2", componentId); // NOT Installed && Component being installed but not installed already. + var rollbackPerUserCA = new CustomActionTuple(sourceLineNumbers, rollbackNamePerUser) + { + ExecutionType = CustomActionExecutionType.Rollback, + IgnoreResult = true, + Impersonate = true, + }; + var rollbackPerMachineCA = new CustomActionTuple(sourceLineNumbers, rollbackNamePerMachine) + { + ExecutionType = CustomActionExecutionType.Rollback, + IgnoreResult = true, + Impersonate = false, + }; - this.SchedulePropertyExeAction(section, sourceLineNumbers, rollbackNamePerUser, propertyId, rollbackCmdLinePerUser, rollbackExtraBitsPerUser, rollbackConditionPerUser, null, installAfter); - this.SchedulePropertyExeAction(section, sourceLineNumbers, rollbackNamePerMachine, propertyId, rollbackCmdLinePerMachine, rollbackExtraBitsPerMachine, rollbackConditionPerMachine, null, rollbackNamePerUser.Id); + this.SchedulePropertyExeAction(section, sourceLineNumbers, rollbackNamePerUser, propertyId, rollbackCmdLinePerUser, rollbackPerUserCA, rollbackConditionPerUser, null, installAfter); + this.SchedulePropertyExeAction(section, sourceLineNumbers, rollbackNamePerMachine, propertyId, rollbackCmdLinePerMachine, rollbackPerMachineCA, rollbackConditionPerMachine, null, rollbackNamePerUser.Id); installAfter = rollbackNamePerMachine.Id; } - Identifier installNamePerUser = this.ParseHelper.CreateIdentifier("viu", componentId, fileId, "per-user", target ?? String.Empty, targetVersion ?? String.Empty); - Identifier installNamePerMachine = this.ParseHelper.CreateIdentifier("vim", componentId, fileId, "per-machine", target ?? String.Empty, targetVersion ?? String.Empty); - string installCmdLinePerUser = String.Format("{0} \"[#{1}]\"", cmdlinePrefix, fileId); - string installCmdLinePerMachine = String.Concat(installCmdLinePerUser, " /admin"); - string installConditionPerUser = String.Format("NOT ALLUSERS AND ${0}=3", componentId); // only execute if the Component being installed. - string installConditionPerMachine = String.Format("ALLUSERS AND ${0}=3", componentId); // only execute if the Component being installed. - - this.SchedulePropertyExeAction(section, sourceLineNumbers, installNamePerUser, propertyId, installCmdLinePerUser, installExtraBits, installConditionPerUser, null, installAfter); - this.SchedulePropertyExeAction(section, sourceLineNumbers, installNamePerMachine, propertyId, installCmdLinePerMachine, installExtraBits | VSCompiler.MsidbCustomActionTypeNoImpersonate, installConditionPerMachine, null, installNamePerUser.Id); + this.SchedulePropertyExeAction(section, sourceLineNumbers, installNamePerUser, propertyId, installCmdLinePerUser, installPerUserCA, installConditionPerUser, null, installAfter); + this.SchedulePropertyExeAction(section, sourceLineNumbers, installNamePerMachine, propertyId, installCmdLinePerMachine, installPerMachineCA, installConditionPerMachine, null, installNamePerUser.Id); // If not permanent, schedule the uninstall custom action. if (permanent != YesNoType.Yes) { - Identifier uninstallNamePerUser = this.ParseHelper.CreateIdentifier("vuu", componentId, fileId, "per-user", target ?? String.Empty, targetVersion ?? String.Empty); - Identifier uninstallNamePerMachine = this.ParseHelper.CreateIdentifier("vum", componentId, fileId, "per-machine", target ?? String.Empty, targetVersion ?? String.Empty); - string uninstallCmdLinePerUser = String.Concat(cmdlinePrefix, " /u:\"", packageId, "\""); - string uninstallCmdLinePerMachine = String.Concat(uninstallCmdLinePerUser, " /admin"); - int uninstallExtraBitsPerUser = VSCompiler.MsidbCustomActionTypeContinue | VSCompiler.MsidbCustomActionTypeInScript; - int uninstallExtraBitsPerMachine = uninstallExtraBitsPerUser | VSCompiler.MsidbCustomActionTypeNoImpersonate; - string uninstallConditionPerUser = String.Format("NOT ALLUSERS AND ${0}=2 AND ?{0}>2", componentId); // Only execute if component is being uninstalled. - string uninstallConditionPerMachine = String.Format("ALLUSERS AND ${0}=2 AND ?{0}>2", componentId); // Only execute if component is being uninstalled. + var uninstallNamePerUser = this.ParseHelper.CreateIdentifier("vuu", componentId, fileId, "per-user", target ?? String.Empty, targetVersion ?? String.Empty); + var uninstallNamePerMachine = this.ParseHelper.CreateIdentifier("vum", componentId, fileId, "per-machine", target ?? String.Empty, targetVersion ?? String.Empty); + var uninstallCmdLinePerUser = String.Concat(cmdlinePrefix, " /u:\"", packageId, "\""); + var uninstallCmdLinePerMachine = String.Concat(uninstallCmdLinePerUser, " /admin"); + var uninstallConditionPerUser = String.Format("NOT ALLUSERS AND ${0}=2 AND ?{0}>2", componentId); // Only execute if component is being uninstalled. + var uninstallConditionPerMachine = String.Format("ALLUSERS AND ${0}=2 AND ?{0}>2", componentId); // Only execute if component is being uninstalled. + var uninstallPerUserCA = new CustomActionTuple(sourceLineNumbers, uninstallNamePerUser) + { + ExecutionType = CustomActionExecutionType.Deferred, + IgnoreResult = true, + Impersonate = true, + }; + var uninstallPerMachineCA = new CustomActionTuple(sourceLineNumbers, uninstallNamePerMachine) + { + ExecutionType = CustomActionExecutionType.Deferred, + IgnoreResult = true, + Impersonate = false, + }; - this.SchedulePropertyExeAction(section, sourceLineNumbers, uninstallNamePerUser, propertyId, uninstallCmdLinePerUser, uninstallExtraBitsPerUser, uninstallConditionPerUser, "InstallFinalize", null); - this.SchedulePropertyExeAction(section, sourceLineNumbers, uninstallNamePerMachine, propertyId, uninstallCmdLinePerMachine, uninstallExtraBitsPerMachine, uninstallConditionPerMachine, "InstallFinalize", null); + this.SchedulePropertyExeAction(section, sourceLineNumbers, uninstallNamePerUser, propertyId, uninstallCmdLinePerUser, uninstallPerUserCA, uninstallConditionPerUser, "InstallFinalize", null); + this.SchedulePropertyExeAction(section, sourceLineNumbers, uninstallNamePerMachine, propertyId, uninstallCmdLinePerMachine, uninstallPerMachineCA, uninstallConditionPerMachine, "InstallFinalize", null); } } } - private void SchedulePropertyExeAction(IntermediateSection section, SourceLineNumber sourceLineNumbers, Identifier name, string source, string cmdline, int extraBits, string condition, string beforeAction, string afterAction) + private void SchedulePropertyExeAction(IntermediateSection section, SourceLineNumber sourceLineNumbers, Identifier name, string source, string cmdline, CustomActionTuple caTemplate, string condition, string beforeAction, string afterAction) { - const string sequence = "InstallExecuteSequence"; - - var actionRow = this.ParseHelper.CreateRow(section, sourceLineNumbers, "CustomAction", name); - actionRow.Set(1, VSCompiler.MsidbCustomActionTypeProperty | VSCompiler.MsidbCustomActionTypeExe | extraBits); - actionRow.Set(2, source); - actionRow.Set(3, cmdline); - - var sequenceRow = this.ParseHelper.CreateRow(section, sourceLineNumbers, "WixAction", new Identifier(name.Access, sequence, name.Id)); - sequenceRow.Set(0, sequence); - sequenceRow.Set(1, name.Id); - sequenceRow.Set(2, condition); - // no explicit sequence - sequenceRow.Set(4, beforeAction); - sequenceRow.Set(5, afterAction); - sequenceRow.Set(6, 0); // not overridable + const SequenceTable sequence = SequenceTable.InstallExecuteSequence; + + caTemplate.SourceType = CustomActionSourceType.Property; + caTemplate.Source = source; + caTemplate.TargetType = CustomActionTargetType.Exe; + caTemplate.Target = cmdline; + section.AddTuple(caTemplate); + + section.AddTuple(new WixActionTuple(sourceLineNumbers, new Identifier(name.Access, sequence, name.Id)) + { + SequenceTable = SequenceTable.InstallExecuteSequence, + Action = name.Id, + Condition = condition, + // no explicit sequence + Before = beforeAction, + After = afterAction, + Overridable = false, + }); if (null != beforeAction) { if (WindowsInstallerStandard.IsStandardAction(beforeAction)) { - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "WixAction", sequence, beforeAction); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.WixAction, sequence.ToString(), beforeAction); } else { - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", beforeAction); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.CustomAction, beforeAction); } } @@ -763,13 +811,18 @@ namespace WixToolset.VisualStudio { if (WindowsInstallerStandard.IsStandardAction(afterAction)) { - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "WixAction", sequence, afterAction); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.WixAction, sequence.ToString(), afterAction); } else { - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", afterAction); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.CustomAction, afterAction); } } } + + private void AddReferenceToRegisterMicrosoftHelp(IntermediateSection section, SourceLineNumber sourceLineNumbers) + { + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.CustomAction, "CA_RegisterMicrosoftHelp.3643236F_FC70_11D3_A536_0090278A1BB8"); + } } } diff --git a/src/wixext/VSExtensionData.cs b/src/wixext/VSExtensionData.cs index bc846af0..3d28b625 100644 --- a/src/wixext/VSExtensionData.cs +++ b/src/wixext/VSExtensionData.cs @@ -7,6 +7,18 @@ namespace WixToolset.VisualStudio public sealed class VSExtensionData : BaseExtensionData { + /// + /// Gets the default culture. + /// + /// The default culture. + public override string DefaultCulture => "en-US"; + + public override bool TryGetTupleDefinitionByName(string name, out IntermediateTupleDefinition tupleDefinition) + { + tupleDefinition = VSTupleDefinitions.ByName(name); + return tupleDefinition != null; + } + public override Intermediate GetLibrary(ITupleDefinitionCreator tupleDefinitions) { return Intermediate.Load(typeof(VSExtensionData).Assembly, "WixToolset.VisualStudio.vs.wixlib", tupleDefinitions); diff --git a/src/wixext/VSTableDefinitions.cs b/src/wixext/VSTableDefinitions.cs index 64634004..f630f138 100644 --- a/src/wixext/VSTableDefinitions.cs +++ b/src/wixext/VSTableDefinitions.cs @@ -6,67 +6,92 @@ namespace WixToolset.VisualStudio public static class VSTableDefinitions { - public static readonly TableDefinition[] Tables = new[] { - new TableDefinition( - "HelpFile", - new[] - { - new ColumnDefinition("HelpFileKey", ColumnType.String, 72, true, false, ColumnCategory.Identifier, description: "Primary Key for HelpFile Table (required)."), - new ColumnDefinition("HelpFileName", ColumnType.String, 0, false, false, ColumnCategory.Text, description: "Internal Microsoft Help ID for this HelpFile (required)."), - new ColumnDefinition("LangID", ColumnType.Number, 2, false, true, ColumnCategory.Language, description: "Language ID for content file (optional)."), - new ColumnDefinition("File_HxS", ColumnType.String, 72, false, true, ColumnCategory.Identifier, keyTable:"File", keyColumn: 1, description: "Key for HxS (Title) file (required)."), - new ColumnDefinition("File_HxI", ColumnType.String, 72, false, true, ColumnCategory.Identifier, keyTable:"File", keyColumn: 1, description: "Key for HxI (Index) file (required)."), - new ColumnDefinition("File_HxQ", ColumnType.String, 72, false, true, ColumnCategory.Identifier, keyTable:"File", keyColumn: 1, description: "Key for HxQ (Query) file (required)."), - new ColumnDefinition("File_HxR", ColumnType.String, 72, false, true, ColumnCategory.Identifier, keyTable:"File", keyColumn: 1, description: "Key for HxR (Attributes) file (required)."), - new ColumnDefinition("File_Samples", ColumnType.String, 72, false, true, ColumnCategory.Identifier, keyTable:"File", keyColumn: 1, description: "Key for a file that is in the 'root' of the samples directory for this HelpFile (optional)."), - } - ), - new TableDefinition( - "HelpFileToNamespace", - new[] - { - new ColumnDefinition("HelpFile_", ColumnType.String, 72, true, false, ColumnCategory.Identifier, keyTable: "HelpFile", keyColumn: 1, description: "Foreign key into HelpFile table (required)."), - new ColumnDefinition("HelpNamespace_", ColumnType.String, 72, true, false, ColumnCategory.Identifier, keyTable: "HelpNamespace", keyColumn: 1, description: "Foreign key into HelpNamespace table (required)."), - } - ), - new TableDefinition( - "HelpFilter", - new[] - { - new ColumnDefinition("FilterKey", ColumnType.String, 72, true, false, ColumnCategory.Identifier, description: "Primary Key for HelpFilter (required)."), - new ColumnDefinition("Description", ColumnType.Localized, 0, false, false, ColumnCategory.Text, description: "Friendly name for Filter (required)."), - new ColumnDefinition("QueryString", ColumnType.String, 0, false, true, ColumnCategory.Text, description: "Query String for Help Filter (optional)."), - } - ), - new TableDefinition( - "HelpFilterToNamespace", - new[] - { - new ColumnDefinition("HelpFilter_", ColumnType.String, 72, true, false, ColumnCategory.Identifier, keyTable: "HelpFilter", keyColumn: 1, description: "Foreign key into HelpFilter table (required)."), - new ColumnDefinition("HelpNamespace_", ColumnType.String, 72, true, false, ColumnCategory.Identifier, keyTable: "HelpNamespace", keyColumn: 1, description: "Foreign key into HelpNamespace table (required)."), - } - ), - new TableDefinition( - "HelpNamespace", - new[] - { - new ColumnDefinition("NamespaceKey", ColumnType.String, 72, true, false, ColumnCategory.Identifier, description: "Primary Key for HelpNamespace (required)."), - new ColumnDefinition("NamespaceName", ColumnType.String, 0, false, false, ColumnCategory.Text, description: "Internal Microsoft Help ID for this Namespace (required)."), - new ColumnDefinition("File_Collection", ColumnType.String, 72, false, false, ColumnCategory.Identifier, keyTable:"File", keyColumn: 1, description: "Key for HxC (Collection) file (required)."), - new ColumnDefinition("Description", ColumnType.Localized, 0, false, true, ColumnCategory.Text, description: "Friendly name for Namespace (optional)."), - } - ), - new TableDefinition( - "HelpPlugin", - new[] - { - new ColumnDefinition("HelpNamespace_", ColumnType.String, 72, true, false, ColumnCategory.Identifier, keyTable: "HelpNamespace", keyColumn: 1, description: "Foreign key into HelpNamespace table for the child namespace that will be plugged into the parent namespace (required)."), - new ColumnDefinition("HelpNamespace_Parent", ColumnType.String, 72, true, false, ColumnCategory.Identifier, keyTable: "HelpNamespace", keyColumn: 1, description: "Foreign key into HelpNamespace table for the parent namespace into which the child will be inserted (required)."), - new ColumnDefinition("File_HxT", ColumnType.String, 72, false, true, ColumnCategory.Identifier, keyTable:"File", keyColumn: 1, description: "Key for HxT file of child namespace (optional)."), - new ColumnDefinition("File_HxA", ColumnType.String, 72, false, true, ColumnCategory.Identifier, keyTable:"File", keyColumn: 1, description: "Key for HxA (Attributes) file of child namespace (optional)."), - new ColumnDefinition("File_ParentHxT", ColumnType.String, 72, false, true, ColumnCategory.Identifier, keyTable:"File", keyColumn: 1, description: "Key for HxT file of parent namespace that now includes the new child namespace (optional)."), - } - ), + public static readonly TableDefinition HelpFile = new TableDefinition( + "HelpFile", + new[] + { + new ColumnDefinition("HelpFileKey", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary Key for HelpFile Table (required).", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("HelpFileName", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Text, description: "Internal Microsoft Help ID for this HelpFile (required)."), + new ColumnDefinition("LangID", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Language, description: "Language ID for content file (optional)."), + new ColumnDefinition("File_HxS", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "File", keyColumn: 1, description: "Key for HxS (Title) file (required).", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("File_HxI", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "File", keyColumn: 1, description: "Key for HxI (Index) file (optional).", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("File_HxQ", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "File", keyColumn: 1, description: "Key for HxQ (Query) file (optional).", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("File_HxR", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "File", keyColumn: 1, description: "Key for HxR (Attributes) file (optional).", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("File_Samples", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "File", keyColumn: 1, description: "Key for a file that is in the 'root' of the samples directory for this HelpFile (optional).", modularizeType: ColumnModularizeType.Column), + }, + tupleDefinitionName: VSTupleDefinitions.HelpFile.Name, + tupleIdIsPrimaryKey: true + ); + + public static readonly TableDefinition HelpFileToNamespace = new TableDefinition( + "HelpFileToNamespace", + new[] + { + new ColumnDefinition("HelpFile_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "HelpFile", keyColumn: 1, description: "Foreign key into HelpFile table (required).", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("HelpNamespace_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "HelpNamespace", keyColumn: 1, description: "Foreign key into HelpNamespace table (required)."), + }, + tupleDefinitionName: VSTupleDefinitions.HelpFileToNamespace.Name, + tupleIdIsPrimaryKey: false + ); + + public static readonly TableDefinition HelpFilter = new TableDefinition( + "HelpFilter", + new[] + { + new ColumnDefinition("FilterKey", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary Key for HelpFilter (required).", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Description", ColumnType.Localized, 0, primaryKey: false, nullable: false, ColumnCategory.Text, description: "Friendly name for Filter (required)."), + new ColumnDefinition("QueryString", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Text, description: "Query String for Help Filter (optional)."), + }, + tupleDefinitionName: VSTupleDefinitions.HelpFilter.Name, + tupleIdIsPrimaryKey: true + ); + + public static readonly TableDefinition HelpFilterToNamespace = new TableDefinition( + "HelpFilterToNamespace", + new[] + { + new ColumnDefinition("HelpFilter_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "HelpFilter", keyColumn: 1, description: "Foreign key into HelpFilter table (required).", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("HelpNamespace_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "HelpNamespace", keyColumn: 1, description: "Foreign key into HelpNamespace table (required)."), + }, + tupleDefinitionName: VSTupleDefinitions.HelpFilterToNamespace.Name, + tupleIdIsPrimaryKey: false + ); + + public static readonly TableDefinition HelpNamespace = new TableDefinition( + "HelpNamespace", + new[] + { + new ColumnDefinition("NamespaceKey", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary Key for HelpNamespace (required)."), + new ColumnDefinition("NamespaceName", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Text, description: "Internal Microsoft Help ID for this Namespace (required)."), + new ColumnDefinition("File_Collection", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "File", keyColumn: 1, description: "Key for HxC (Collection) file (required).", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Description", ColumnType.Localized, 0, primaryKey: false, nullable: true, ColumnCategory.Text, description: "Friendly name for Namespace (optional)."), + }, + tupleDefinitionName: VSTupleDefinitions.HelpNamespace.Name, + tupleIdIsPrimaryKey: true + ); + + public static readonly TableDefinition HelpPlugin = new TableDefinition( + "HelpPlugin", + new[] + { + new ColumnDefinition("HelpNamespace_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "HelpNamespace", keyColumn: 1, description: "Foreign key into HelpNamespace table for the child namespace that will be plugged into the parent namespace (required)."), + new ColumnDefinition("HelpNamespace_Parent", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "HelpNamespace", keyColumn: 1, description: "Foreign key into HelpNamespace table for the parent namespace into which the child will be inserted (required)."), + new ColumnDefinition("File_HxT", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "File", keyColumn: 1, description: "Key for HxT file of child namespace (optional).", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("File_HxA", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "File", keyColumn: 1, description: "Key for HxA (Attributes) file of child namespace (optional).", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("File_ParentHxT", ColumnType.String, 72, primaryKey: false, nullable: true, ColumnCategory.Identifier, keyTable: "File", keyColumn: 1, description: "Key for HxT file of parent namespace that now includes the new child namespace (optional).", modularizeType: ColumnModularizeType.Column), + }, + tupleDefinitionName: VSTupleDefinitions.HelpPlugin.Name, + tupleIdIsPrimaryKey: false + ); + + public static readonly TableDefinition[] All = new[] + { + HelpFile, + HelpFileToNamespace, + HelpFilter, + HelpFilterToNamespace, + HelpNamespace, + HelpPlugin, }; } } diff --git a/src/wixext/VSWindowsInstallerBackendBinderExtension.cs b/src/wixext/VSWindowsInstallerBackendBinderExtension.cs index 7a9579ca..825c8ca7 100644 --- a/src/wixext/VSWindowsInstallerBackendBinderExtension.cs +++ b/src/wixext/VSWindowsInstallerBackendBinderExtension.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. namespace WixToolset.VisualStudio { @@ -8,6 +8,6 @@ namespace WixToolset.VisualStudio public class VSWindowsInstallerBackendBinderExtension : BaseWindowsInstallerBackendBinderExtension { - public override IEnumerable TableDefinitions => VSTableDefinitions.Tables; + public override IEnumerable TableDefinitions => VSTableDefinitions.All; } } -- cgit v1.2.3-55-g6feb