summaryrefslogtreecommitdiff
path: root/src/ext/VisualStudio/wixext
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext/VisualStudio/wixext')
-rw-r--r--src/ext/VisualStudio/wixext/Symbols/HelpFileSymbol.cs95
-rw-r--r--src/ext/VisualStudio/wixext/Symbols/HelpFileToNamespaceSymbol.cs55
-rw-r--r--src/ext/VisualStudio/wixext/Symbols/HelpFilterSymbol.cs55
-rw-r--r--src/ext/VisualStudio/wixext/Symbols/HelpFilterToNamespaceSymbol.cs55
-rw-r--r--src/ext/VisualStudio/wixext/Symbols/HelpNamespaceSymbol.cs63
-rw-r--r--src/ext/VisualStudio/wixext/Symbols/HelpPluginSymbol.cs79
-rw-r--r--src/ext/VisualStudio/wixext/Symbols/VSSymbolDefinitions.cs59
-rw-r--r--src/ext/VisualStudio/wixext/VSCompiler.cs828
-rw-r--r--src/ext/VisualStudio/wixext/VSDecompiler.cs298
-rw-r--r--src/ext/VisualStudio/wixext/VSExtensionData.cs27
-rw-r--r--src/ext/VisualStudio/wixext/VSExtensionFactory.cs18
-rw-r--r--src/ext/VisualStudio/wixext/VSTableDefinitions.cs97
-rw-r--r--src/ext/VisualStudio/wixext/VSWindowsInstallerBackendBinderExtension.cs13
-rw-r--r--src/ext/VisualStudio/wixext/WixToolset.VisualStudio.wixext.csproj30
-rw-r--r--src/ext/VisualStudio/wixext/WixToolset.VisualStudio.wixext.nuspec23
-rw-r--r--src/ext/VisualStudio/wixext/WixToolset.VisualStudio.wixext.targets8
-rw-r--r--src/ext/VisualStudio/wixext/WixToolset.VisualStudio.wixext.v3.ncrunchproject7
17 files changed, 1810 insertions, 0 deletions
diff --git a/src/ext/VisualStudio/wixext/Symbols/HelpFileSymbol.cs b/src/ext/VisualStudio/wixext/Symbols/HelpFileSymbol.cs
new file mode 100644
index 00000000..8078f4ab
--- /dev/null
+++ b/src/ext/VisualStudio/wixext/Symbols/HelpFileSymbol.cs
@@ -0,0 +1,95 @@
1// 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.
2
3namespace WixToolset.VisualStudio
4{
5 using WixToolset.Data;
6 using WixToolset.VisualStudio.Symbols;
7
8 public static partial class VSSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition HelpFile = new IntermediateSymbolDefinition(
11 VSSymbolDefinitionType.HelpFile.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(HelpFileSymbolFields.HelpFileName), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(HelpFileSymbolFields.LangID), IntermediateFieldType.Number),
16 new IntermediateFieldDefinition(nameof(HelpFileSymbolFields.HxSFileRef), IntermediateFieldType.String),
17 new IntermediateFieldDefinition(nameof(HelpFileSymbolFields.HxIFileRef), IntermediateFieldType.String),
18 new IntermediateFieldDefinition(nameof(HelpFileSymbolFields.HxQFileRef), IntermediateFieldType.String),
19 new IntermediateFieldDefinition(nameof(HelpFileSymbolFields.HxRFileRef), IntermediateFieldType.String),
20 new IntermediateFieldDefinition(nameof(HelpFileSymbolFields.SamplesFileRef), IntermediateFieldType.String),
21 },
22 typeof(HelpFileSymbol));
23 }
24}
25
26namespace WixToolset.VisualStudio.Symbols
27{
28 using WixToolset.Data;
29
30 public enum HelpFileSymbolFields
31 {
32 HelpFileName,
33 LangID,
34 HxSFileRef,
35 HxIFileRef,
36 HxQFileRef,
37 HxRFileRef,
38 SamplesFileRef,
39 }
40
41 public class HelpFileSymbol : IntermediateSymbol
42 {
43 public HelpFileSymbol() : base(VSSymbolDefinitions.HelpFile, null, null)
44 {
45 }
46
47 public HelpFileSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(VSSymbolDefinitions.HelpFile, sourceLineNumber, id)
48 {
49 }
50
51 public IntermediateField this[HelpFileSymbolFields index] => this.Fields[(int)index];
52
53 public string HelpFileName
54 {
55 get => this.Fields[(int)HelpFileSymbolFields.HelpFileName].AsString();
56 set => this.Set((int)HelpFileSymbolFields.HelpFileName, value);
57 }
58
59 public int? LangID
60 {
61 get => this.Fields[(int)HelpFileSymbolFields.LangID].AsNullableNumber();
62 set => this.Set((int)HelpFileSymbolFields.LangID, value);
63 }
64
65 public string HxSFileRef
66 {
67 get => this.Fields[(int)HelpFileSymbolFields.HxSFileRef].AsString();
68 set => this.Set((int)HelpFileSymbolFields.HxSFileRef, value);
69 }
70
71 public string HxIFileRef
72 {
73 get => this.Fields[(int)HelpFileSymbolFields.HxIFileRef].AsString();
74 set => this.Set((int)HelpFileSymbolFields.HxIFileRef, value);
75 }
76
77 public string HxQFileRef
78 {
79 get => this.Fields[(int)HelpFileSymbolFields.HxQFileRef].AsString();
80 set => this.Set((int)HelpFileSymbolFields.HxQFileRef, value);
81 }
82
83 public string HxRFileRef
84 {
85 get => this.Fields[(int)HelpFileSymbolFields.HxRFileRef].AsString();
86 set => this.Set((int)HelpFileSymbolFields.HxRFileRef, value);
87 }
88
89 public string SamplesFileRef
90 {
91 get => this.Fields[(int)HelpFileSymbolFields.SamplesFileRef].AsString();
92 set => this.Set((int)HelpFileSymbolFields.SamplesFileRef, value);
93 }
94 }
95} \ No newline at end of file
diff --git a/src/ext/VisualStudio/wixext/Symbols/HelpFileToNamespaceSymbol.cs b/src/ext/VisualStudio/wixext/Symbols/HelpFileToNamespaceSymbol.cs
new file mode 100644
index 00000000..f18d6701
--- /dev/null
+++ b/src/ext/VisualStudio/wixext/Symbols/HelpFileToNamespaceSymbol.cs
@@ -0,0 +1,55 @@
1// 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.
2
3namespace WixToolset.VisualStudio
4{
5 using WixToolset.Data;
6 using WixToolset.VisualStudio.Symbols;
7
8 public static partial class VSSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition HelpFileToNamespace = new IntermediateSymbolDefinition(
11 VSSymbolDefinitionType.HelpFileToNamespace.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(HelpFileToNamespaceSymbolFields.HelpFileRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(HelpFileToNamespaceSymbolFields.HelpNamespaceRef), IntermediateFieldType.String),
16 },
17 typeof(HelpFileToNamespaceSymbol));
18 }
19}
20
21namespace WixToolset.VisualStudio.Symbols
22{
23 using WixToolset.Data;
24
25 public enum HelpFileToNamespaceSymbolFields
26 {
27 HelpFileRef,
28 HelpNamespaceRef,
29 }
30
31 public class HelpFileToNamespaceSymbol : IntermediateSymbol
32 {
33 public HelpFileToNamespaceSymbol() : base(VSSymbolDefinitions.HelpFileToNamespace, null, null)
34 {
35 }
36
37 public HelpFileToNamespaceSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(VSSymbolDefinitions.HelpFileToNamespace, sourceLineNumber, id)
38 {
39 }
40
41 public IntermediateField this[HelpFileToNamespaceSymbolFields index] => this.Fields[(int)index];
42
43 public string HelpFileRef
44 {
45 get => this.Fields[(int)HelpFileToNamespaceSymbolFields.HelpFileRef].AsString();
46 set => this.Set((int)HelpFileToNamespaceSymbolFields.HelpFileRef, value);
47 }
48
49 public string HelpNamespaceRef
50 {
51 get => this.Fields[(int)HelpFileToNamespaceSymbolFields.HelpNamespaceRef].AsString();
52 set => this.Set((int)HelpFileToNamespaceSymbolFields.HelpNamespaceRef, value);
53 }
54 }
55} \ No newline at end of file
diff --git a/src/ext/VisualStudio/wixext/Symbols/HelpFilterSymbol.cs b/src/ext/VisualStudio/wixext/Symbols/HelpFilterSymbol.cs
new file mode 100644
index 00000000..9deb47d0
--- /dev/null
+++ b/src/ext/VisualStudio/wixext/Symbols/HelpFilterSymbol.cs
@@ -0,0 +1,55 @@
1// 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.
2
3namespace WixToolset.VisualStudio
4{
5 using WixToolset.Data;
6 using WixToolset.VisualStudio.Symbols;
7
8 public static partial class VSSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition HelpFilter = new IntermediateSymbolDefinition(
11 VSSymbolDefinitionType.HelpFilter.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(HelpFilterSymbolFields.Description), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(HelpFilterSymbolFields.QueryString), IntermediateFieldType.String),
16 },
17 typeof(HelpFilterSymbol));
18 }
19}
20
21namespace WixToolset.VisualStudio.Symbols
22{
23 using WixToolset.Data;
24
25 public enum HelpFilterSymbolFields
26 {
27 Description,
28 QueryString,
29 }
30
31 public class HelpFilterSymbol : IntermediateSymbol
32 {
33 public HelpFilterSymbol() : base(VSSymbolDefinitions.HelpFilter, null, null)
34 {
35 }
36
37 public HelpFilterSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(VSSymbolDefinitions.HelpFilter, sourceLineNumber, id)
38 {
39 }
40
41 public IntermediateField this[HelpFilterSymbolFields index] => this.Fields[(int)index];
42
43 public string Description
44 {
45 get => this.Fields[(int)HelpFilterSymbolFields.Description].AsString();
46 set => this.Set((int)HelpFilterSymbolFields.Description, value);
47 }
48
49 public string QueryString
50 {
51 get => this.Fields[(int)HelpFilterSymbolFields.QueryString].AsString();
52 set => this.Set((int)HelpFilterSymbolFields.QueryString, value);
53 }
54 }
55} \ No newline at end of file
diff --git a/src/ext/VisualStudio/wixext/Symbols/HelpFilterToNamespaceSymbol.cs b/src/ext/VisualStudio/wixext/Symbols/HelpFilterToNamespaceSymbol.cs
new file mode 100644
index 00000000..f3d21289
--- /dev/null
+++ b/src/ext/VisualStudio/wixext/Symbols/HelpFilterToNamespaceSymbol.cs
@@ -0,0 +1,55 @@
1// 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.
2
3namespace WixToolset.VisualStudio
4{
5 using WixToolset.Data;
6 using WixToolset.VisualStudio.Symbols;
7
8 public static partial class VSSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition HelpFilterToNamespace = new IntermediateSymbolDefinition(
11 VSSymbolDefinitionType.HelpFilterToNamespace.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(HelpFilterToNamespaceSymbolFields.HelpFilterRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(HelpFilterToNamespaceSymbolFields.HelpNamespaceRef), IntermediateFieldType.String),
16 },
17 typeof(HelpFilterToNamespaceSymbol));
18 }
19}
20
21namespace WixToolset.VisualStudio.Symbols
22{
23 using WixToolset.Data;
24
25 public enum HelpFilterToNamespaceSymbolFields
26 {
27 HelpFilterRef,
28 HelpNamespaceRef,
29 }
30
31 public class HelpFilterToNamespaceSymbol : IntermediateSymbol
32 {
33 public HelpFilterToNamespaceSymbol() : base(VSSymbolDefinitions.HelpFilterToNamespace, null, null)
34 {
35 }
36
37 public HelpFilterToNamespaceSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(VSSymbolDefinitions.HelpFilterToNamespace, sourceLineNumber, id)
38 {
39 }
40
41 public IntermediateField this[HelpFilterToNamespaceSymbolFields index] => this.Fields[(int)index];
42
43 public string HelpFilterRef
44 {
45 get => this.Fields[(int)HelpFilterToNamespaceSymbolFields.HelpFilterRef].AsString();
46 set => this.Set((int)HelpFilterToNamespaceSymbolFields.HelpFilterRef, value);
47 }
48
49 public string HelpNamespaceRef
50 {
51 get => this.Fields[(int)HelpFilterToNamespaceSymbolFields.HelpNamespaceRef].AsString();
52 set => this.Set((int)HelpFilterToNamespaceSymbolFields.HelpNamespaceRef, value);
53 }
54 }
55} \ No newline at end of file
diff --git a/src/ext/VisualStudio/wixext/Symbols/HelpNamespaceSymbol.cs b/src/ext/VisualStudio/wixext/Symbols/HelpNamespaceSymbol.cs
new file mode 100644
index 00000000..8d2c2f80
--- /dev/null
+++ b/src/ext/VisualStudio/wixext/Symbols/HelpNamespaceSymbol.cs
@@ -0,0 +1,63 @@
1// 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.
2
3namespace WixToolset.VisualStudio
4{
5 using WixToolset.Data;
6 using WixToolset.VisualStudio.Symbols;
7
8 public static partial class VSSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition HelpNamespace = new IntermediateSymbolDefinition(
11 VSSymbolDefinitionType.HelpNamespace.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(HelpNamespaceSymbolFields.NamespaceName), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(HelpNamespaceSymbolFields.CollectionFileRef), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(HelpNamespaceSymbolFields.Description), IntermediateFieldType.String),
17 },
18 typeof(HelpNamespaceSymbol));
19 }
20}
21
22namespace WixToolset.VisualStudio.Symbols
23{
24 using WixToolset.Data;
25
26 public enum HelpNamespaceSymbolFields
27 {
28 NamespaceName,
29 CollectionFileRef,
30 Description,
31 }
32
33 public class HelpNamespaceSymbol : IntermediateSymbol
34 {
35 public HelpNamespaceSymbol() : base(VSSymbolDefinitions.HelpNamespace, null, null)
36 {
37 }
38
39 public HelpNamespaceSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(VSSymbolDefinitions.HelpNamespace, sourceLineNumber, id)
40 {
41 }
42
43 public IntermediateField this[HelpNamespaceSymbolFields index] => this.Fields[(int)index];
44
45 public string NamespaceName
46 {
47 get => this.Fields[(int)HelpNamespaceSymbolFields.NamespaceName].AsString();
48 set => this.Set((int)HelpNamespaceSymbolFields.NamespaceName, value);
49 }
50
51 public string CollectionFileRef
52 {
53 get => this.Fields[(int)HelpNamespaceSymbolFields.CollectionFileRef].AsString();
54 set => this.Set((int)HelpNamespaceSymbolFields.CollectionFileRef, value);
55 }
56
57 public string Description
58 {
59 get => this.Fields[(int)HelpNamespaceSymbolFields.Description].AsString();
60 set => this.Set((int)HelpNamespaceSymbolFields.Description, value);
61 }
62 }
63} \ No newline at end of file
diff --git a/src/ext/VisualStudio/wixext/Symbols/HelpPluginSymbol.cs b/src/ext/VisualStudio/wixext/Symbols/HelpPluginSymbol.cs
new file mode 100644
index 00000000..a452fbd5
--- /dev/null
+++ b/src/ext/VisualStudio/wixext/Symbols/HelpPluginSymbol.cs
@@ -0,0 +1,79 @@
1// 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.
2
3namespace WixToolset.VisualStudio
4{
5 using WixToolset.Data;
6 using WixToolset.VisualStudio.Symbols;
7
8 public static partial class VSSymbolDefinitions
9 {
10 public static readonly IntermediateSymbolDefinition HelpPlugin = new IntermediateSymbolDefinition(
11 VSSymbolDefinitionType.HelpPlugin.ToString(),
12 new[]
13 {
14 new IntermediateFieldDefinition(nameof(HelpPluginSymbolFields.HelpNamespaceRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(HelpPluginSymbolFields.ParentHelpNamespaceRef), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(HelpPluginSymbolFields.HxTFileRef), IntermediateFieldType.String),
17 new IntermediateFieldDefinition(nameof(HelpPluginSymbolFields.HxAFileRef), IntermediateFieldType.String),
18 new IntermediateFieldDefinition(nameof(HelpPluginSymbolFields.ParentHxTFileRef), IntermediateFieldType.String),
19 },
20 typeof(HelpPluginSymbol));
21 }
22}
23
24namespace WixToolset.VisualStudio.Symbols
25{
26 using WixToolset.Data;
27
28 public enum HelpPluginSymbolFields
29 {
30 HelpNamespaceRef,
31 ParentHelpNamespaceRef,
32 HxTFileRef,
33 HxAFileRef,
34 ParentHxTFileRef,
35 }
36
37 public class HelpPluginSymbol : IntermediateSymbol
38 {
39 public HelpPluginSymbol() : base(VSSymbolDefinitions.HelpPlugin, null, null)
40 {
41 }
42
43 public HelpPluginSymbol(SourceLineNumber sourceLineNumber, Identifier id = null) : base(VSSymbolDefinitions.HelpPlugin, sourceLineNumber, id)
44 {
45 }
46
47 public IntermediateField this[HelpPluginSymbolFields index] => this.Fields[(int)index];
48
49 public string HelpNamespaceRef
50 {
51 get => this.Fields[(int)HelpPluginSymbolFields.HelpNamespaceRef].AsString();
52 set => this.Set((int)HelpPluginSymbolFields.HelpNamespaceRef, value);
53 }
54
55 public string ParentHelpNamespaceRef
56 {
57 get => this.Fields[(int)HelpPluginSymbolFields.ParentHelpNamespaceRef].AsString();
58 set => this.Set((int)HelpPluginSymbolFields.ParentHelpNamespaceRef, value);
59 }
60
61 public string HxTFileRef
62 {
63 get => this.Fields[(int)HelpPluginSymbolFields.HxTFileRef].AsString();
64 set => this.Set((int)HelpPluginSymbolFields.HxTFileRef, value);
65 }
66
67 public string HxAFileRef
68 {
69 get => this.Fields[(int)HelpPluginSymbolFields.HxAFileRef].AsString();
70 set => this.Set((int)HelpPluginSymbolFields.HxAFileRef, value);
71 }
72
73 public string ParentHxTFileRef
74 {
75 get => this.Fields[(int)HelpPluginSymbolFields.ParentHxTFileRef].AsString();
76 set => this.Set((int)HelpPluginSymbolFields.ParentHxTFileRef, value);
77 }
78 }
79} \ No newline at end of file
diff --git a/src/ext/VisualStudio/wixext/Symbols/VSSymbolDefinitions.cs b/src/ext/VisualStudio/wixext/Symbols/VSSymbolDefinitions.cs
new file mode 100644
index 00000000..cea6a2b6
--- /dev/null
+++ b/src/ext/VisualStudio/wixext/Symbols/VSSymbolDefinitions.cs
@@ -0,0 +1,59 @@
1// 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.
2
3namespace WixToolset.VisualStudio
4{
5 using System;
6 using WixToolset.Data;
7
8 public enum VSSymbolDefinitionType
9 {
10 HelpFile,
11 HelpFileToNamespace,
12 HelpFilter,
13 HelpFilterToNamespace,
14 HelpNamespace,
15 HelpPlugin,
16 }
17
18 public static partial class VSSymbolDefinitions
19 {
20 public static readonly Version Version = new Version("4.0.0");
21
22 public static IntermediateSymbolDefinition ByName(string name)
23 {
24 if (!Enum.TryParse(name, out VSSymbolDefinitionType type))
25 {
26 return null;
27 }
28
29 return ByType(type);
30 }
31
32 public static IntermediateSymbolDefinition ByType(VSSymbolDefinitionType type)
33 {
34 switch (type)
35 {
36 case VSSymbolDefinitionType.HelpFile:
37 return VSSymbolDefinitions.HelpFile;
38
39 case VSSymbolDefinitionType.HelpFileToNamespace:
40 return VSSymbolDefinitions.HelpFileToNamespace;
41
42 case VSSymbolDefinitionType.HelpFilter:
43 return VSSymbolDefinitions.HelpFilter;
44
45 case VSSymbolDefinitionType.HelpFilterToNamespace:
46 return VSSymbolDefinitions.HelpFilterToNamespace;
47
48 case VSSymbolDefinitionType.HelpNamespace:
49 return VSSymbolDefinitions.HelpNamespace;
50
51 case VSSymbolDefinitionType.HelpPlugin:
52 return VSSymbolDefinitions.HelpPlugin;
53
54 default:
55 throw new ArgumentOutOfRangeException(nameof(type));
56 }
57 }
58 }
59}
diff --git a/src/ext/VisualStudio/wixext/VSCompiler.cs b/src/ext/VisualStudio/wixext/VSCompiler.cs
new file mode 100644
index 00000000..65f0f97d
--- /dev/null
+++ b/src/ext/VisualStudio/wixext/VSCompiler.cs
@@ -0,0 +1,828 @@
1// 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.
2
3namespace WixToolset.VisualStudio
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Globalization;
8 using System.Xml.Linq;
9 using WixToolset.Data;
10 using WixToolset.Data.Symbols;
11 using WixToolset.Data.WindowsInstaller;
12 using WixToolset.Extensibility;
13 using WixToolset.VisualStudio.Symbols;
14
15 /// <summary>
16 /// The compiler for the WiX Toolset Visual Studio Extension.
17 /// </summary>
18 public sealed class VSCompiler : BaseCompilerExtension
19 {
20 internal const int MsidbCustomActionTypeExe = 0x00000002; // Target = command line args
21 internal const int MsidbCustomActionTypeProperty = 0x00000030; // Source = full path to executable
22 internal const int MsidbCustomActionTypeContinue = 0x00000040; // ignore action return status; continue running
23 internal const int MsidbCustomActionTypeRollback = 0x00000100; // in conjunction with InScript: queue in Rollback script
24 internal const int MsidbCustomActionTypeInScript = 0x00000400; // queue for execution within script
25 internal const int MsidbCustomActionTypeNoImpersonate = 0x00000800; // queue for not impersonating
26
27 public override XNamespace Namespace => "http://wixtoolset.org/schemas/v4/wxs/vs";
28
29 public override void ParseElement(Intermediate intermediate, IntermediateSection section, XElement parentElement, XElement element, IDictionary<string, string> context)
30 {
31 switch (parentElement.Name.LocalName)
32 {
33 case "Component":
34 switch (element.Name.LocalName)
35 {
36 case "VsixPackage":
37 this.ParseVsixPackageElement(intermediate, section, element, context["ComponentId"], null);
38 break;
39 default:
40 this.ParseHelper.UnexpectedElement(parentElement, element);
41 break;
42 }
43 break;
44 case "File":
45 switch (element.Name.LocalName)
46 {
47 case "HelpCollection":
48 this.ParseHelpCollectionElement(intermediate, section, element, context["FileId"]);
49 break;
50 case "HelpFile":
51 this.ParseHelpFileElement(intermediate, section, element, context["FileId"]);
52 break;
53 case "VsixPackage":
54 this.ParseVsixPackageElement(intermediate, section, element, context["ComponentId"], context["FileId"]);
55 break;
56 default:
57 this.ParseHelper.UnexpectedElement(parentElement, element);
58 break;
59 }
60 break;
61 case "Fragment":
62 case "Module":
63 case "Package":
64 switch (element.Name.LocalName)
65 {
66 case "HelpCollectionRef":
67 this.ParseHelpCollectionRefElement(intermediate, section, element);
68 break;
69 case "HelpFilter":
70 this.ParseHelpFilterElement(intermediate, section, element);
71 break;
72 default:
73 this.ParseHelper.UnexpectedElement(parentElement, element);
74 break;
75 }
76 break;
77 default:
78 this.ParseHelper.UnexpectedElement(parentElement, element);
79 break;
80 }
81 }
82
83 private void ParseHelpCollectionRefElement(Intermediate intermediate, IntermediateSection section, XElement element)
84 {
85 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
86 Identifier id = null;
87
88 foreach (var attrib in element.Attributes())
89 {
90 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
91 {
92 switch (attrib.Name.LocalName)
93 {
94 case "Id":
95 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
96 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, VSSymbolDefinitions.HelpNamespace, id.Id);
97 break;
98 default:
99 this.ParseHelper.UnexpectedAttribute(element, attrib);
100 break;
101 }
102 }
103 else
104 {
105 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
106 }
107 }
108
109 if (null == id)
110 {
111 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Id"));
112 }
113
114 foreach (var child in element.Elements())
115 {
116 if (this.Namespace == child.Name.Namespace)
117 {
118 switch (child.Name.LocalName)
119 {
120 case "HelpFileRef":
121 this.ParseHelpFileRefElement(intermediate, section, child, id);
122 break;
123 default:
124 this.ParseHelper.UnexpectedElement(element, child);
125 break;
126 }
127 }
128 else
129 {
130 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, element, child);
131 }
132 }
133 }
134
135 private void ParseHelpCollectionElement(Intermediate intermediate, IntermediateSection section, XElement element, string fileId)
136 {
137 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
138 Identifier id = null;
139 string description = null;
140 string name = null;
141 var suppressCAs = YesNoType.No;
142
143 foreach (var attrib in element.Attributes())
144 {
145 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
146 {
147 switch (attrib.Name.LocalName)
148 {
149 case "Id":
150 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
151 break;
152 case "Description":
153 description = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
154 break;
155 case "Name":
156 name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
157 break;
158 case "SuppressCustomActions":
159 suppressCAs = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
160 break;
161 default:
162 this.ParseHelper.UnexpectedAttribute(element, attrib);
163 break;
164 }
165 }
166 else
167 {
168 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
169 }
170 }
171
172 if (null == id)
173 {
174 id = this.ParseHelper.CreateIdentifier("vshc", fileId, description, name);
175 }
176
177 if (null == description)
178 {
179 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Description"));
180 }
181
182 if (null == name)
183 {
184 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name"));
185 }
186
187 foreach (var child in element.Elements())
188 {
189 if (this.Namespace == child.Name.Namespace)
190 {
191 switch (child.Name.LocalName)
192 {
193 case "HelpFileRef":
194 this.ParseHelpFileRefElement(intermediate, section, child, id);
195 break;
196 case "HelpFilterRef":
197 this.ParseHelpFilterRefElement(intermediate, section, child, id);
198 break;
199 case "PlugCollectionInto":
200 this.ParsePlugCollectionIntoElement(intermediate, section, child, id);
201 break;
202 default:
203 this.ParseHelper.UnexpectedElement(element, child);
204 break;
205 }
206 }
207 else
208 {
209 this.ParseHelper.ParseExtensionElement(this.Context.Extensions, intermediate, section, element, child);
210 }
211 }
212
213 if (!this.Messaging.EncounteredError)
214 {
215 section.AddSymbol(new HelpNamespaceSymbol(sourceLineNumbers, id)
216 {
217 NamespaceName = name,
218 CollectionFileRef = fileId,
219 Description = description,
220 });
221
222 if (YesNoType.No == suppressCAs)
223 {
224 this.AddReferenceToRegisterMicrosoftHelp(section, sourceLineNumbers);
225 }
226 }
227 }
228
229 private void ParseHelpFileElement(Intermediate intermediate, IntermediateSection section, XElement element, string fileId)
230 {
231 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
232 Identifier id = null;
233 string name = null;
234 var language = CompilerConstants.IntegerNotSet;
235 string hxi = null;
236 string hxq = null;
237 string hxr = null;
238 string samples = null;
239 var suppressCAs = YesNoType.No;
240
241 foreach (var attrib in element.Attributes())
242 {
243 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
244 {
245 switch (attrib.Name.LocalName)
246 {
247 case "Id":
248 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
249 break;
250 case "AttributeIndex":
251 hxr = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
252 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.File, hxr);
253 break;
254 case "Index":
255 hxi = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
256 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.File, hxi);
257 break;
258 case "Language":
259 language = this.ParseHelper.GetAttributeIntegerValue(sourceLineNumbers, attrib, 0, short.MaxValue);
260 break;
261 case "Name":
262 name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
263 break;
264 case "SampleLocation":
265 samples = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
266 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.File, samples);
267 break;
268 case "Search":
269 hxq = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
270 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.File, hxq);
271 break;
272 case "SuppressCustomActions":
273 suppressCAs = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
274 break;
275 default:
276 this.ParseHelper.UnexpectedAttribute(element, attrib);
277 break;
278 }
279 }
280 else
281 {
282 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
283 }
284 }
285
286 if (null == id)
287 {
288 id = this.ParseHelper.CreateIdentifier("vshf", fileId, name, language.ToString(CultureInfo.InvariantCulture.NumberFormat));
289 }
290
291 if (null == name)
292 {
293 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name"));
294 }
295
296 // Uninstall will always fail silently, leaving file registered, if Language is not set
297 if (CompilerConstants.IntegerNotSet == language)
298 {
299 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Language"));
300 }
301
302 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
303
304 if (!this.Messaging.EncounteredError)
305 {
306 section.AddSymbol(new HelpFileSymbol(sourceLineNumbers, id)
307 {
308 HelpFileName = name,
309 LangID = language,
310 HxSFileRef = fileId,
311 HxIFileRef = hxi,
312 HxQFileRef = hxq,
313 HxRFileRef = hxr,
314 SamplesFileRef = samples,
315 });
316
317 if (YesNoType.No == suppressCAs)
318 {
319 this.AddReferenceToRegisterMicrosoftHelp(section, sourceLineNumbers);
320 }
321 }
322 }
323
324 private void ParseHelpFileRefElement(Intermediate intermediate, IntermediateSection section, XElement element, Identifier collectionId)
325 {
326 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
327 Identifier id = null;
328
329 foreach (var attrib in element.Attributes())
330 {
331 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
332 {
333 switch (attrib.Name.LocalName)
334 {
335 case "Id":
336 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
337 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, VSSymbolDefinitions.HelpFile, id.Id);
338 break;
339 default:
340 this.ParseHelper.UnexpectedAttribute(element, attrib);
341 break;
342 }
343 }
344 else
345 {
346 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
347 }
348 }
349
350 if (null == id)
351 {
352 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Id"));
353 }
354
355 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
356
357 if (!this.Messaging.EncounteredError)
358 {
359 section.AddSymbol(new HelpFileToNamespaceSymbol(sourceLineNumbers, id)
360 {
361 HelpFileRef = id.Id,
362 HelpNamespaceRef = collectionId.Id,
363 });
364 }
365 }
366
367 private void ParseHelpFilterElement(Intermediate intermediate, IntermediateSection section, XElement element)
368 {
369 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
370 Identifier id = null;
371 string filterDefinition = null;
372 string name = null;
373 var suppressCAs = YesNoType.No;
374
375 foreach (var attrib in element.Attributes())
376 {
377 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
378 {
379 switch (attrib.Name.LocalName)
380 {
381 case "Id":
382 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
383 break;
384 case "FilterDefinition":
385 filterDefinition = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
386 break;
387 case "Name":
388 name = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
389 break;
390 case "SuppressCustomActions":
391 suppressCAs = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
392 break;
393 default:
394 this.ParseHelper.UnexpectedAttribute(element, attrib);
395 break;
396 }
397 }
398 else
399 {
400 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
401 }
402 }
403
404 if (null == id)
405 {
406 id = this.ParseHelper.CreateIdentifier("hfl", name, filterDefinition);
407 }
408
409 if (null == name)
410 {
411 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name"));
412 }
413
414 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
415
416 if (!this.Messaging.EncounteredError)
417 {
418 section.AddSymbol(new HelpFilterSymbol(sourceLineNumbers, id)
419 {
420 Description = name,
421 QueryString = filterDefinition,
422 });
423
424 if (YesNoType.No == suppressCAs)
425 {
426 this.AddReferenceToRegisterMicrosoftHelp(section, sourceLineNumbers);
427 }
428 }
429 }
430
431 private void ParseHelpFilterRefElement(Intermediate intermediate, IntermediateSection section, XElement element, Identifier collectionId)
432 {
433 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
434 Identifier id = null;
435
436 foreach (var attrib in element.Attributes())
437 {
438 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
439 {
440 switch (attrib.Name.LocalName)
441 {
442 case "Id":
443 id = this.ParseHelper.GetAttributeIdentifier(sourceLineNumbers, attrib);
444 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, VSSymbolDefinitions.HelpFilter, id.Id);
445 break;
446 default:
447 this.ParseHelper.UnexpectedAttribute(element, attrib);
448 break;
449 }
450 }
451 else
452 {
453 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
454 }
455 }
456
457 if (null == id)
458 {
459 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Id"));
460 }
461
462 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
463
464 if (!this.Messaging.EncounteredError)
465 {
466 section.AddSymbol(new HelpFilterToNamespaceSymbol(sourceLineNumbers, id)
467 {
468 HelpFilterRef = id.Id,
469 HelpNamespaceRef = collectionId.Id,
470 });
471 }
472 }
473
474 private void ParsePlugCollectionIntoElement(Intermediate intermediate, IntermediateSection section, XElement element, Identifier parentId)
475 {
476 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
477 string hxa = null;
478 string hxt = null;
479 string hxtParent = null;
480 string namespaceParent = null;
481 string feature = null;
482 var suppressExternalNamespaces = YesNoType.No;
483
484 foreach (var attrib in element.Attributes())
485 {
486 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
487 {
488 switch (attrib.Name.LocalName)
489 {
490 case "Attributes":
491 hxa = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
492 break;
493 case "TableOfContents":
494 hxt = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
495 break;
496 case "TargetCollection":
497 namespaceParent = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
498 break;
499 case "TargetTableOfContents":
500 hxtParent = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
501 break;
502 case "TargetFeature":
503 feature = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
504 break;
505 case "SuppressExternalNamespaces":
506 suppressExternalNamespaces = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
507 break;
508 default:
509 this.ParseHelper.UnexpectedAttribute(element, attrib);
510 break;
511 }
512 }
513 else
514 {
515 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
516 }
517 }
518
519 var pluginVS05 = namespaceParent.Equals("MS_VSIPCC_v80", StringComparison.Ordinal);
520 var pluginVS08 = namespaceParent.Equals("MS.VSIPCC.v90", StringComparison.Ordinal);
521
522 if (null == namespaceParent)
523 {
524 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "TargetCollection"));
525 }
526
527 if (null == feature && (pluginVS05 || pluginVS08) && YesNoType.No == suppressExternalNamespaces)
528 {
529 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "TargetFeature"));
530 }
531
532 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
533
534 if (!this.Messaging.EncounteredError)
535 {
536 section.AddSymbol(new HelpPluginSymbol(sourceLineNumbers, parentId)
537 {
538 HelpNamespaceRef = parentId.Id,
539 ParentHelpNamespaceRef = namespaceParent,
540 HxTFileRef = hxt,
541 HxAFileRef = hxa,
542 ParentHxTFileRef = hxtParent,
543 });
544
545 if (pluginVS05)
546 {
547 if (YesNoType.No == suppressExternalNamespaces)
548 {
549 // Bring in the help 2 base namespace components for VS 2005
550 this.ParseHelper.CreateComplexReference(section, sourceLineNumbers, ComplexReferenceParentType.Feature, feature, String.Empty,
551 ComplexReferenceChildType.ComponentGroup, "Help2_VS2005_Namespace_Components", false);
552 // Reference CustomAction since nothing will happen without it
553 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.CustomAction, "CA_HxMerge_VSIPCC_VSCC");
554 }
555 }
556 else if (pluginVS08)
557 {
558 if (YesNoType.No == suppressExternalNamespaces)
559 {
560 // Bring in the help 2 base namespace components for VS 2008
561 this.ParseHelper.CreateComplexReference(section, sourceLineNumbers, ComplexReferenceParentType.Feature, feature, String.Empty,
562 ComplexReferenceChildType.ComponentGroup, "Help2_VS2008_Namespace_Components", false);
563 // Reference CustomAction since nothing will happen without it
564 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.CustomAction, "CA_ScheduleExtHelpPlugin_VSCC_VSIPCC");
565 }
566 }
567 else
568 {
569 // Reference the parent namespace to enforce the foreign key relationship
570 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, VSSymbolDefinitions.HelpNamespace, namespaceParent);
571 }
572 }
573 }
574
575 private void ParseVsixPackageElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId, string fileId)
576 {
577 var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
578 var propertyId = "VS_VSIX_INSTALLER_PATH";
579 string packageId = null;
580 var permanent = YesNoType.NotSet;
581 string target = null;
582 string targetVersion = null;
583 var vital = YesNoType.NotSet;
584
585 foreach (var attrib in element.Attributes())
586 {
587 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
588 {
589 switch (attrib.Name.LocalName)
590 {
591 case "File":
592 if (String.IsNullOrEmpty(fileId))
593 {
594 fileId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
595 }
596 else
597 {
598 this.Messaging.Write(ErrorMessages.IllegalAttributeWhenNested(sourceLineNumbers, element.Name.LocalName, "File", "File"));
599 }
600 break;
601 case "PackageId":
602 packageId = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
603 break;
604 case "Permanent":
605 permanent = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
606 break;
607 case "Target":
608 target = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
609 switch (target.ToLowerInvariant())
610 {
611 case "integrated":
612 case "integratedshell":
613 target = "IntegratedShell";
614 break;
615 case "professional":
616 target = "Pro";
617 break;
618 case "premium":
619 target = "Premium";
620 break;
621 case "ultimate":
622 target = "Ultimate";
623 break;
624 case "vbexpress":
625 target = "VBExpress";
626 break;
627 case "vcexpress":
628 target = "VCExpress";
629 break;
630 case "vcsexpress":
631 target = "VCSExpress";
632 break;
633 case "vwdexpress":
634 target = "VWDExpress";
635 break;
636 }
637 break;
638 case "TargetVersion":
639 targetVersion = this.ParseHelper.GetAttributeVersionValue(sourceLineNumbers, attrib);
640 break;
641 case "Vital":
642 vital = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
643 break;
644 case "VsixInstallerPathProperty":
645 propertyId = this.ParseHelper.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
646 break;
647 default:
648 this.ParseHelper.UnexpectedAttribute(element, attrib);
649 break;
650 }
651 }
652 else
653 {
654 this.ParseHelper.ParseExtensionAttribute(this.Context.Extensions, intermediate, section, element, attrib);
655 }
656 }
657
658 if (String.IsNullOrEmpty(fileId))
659 {
660 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "File"));
661 }
662
663 if (String.IsNullOrEmpty(packageId))
664 {
665 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "PackageId"));
666 }
667
668 if (!String.IsNullOrEmpty(target) && String.IsNullOrEmpty(targetVersion))
669 {
670 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "TargetVersion", "Target"));
671 }
672 else if (String.IsNullOrEmpty(target) && !String.IsNullOrEmpty(targetVersion))
673 {
674 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Target", "TargetVersion"));
675 }
676
677 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
678
679 if (!this.Messaging.EncounteredError)
680 {
681 // Ensure there is a reference to the AppSearch Property that will find the VsixInstaller.exe.
682 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.Property, propertyId);
683
684 // Ensure there is a reference to the package file (even if we are a child under it).
685 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.File, fileId);
686
687 var cmdlinePrefix = "/q ";
688
689 if (!String.IsNullOrEmpty(target))
690 {
691 cmdlinePrefix = String.Format("{0} /skuName:{1} /skuVersion:{2}", cmdlinePrefix, target, targetVersion);
692 }
693
694 var installAfter = "WriteRegistryValues"; // by default, come after the registry key registration.
695
696 var installNamePerUser = this.ParseHelper.CreateIdentifier("viu", componentId, fileId, "per-user", target, targetVersion);
697 var installNamePerMachine = this.ParseHelper.CreateIdentifier("vim", componentId, fileId, "per-machine", target, targetVersion);
698 var installCmdLinePerUser = String.Format("{0} \"[#{1}]\"", cmdlinePrefix, fileId);
699 var installCmdLinePerMachine = String.Concat(installCmdLinePerUser, " /admin");
700 var installConditionPerUser = String.Format("NOT ALLUSERS AND ${0}=3", componentId); // only execute if the Component being installed.
701 var installConditionPerMachine = String.Format("ALLUSERS AND ${0}=3", componentId); // only execute if the Component being installed.
702 var installPerUserCA = new CustomActionSymbol(sourceLineNumbers, installNamePerUser)
703 {
704 ExecutionType = CustomActionExecutionType.Deferred,
705 Impersonate = true,
706 };
707 var installPerMachineCA = new CustomActionSymbol(sourceLineNumbers, installNamePerMachine)
708 {
709 ExecutionType = CustomActionExecutionType.Deferred,
710 Impersonate = false,
711 };
712
713 // If the package is not vital, mark the install action as continue.
714 if (vital == YesNoType.No)
715 {
716 installPerUserCA.IgnoreResult = true;
717 installPerMachineCA.IgnoreResult = true;
718 }
719 else // the package is vital so ensure there is a rollback action scheduled.
720 {
721 var rollbackNamePerUser = this.ParseHelper.CreateIdentifier("vru", componentId, fileId, "per-user", target, targetVersion);
722 var rollbackNamePerMachine = this.ParseHelper.CreateIdentifier("vrm", componentId, fileId, "per-machine", target, targetVersion);
723 var rollbackCmdLinePerUser = String.Concat(cmdlinePrefix, " /u:\"", packageId, "\"");
724 var rollbackCmdLinePerMachine = String.Concat(rollbackCmdLinePerUser, " /admin");
725 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.
726 var rollbackConditionPerMachine = String.Format("ALLUSERS AND NOT Installed AND ${0}=2 AND ?{0}>2", componentId); // NOT Installed && Component being installed but not installed already.
727 var rollbackPerUserCA = new CustomActionSymbol(sourceLineNumbers, rollbackNamePerUser)
728 {
729 ExecutionType = CustomActionExecutionType.Rollback,
730 IgnoreResult = true,
731 Impersonate = true,
732 };
733 var rollbackPerMachineCA = new CustomActionSymbol(sourceLineNumbers, rollbackNamePerMachine)
734 {
735 ExecutionType = CustomActionExecutionType.Rollback,
736 IgnoreResult = true,
737 Impersonate = false,
738 };
739
740 this.SchedulePropertyExeAction(section, sourceLineNumbers, rollbackNamePerUser, propertyId, rollbackCmdLinePerUser, rollbackPerUserCA, rollbackConditionPerUser, null, installAfter);
741 this.SchedulePropertyExeAction(section, sourceLineNumbers, rollbackNamePerMachine, propertyId, rollbackCmdLinePerMachine, rollbackPerMachineCA, rollbackConditionPerMachine, null, rollbackNamePerUser.Id);
742
743 installAfter = rollbackNamePerMachine.Id;
744 }
745
746 this.SchedulePropertyExeAction(section, sourceLineNumbers, installNamePerUser, propertyId, installCmdLinePerUser, installPerUserCA, installConditionPerUser, null, installAfter);
747 this.SchedulePropertyExeAction(section, sourceLineNumbers, installNamePerMachine, propertyId, installCmdLinePerMachine, installPerMachineCA, installConditionPerMachine, null, installNamePerUser.Id);
748
749 // If not permanent, schedule the uninstall custom action.
750 if (permanent != YesNoType.Yes)
751 {
752 var uninstallNamePerUser = this.ParseHelper.CreateIdentifier("vuu", componentId, fileId, "per-user", target ?? String.Empty, targetVersion ?? String.Empty);
753 var uninstallNamePerMachine = this.ParseHelper.CreateIdentifier("vum", componentId, fileId, "per-machine", target ?? String.Empty, targetVersion ?? String.Empty);
754 var uninstallCmdLinePerUser = String.Concat(cmdlinePrefix, " /u:\"", packageId, "\"");
755 var uninstallCmdLinePerMachine = String.Concat(uninstallCmdLinePerUser, " /admin");
756 var uninstallConditionPerUser = String.Format("NOT ALLUSERS AND ${0}=2 AND ?{0}>2", componentId); // Only execute if component is being uninstalled.
757 var uninstallConditionPerMachine = String.Format("ALLUSERS AND ${0}=2 AND ?{0}>2", componentId); // Only execute if component is being uninstalled.
758 var uninstallPerUserCA = new CustomActionSymbol(sourceLineNumbers, uninstallNamePerUser)
759 {
760 ExecutionType = CustomActionExecutionType.Deferred,
761 IgnoreResult = true,
762 Impersonate = true,
763 };
764 var uninstallPerMachineCA = new CustomActionSymbol(sourceLineNumbers, uninstallNamePerMachine)
765 {
766 ExecutionType = CustomActionExecutionType.Deferred,
767 IgnoreResult = true,
768 Impersonate = false,
769 };
770
771 this.SchedulePropertyExeAction(section, sourceLineNumbers, uninstallNamePerUser, propertyId, uninstallCmdLinePerUser, uninstallPerUserCA, uninstallConditionPerUser, "InstallFinalize", null);
772 this.SchedulePropertyExeAction(section, sourceLineNumbers, uninstallNamePerMachine, propertyId, uninstallCmdLinePerMachine, uninstallPerMachineCA, uninstallConditionPerMachine, "InstallFinalize", null);
773 }
774 }
775 }
776
777 private void SchedulePropertyExeAction(IntermediateSection section, SourceLineNumber sourceLineNumbers, Identifier name, string source, string cmdline, CustomActionSymbol caTemplate, string condition, string beforeAction, string afterAction)
778 {
779 const SequenceTable sequence = SequenceTable.InstallExecuteSequence;
780
781 caTemplate.SourceType = CustomActionSourceType.Property;
782 caTemplate.Source = source;
783 caTemplate.TargetType = CustomActionTargetType.Exe;
784 caTemplate.Target = cmdline;
785 section.AddSymbol(caTemplate);
786
787 section.AddSymbol(new WixActionSymbol(sourceLineNumbers, new Identifier(name.Access, sequence, name.Id))
788 {
789 SequenceTable = SequenceTable.InstallExecuteSequence,
790 Action = name.Id,
791 Condition = condition,
792 // no explicit sequence
793 Before = beforeAction,
794 After = afterAction,
795 Overridable = false,
796 });
797
798 if (null != beforeAction)
799 {
800 if (WindowsInstallerStandard.IsStandardAction(beforeAction))
801 {
802 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.WixAction, sequence.ToString(), beforeAction);
803 }
804 else
805 {
806 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.CustomAction, beforeAction);
807 }
808 }
809
810 if (null != afterAction)
811 {
812 if (WindowsInstallerStandard.IsStandardAction(afterAction))
813 {
814 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.WixAction, sequence.ToString(), afterAction);
815 }
816 else
817 {
818 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.CustomAction, afterAction);
819 }
820 }
821 }
822
823 private void AddReferenceToRegisterMicrosoftHelp(IntermediateSection section, SourceLineNumber sourceLineNumbers)
824 {
825 this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, SymbolDefinitions.CustomAction, "CA_RegisterMicrosoftHelp.3643236F_FC70_11D3_A536_0090278A1BB8");
826 }
827 }
828}
diff --git a/src/ext/VisualStudio/wixext/VSDecompiler.cs b/src/ext/VisualStudio/wixext/VSDecompiler.cs
new file mode 100644
index 00000000..08dc364a
--- /dev/null
+++ b/src/ext/VisualStudio/wixext/VSDecompiler.cs
@@ -0,0 +1,298 @@
1// 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.
2
3namespace WixToolset.VisualStudio
4{
5#if TODO_CONSIDER_DECOMPILER
6 using System;
7 using System.Collections;
8 using System.Diagnostics;
9 using System.Globalization;
10 using WixToolset.Data;
11 using WixToolset.Extensibility;
12 using VS = WixToolset.Extensions.Serialize.VS;
13 using Wix = WixToolset.Data.Serialize;
14
15 /// <summary>
16 /// The decompiler for the WiX Toolset Visual Studio Extension.
17 /// </summary>
18 public sealed class VSDecompiler : DecompilerExtension
19 {
20 /// <summary>
21 /// Creates a decompiler for VS Extension.
22 /// </summary>
23 public VSDecompiler()
24 {
25 this.TableDefinitions = VSExtensionData.GetExtensionTableDefinitions();
26 }
27
28 /// <summary>
29 /// Get the extensions library to be removed.
30 /// </summary>
31 /// <param name="tableDefinitions">Table definitions for library.</param>
32 /// <returns>Library to remove from decompiled output.</returns>
33 public override Library GetLibraryToRemove(TableDefinitionCollection tableDefinitions)
34 {
35 return VSExtensionData.GetExtensionLibrary(tableDefinitions);
36 }
37
38 /// <summary>
39 /// Decompiles an extension table.
40 /// </summary>
41 /// <param name="table">The table to decompile.</param>
42 public override void DecompileTable(Table table)
43 {
44 switch (table.Name)
45 {
46 case "HelpFile":
47 this.DecompileHelpFileTable(table);
48 break;
49 case "HelpFileToNamespace":
50 this.DecompileHelpFileToNamespaceTable(table);
51 break;
52 case "HelpFilter":
53 this.DecompileHelpFilterTable(table);
54 break;
55 case "HelpFilterToNamespace":
56 this.DecompileHelpFilterToNamespaceTable(table);
57 break;
58 case "HelpNamespace":
59 this.DecompileHelpNamespaceTable(table);
60 break;
61 case "HelpPlugin":
62 this.DecompileHelpPluginTable(table);
63 break;
64 default:
65 base.DecompileTable(table);
66 break;
67 }
68 }
69
70 /// <summary>
71 /// Decompile the HelpFile table.
72 /// </summary>
73 /// <param name="table">The table to decompile.</param>
74 private void DecompileHelpFileTable(Table table)
75 {
76 foreach (Row row in table.Rows)
77 {
78 VS.HelpFile helpFile = new VS.HelpFile();
79
80 helpFile.Id = (string)row[0];
81
82 helpFile.Name = (string)row[1];
83
84 if (null != row[2])
85 {
86 helpFile.Language = (int)row[2];
87 }
88
89 if (null != row[4])
90 {
91 helpFile.Index = (string)row[4];
92 }
93
94 if (null != row[5])
95 {
96 helpFile.Search = (string)row[5];
97 }
98
99 if (null != row[6])
100 {
101 helpFile.AttributeIndex = (string)row[6];
102 }
103
104 if (null != row[7])
105 {
106 helpFile.SampleLocation = (string)row[7];
107 }
108
109 if (this.Core.RootElement is Wix.Module)
110 {
111 helpFile.SuppressCustomActions = VS.YesNoType.yes;
112 }
113
114 Wix.File file = (Wix.File)this.Core.GetIndexedElement("File", (string)row[3]);
115 if (null != file)
116 {
117 file.AddChild(helpFile);
118 }
119 else
120 {
121 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "File_HxS", (string)row[3], "File"));
122 }
123 }
124 }
125
126 /// <summary>
127 /// Decompile the HelpFileToNamespace table.
128 /// </summary>
129 /// <param name="table">The table to decompile.</param>
130 private void DecompileHelpFileToNamespaceTable(Table table)
131 {
132 foreach (Row row in table.Rows)
133 {
134 VS.HelpFileRef helpFileRef = new VS.HelpFileRef();
135
136 helpFileRef.Id = (string)row[0];
137
138 VS.HelpCollection helpCollection = (VS.HelpCollection)this.Core.GetIndexedElement("HelpNamespace", (string)row[1]);
139 if (null != helpCollection)
140 {
141 helpCollection.AddChild(helpFileRef);
142 }
143 else
144 {
145 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "HelpNamespace_", (string)row[1], "HelpNamespace"));
146 }
147 }
148 }
149
150 /// <summary>
151 /// Decompile the HelpFilter table.
152 /// </summary>
153 /// <param name="table">The table to decompile.</param>
154 private void DecompileHelpFilterTable(Table table)
155 {
156 foreach (Row row in table.Rows)
157 {
158 VS.HelpFilter helpFilter = new VS.HelpFilter();
159
160 helpFilter.Id = (string)row[0];
161
162 helpFilter.Name = (string)row[1];
163
164 if (null != row[2])
165 {
166 helpFilter.FilterDefinition = (string)row[2];
167 }
168
169 if (this.Core.RootElement is Wix.Module)
170 {
171 helpFilter.SuppressCustomActions = VS.YesNoType.yes;
172 }
173
174 this.Core.RootElement.AddChild(helpFilter);
175 }
176 }
177
178 /// <summary>
179 /// Decompile the HelpFilterToNamespace table.
180 /// </summary>
181 /// <param name="table">The table to decompile.</param>
182 private void DecompileHelpFilterToNamespaceTable(Table table)
183 {
184 foreach (Row row in table.Rows)
185 {
186 VS.HelpFilterRef helpFilterRef = new VS.HelpFilterRef();
187
188 helpFilterRef.Id = (string)row[0];
189
190 VS.HelpCollection helpCollection = (VS.HelpCollection)this.Core.GetIndexedElement("HelpNamespace", (string)row[1]);
191 if (null != helpCollection)
192 {
193 helpCollection.AddChild(helpFilterRef);
194 }
195 else
196 {
197 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "HelpNamespace_", (string)row[1], "HelpNamespace"));
198 }
199 }
200 }
201
202 /// <summary>
203 /// Decompile the HelpNamespace table.
204 /// </summary>
205 /// <param name="table">The table to decompile.</param>
206 private void DecompileHelpNamespaceTable(Table table)
207 {
208 foreach (Row row in table.Rows)
209 {
210 VS.HelpCollection helpCollection = new VS.HelpCollection();
211
212 helpCollection.Id = (string)row[0];
213
214 helpCollection.Name = (string)row[1];
215
216 if (null != row[3])
217 {
218 helpCollection.Description = (string)row[3];
219 }
220
221 if (this.Core.RootElement is Wix.Module)
222 {
223 helpCollection.SuppressCustomActions = VS.YesNoType.yes;
224 }
225
226 Wix.File file = (Wix.File)this.Core.GetIndexedElement("File", (string)row[2]);
227 if (null != file)
228 {
229 file.AddChild(helpCollection);
230 }
231 else if (0 != String.Compare(helpCollection.Id, "MS_VSIPCC_v80", StringComparison.Ordinal) &&
232 0 != String.Compare(helpCollection.Id, "MS.VSIPCC.v90", StringComparison.Ordinal))
233 {
234 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "File_Collection", (string)row[2], "File"));
235 }
236 this.Core.IndexElement(row, helpCollection);
237 }
238 }
239
240 /// <summary>
241 /// Decompile the HelpPlugin table.
242 /// </summary>
243 /// <param name="table">The table to decompile.</param>
244 private void DecompileHelpPluginTable(Table table)
245 {
246 foreach (Row row in table.Rows)
247 {
248 VS.PlugCollectionInto plugCollectionInto = new VS.PlugCollectionInto();
249
250 plugCollectionInto.TargetCollection = (string)row[1];
251
252 if (null != row[2])
253 {
254 plugCollectionInto.TableOfContents = (string)row[2];
255 }
256
257 if (null != row[3])
258 {
259 plugCollectionInto.Attributes = (string)row[3];
260 }
261
262 if (null != row[4])
263 {
264 plugCollectionInto.TargetTableOfContents = (string)row[4];
265 }
266
267 if (this.Core.RootElement is Wix.Module)
268 {
269 plugCollectionInto.SuppressExternalNamespaces = VS.YesNoType.yes;
270 }
271
272 //we cannot do this work because we cannot get the FeatureComponent table
273 //plugCollectionInto.TargetFeature = DecompileHelpComponents();
274
275 VS.HelpCollection helpCollection = (VS.HelpCollection)this.Core.GetIndexedElement("HelpNamespace", (string)row[0]);
276 if (null != helpCollection)
277 {
278 helpCollection.AddChild(plugCollectionInto);
279 }
280 else
281 {
282 this.Core.OnMessage(WixWarnings.ExpectedForeignRow(row.SourceLineNumbers, table.Name, row.GetPrimaryKey(DecompilerConstants.PrimaryKeyDelimiter), "HelpNamespace_", (string)row[0], "HelpNamespace"));
283 }
284 }
285 }
286 //private string DecompileHelpComponents()
287 //{
288 // throw new NotImplementedException();
289 // //Find both known compontents from FeatureComponents table and build feature list
290
291 // //remove components from FeatureComponents
292
293 // //return a space delimited list of features that mapped to our help components
294 // return String.Empty;
295 //}
296 }
297#endif
298}
diff --git a/src/ext/VisualStudio/wixext/VSExtensionData.cs b/src/ext/VisualStudio/wixext/VSExtensionData.cs
new file mode 100644
index 00000000..51199d2c
--- /dev/null
+++ b/src/ext/VisualStudio/wixext/VSExtensionData.cs
@@ -0,0 +1,27 @@
1// 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.
2
3namespace WixToolset.VisualStudio
4{
5 using WixToolset.Data;
6 using WixToolset.Extensibility;
7
8 public sealed class VSExtensionData : BaseExtensionData
9 {
10 /// <summary>
11 /// Gets the default culture.
12 /// </summary>
13 /// <value>The default culture.</value>
14 public override string DefaultCulture => "en-US";
15
16 public override bool TryGetSymbolDefinitionByName(string name, out IntermediateSymbolDefinition symbolDefinition)
17 {
18 symbolDefinition = VSSymbolDefinitions.ByName(name);
19 return symbolDefinition != null;
20 }
21
22 public override Intermediate GetLibrary(ISymbolDefinitionCreator symbolDefinitions)
23 {
24 return Intermediate.Load(typeof(VSExtensionData).Assembly, "WixToolset.VisualStudio.vs.wixlib", symbolDefinitions);
25 }
26 }
27}
diff --git a/src/ext/VisualStudio/wixext/VSExtensionFactory.cs b/src/ext/VisualStudio/wixext/VSExtensionFactory.cs
new file mode 100644
index 00000000..c6e0cc31
--- /dev/null
+++ b/src/ext/VisualStudio/wixext/VSExtensionFactory.cs
@@ -0,0 +1,18 @@
1// 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.
2
3namespace WixToolset.VisualStudio
4{
5 using System;
6 using System.Collections.Generic;
7 using WixToolset.Extensibility;
8
9 public class VSExtensionFactory : BaseExtensionFactory
10 {
11 protected override IReadOnlyCollection<Type> ExtensionTypes => new[]
12 {
13 typeof(VSCompiler),
14 typeof(VSExtensionData),
15 typeof(VSWindowsInstallerBackendBinderExtension),
16 };
17 }
18}
diff --git a/src/ext/VisualStudio/wixext/VSTableDefinitions.cs b/src/ext/VisualStudio/wixext/VSTableDefinitions.cs
new file mode 100644
index 00000000..0c3ca907
--- /dev/null
+++ b/src/ext/VisualStudio/wixext/VSTableDefinitions.cs
@@ -0,0 +1,97 @@
1// 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.
2
3namespace WixToolset.VisualStudio
4{
5 using WixToolset.Data.WindowsInstaller;
6
7 public static class VSTableDefinitions
8 {
9 public static readonly TableDefinition HelpFile = new TableDefinition(
10 "HelpFile",
11 VSSymbolDefinitions.HelpFile,
12 new[]
13 {
14 new ColumnDefinition("HelpFileKey", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary Key for HelpFile Table (required).", modularizeType: ColumnModularizeType.Column),
15 new ColumnDefinition("HelpFileName", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Text, description: "Internal Microsoft Help ID for this HelpFile (required)."),
16 new ColumnDefinition("LangID", ColumnType.Number, 2, primaryKey: false, nullable: true, ColumnCategory.Language, description: "Language ID for content file (optional)."),
17 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),
18 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),
19 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),
20 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),
21 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),
22 },
23 symbolIdIsPrimaryKey: true
24 );
25
26 public static readonly TableDefinition HelpFileToNamespace = new TableDefinition(
27 "HelpFileToNamespace",
28 VSSymbolDefinitions.HelpFileToNamespace,
29 new[]
30 {
31 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),
32 new ColumnDefinition("HelpNamespace_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "HelpNamespace", keyColumn: 1, description: "Foreign key into HelpNamespace table (required)."),
33 },
34 symbolIdIsPrimaryKey: false
35 );
36
37 public static readonly TableDefinition HelpFilter = new TableDefinition(
38 "HelpFilter",
39 VSSymbolDefinitions.HelpFilter,
40 new[]
41 {
42 new ColumnDefinition("FilterKey", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary Key for HelpFilter (required).", modularizeType: ColumnModularizeType.Column),
43 new ColumnDefinition("Description", ColumnType.Localized, 0, primaryKey: false, nullable: false, ColumnCategory.Text, description: "Friendly name for Filter (required)."),
44 new ColumnDefinition("QueryString", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Text, description: "Query String for Help Filter (optional)."),
45 },
46 symbolIdIsPrimaryKey: true
47 );
48
49 public static readonly TableDefinition HelpFilterToNamespace = new TableDefinition(
50 "HelpFilterToNamespace",
51 VSSymbolDefinitions.HelpFilterToNamespace,
52 new[]
53 {
54 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),
55 new ColumnDefinition("HelpNamespace_", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, keyTable: "HelpNamespace", keyColumn: 1, description: "Foreign key into HelpNamespace table (required)."),
56 },
57 symbolIdIsPrimaryKey: false
58 );
59
60 public static readonly TableDefinition HelpNamespace = new TableDefinition(
61 "HelpNamespace",
62 VSSymbolDefinitions.HelpNamespace,
63 new[]
64 {
65 new ColumnDefinition("NamespaceKey", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "Primary Key for HelpNamespace (required)."),
66 new ColumnDefinition("NamespaceName", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Text, description: "Internal Microsoft Help ID for this Namespace (required)."),
67 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),
68 new ColumnDefinition("Description", ColumnType.Localized, 0, primaryKey: false, nullable: true, ColumnCategory.Text, description: "Friendly name for Namespace (optional)."),
69 },
70 symbolIdIsPrimaryKey: true
71 );
72
73 public static readonly TableDefinition HelpPlugin = new TableDefinition(
74 "HelpPlugin",
75 VSSymbolDefinitions.HelpPlugin,
76 new[]
77 {
78 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)."),
79 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)."),
80 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),
81 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),
82 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),
83 },
84 symbolIdIsPrimaryKey: false
85 );
86
87 public static readonly TableDefinition[] All = new[]
88 {
89 HelpFile,
90 HelpFileToNamespace,
91 HelpFilter,
92 HelpFilterToNamespace,
93 HelpNamespace,
94 HelpPlugin,
95 };
96 }
97}
diff --git a/src/ext/VisualStudio/wixext/VSWindowsInstallerBackendBinderExtension.cs b/src/ext/VisualStudio/wixext/VSWindowsInstallerBackendBinderExtension.cs
new file mode 100644
index 00000000..d0d8648c
--- /dev/null
+++ b/src/ext/VisualStudio/wixext/VSWindowsInstallerBackendBinderExtension.cs
@@ -0,0 +1,13 @@
1// 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.
2
3namespace WixToolset.VisualStudio
4{
5 using System.Collections.Generic;
6 using WixToolset.Data.WindowsInstaller;
7 using WixToolset.Extensibility;
8
9 public class VSWindowsInstallerBackendBinderExtension : BaseWindowsInstallerBackendBinderExtension
10 {
11 public override IReadOnlyCollection<TableDefinition> TableDefinitions => VSTableDefinitions.All;
12 }
13}
diff --git a/src/ext/VisualStudio/wixext/WixToolset.VisualStudio.wixext.csproj b/src/ext/VisualStudio/wixext/WixToolset.VisualStudio.wixext.csproj
new file mode 100644
index 00000000..20282720
--- /dev/null
+++ b/src/ext/VisualStudio/wixext/WixToolset.VisualStudio.wixext.csproj
@@ -0,0 +1,30 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4<Project Sdk="Microsoft.NET.Sdk">
5 <PropertyGroup>
6 <TargetFramework>netstandard2.0</TargetFramework>
7 <RootNamespace>WixToolset.VisualStudio</RootNamespace>
8 <Description>WiX Toolset Visual Studio Extension</Description>
9 <Title>WiX Toolset VS Extension</Title>
10 <IsTool>true</IsTool>
11 <IncludeSymbols>true</IncludeSymbols>
12 </PropertyGroup>
13
14 <ItemGroup>
15 <EmbeddedResource Include="$(OutputPath)..\vs.wixlib" />
16 </ItemGroup>
17
18 <ItemGroup>
19 <ProjectReference Include="..\wixlib\vs.wixproj" ReferenceOutputAssembly="false" Condition=" '$(NCrunch)'=='' " />
20 </ItemGroup>
21
22 <ItemGroup>
23 <PackageReference Include="WixToolset.Extensibility" Version="4.0.*" PrivateAssets="all" />
24 </ItemGroup>
25
26 <ItemGroup>
27 <PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="all" />
28 <PackageReference Include="Nerdbank.GitVersioning" Version="3.3.37" PrivateAssets="all" />
29 </ItemGroup>
30</Project>
diff --git a/src/ext/VisualStudio/wixext/WixToolset.VisualStudio.wixext.nuspec b/src/ext/VisualStudio/wixext/WixToolset.VisualStudio.wixext.nuspec
new file mode 100644
index 00000000..51c9708e
--- /dev/null
+++ b/src/ext/VisualStudio/wixext/WixToolset.VisualStudio.wixext.nuspec
@@ -0,0 +1,23 @@
1<?xml version="1.0"?>
2<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
3 <metadata minClientVersion="4.0">
4 <id>$id$</id>
5 <version>$version$</version>
6 <title>$title$</title>
7 <description>$description$</description>
8 <authors>$authors$</authors>
9 <license type="expression">MS-RL</license>
10 <requireLicenseAcceptance>false</requireLicenseAcceptance>
11 <copyright>$copyright$</copyright>
12 <projectUrl>$projectUrl$</projectUrl>
13 <repository type="$repositorytype$" url="$repositoryurl$" commit="$repositorycommit$" />
14 </metadata>
15
16 <files>
17 <file src="$projectFolder$$id$.targets" target="build" />
18
19 <file src="netstandard2.0\$id$.dll" target="tools" />
20
21 <file src="x86\*.pdb" target="pdbs\x86" />
22 </files>
23</package>
diff --git a/src/ext/VisualStudio/wixext/WixToolset.VisualStudio.wixext.targets b/src/ext/VisualStudio/wixext/WixToolset.VisualStudio.wixext.targets
new file mode 100644
index 00000000..4542375f
--- /dev/null
+++ b/src/ext/VisualStudio/wixext/WixToolset.VisualStudio.wixext.targets
@@ -0,0 +1,8 @@
1<?xml version="1.0" encoding="utf-8"?>
2<!-- 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. -->
3
4<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
5 <ItemGroup>
6 <WixExtension Include="$(MSBuildThisFileDirectory)..\tools\WixToolset.VisualStudio.wixext.dll" />
7 </ItemGroup>
8</Project>
diff --git a/src/ext/VisualStudio/wixext/WixToolset.VisualStudio.wixext.v3.ncrunchproject b/src/ext/VisualStudio/wixext/WixToolset.VisualStudio.wixext.v3.ncrunchproject
new file mode 100644
index 00000000..56556a9f
--- /dev/null
+++ b/src/ext/VisualStudio/wixext/WixToolset.VisualStudio.wixext.v3.ncrunchproject
@@ -0,0 +1,7 @@
1<ProjectConfiguration>
2 <Settings>
3 <AdditionalFilesToIncludeForProject>
4 <Value>..\..\build\Debug\vs.wixlib</Value>
5 </AdditionalFilesToIncludeForProject>
6 </Settings>
7</ProjectConfiguration> \ No newline at end of file