aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wixext/PSCompiler.cs290
-rw-r--r--src/wixext/PSExtensionData.cs34
-rw-r--r--src/wixext/WixPSExtension.csproj43
-rw-r--r--src/wixext/messages.xml20
-rw-r--r--src/wixext/ps.xsd191
-rw-r--r--src/wixlib/PSExtension.wixproj19
-rw-r--r--src/wixlib/PSExtension.wxs12
7 files changed, 609 insertions, 0 deletions
diff --git a/src/wixext/PSCompiler.cs b/src/wixext/PSCompiler.cs
new file mode 100644
index 00000000..61eb287c
--- /dev/null
+++ b/src/wixext/PSCompiler.cs
@@ -0,0 +1,290 @@
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.Extensions
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.Rows;
11 using WixToolset.Extensibility;
12
13 /// <summary>
14 /// The compiler for the WiX Toolset Internet Information Services Extension.
15 /// </summary>
16 public sealed class PSCompiler : CompilerExtension
17 {
18 private const string KeyFormat = @"SOFTWARE\Microsoft\PowerShell\{0}\PowerShellSnapIns\{1}";
19 private const string VarPrefix = "PSVersionMajor";
20
21 /// <summary>
22 /// Instantiate a new PSCompiler.
23 /// </summary>
24 public PSCompiler()
25 {
26 this.Namespace = "http://wixtoolset.org/schemas/v4/wxs/powershell";
27 }
28
29 /// <summary>
30 /// Processes an element for the Compiler.
31 /// </summary>
32 /// <param name="sourceLineNumbers">Source line number for the parent element.</param>
33 /// <param name="parentElement">Parent element of element to process.</param>
34 /// <param name="element">Element to process.</param>
35 /// <param name="contextValues">Extra information about the context in which this element is being parsed.</param>
36 public override void ParseElement(XElement parentElement, XElement element, IDictionary<string, string> context)
37 {
38 switch (parentElement.Name.LocalName)
39 {
40 case "File":
41 string fileId = context["FileId"];
42 string componentId = context["ComponentId"];
43
44 switch (element.Name.LocalName)
45 {
46 case "FormatsFile":
47 this.ParseExtensionsFile(element, "Formats", fileId, componentId);
48 break;
49
50 case "SnapIn":
51 this.ParseSnapInElement(element, fileId, componentId);
52 break;
53
54 case "TypesFile":
55 this.ParseExtensionsFile(element, "Types", fileId, componentId);
56 break;
57
58 default:
59 this.Core.UnexpectedElement(parentElement, element);
60 break;
61 }
62 break;
63
64 default:
65 this.Core.UnexpectedElement(parentElement, element);
66 break;
67 }
68 }
69
70 /// <summary>
71 /// Parses a SnapIn element.
72 /// </summary>
73 /// <param name="node">Element to parse.</param>
74 /// <param name="fileId">Identifier for parent file.</param>
75 /// <param name="componentId">Identifier for parent component.</param>
76 private void ParseSnapInElement(XElement node, string fileId, string componentId)
77 {
78 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
79 string id = null;
80 string assemblyName = null;
81 string customSnapInType = null;
82 string description = null;
83 string descriptionIndirect = null;
84 Version requiredPowerShellVersion = CompilerConstants.IllegalVersion;
85 string vendor = null;
86 string vendorIndirect = null;
87 string version = null;
88
89 foreach (XAttribute attrib in node.Attributes())
90 {
91 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
92 {
93 switch (attrib.Name.LocalName)
94 {
95 case "Id":
96 id = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
97 break;
98
99 case "CustomSnapInType":
100 customSnapInType = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
101 break;
102
103 case "Description":
104 description = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
105 break;
106
107 case "DescriptionIndirect":
108 descriptionIndirect = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
109 break;
110
111 case "RequiredPowerShellVersion":
112 string ver = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
113 requiredPowerShellVersion = new Version(ver);
114 break;
115
116 case "Vendor":
117 vendor = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
118 break;
119
120 case "VendorIndirect":
121 vendorIndirect = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
122 break;
123
124 case "Version":
125 version = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib);
126 break;
127
128 default:
129 this.Core.UnexpectedAttribute(node, attrib);
130 break;
131 }
132 }
133 else
134 {
135 this.Core.ParseExtensionAttribute(node, attrib);
136 }
137 }
138
139 if (null == id)
140 {
141 this.Core.OnMessage(WixErrors.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id"));
142 }
143
144 // Default to require PowerShell 1.0.
145 if (CompilerConstants.IllegalVersion == requiredPowerShellVersion)
146 {
147 requiredPowerShellVersion = new Version(1, 0);
148 }
149
150 // If the snap-in version isn't explicitly specified, get it
151 // from the assembly version at bind time.
152 if (null == version)
153 {
154 version = String.Format("!(bind.assemblyVersion.{0})", fileId);
155 }
156
157 foreach (XElement child in node.Elements())
158 {
159 if (this.Namespace == child.Name.Namespace)
160 {
161 switch (child.Name.LocalName)
162 {
163 case "FormatsFile":
164 this.ParseExtensionsFile(child, "Formats", id, componentId);
165 break;
166 case "TypesFile":
167 this.ParseExtensionsFile(child, "Types", id, componentId);
168 break;
169 default:
170 this.Core.UnexpectedElement(node, child);
171 break;
172 }
173 }
174 else
175 {
176 this.Core.ParseExtensionElement(node, child);
177 }
178 }
179
180 // Get the major part of the required PowerShell version which is
181 // needed for the registry key, and put that into a WiX variable
182 // for use in Formats and Types files. PowerShell v2 still uses 1.
183 int major = (2 == requiredPowerShellVersion.Major) ? 1 : requiredPowerShellVersion.Major;
184
185 WixVariableRow wixVariableRow = (WixVariableRow)this.Core.CreateRow(sourceLineNumbers, "WixVariable");
186 wixVariableRow.Id = String.Format(CultureInfo.InvariantCulture, "{0}_{1}", VarPrefix, id);
187 wixVariableRow.Value = major.ToString(CultureInfo.InvariantCulture);
188 wixVariableRow.Overridable = false;
189
190 int registryRoot = 2; // HKLM
191 string registryKey = String.Format(CultureInfo.InvariantCulture, KeyFormat, major, id);
192
193 this.Core.CreateRegistryRow(sourceLineNumbers, registryRoot, registryKey, "ApplicationBase", String.Format(CultureInfo.InvariantCulture, "[${0}]", componentId), componentId, false);
194
195 // set the assembly name automatically when binding.
196 // processorArchitecture is not handled correctly by PowerShell v1.0
197 // so format the assembly name explicitly.
198 assemblyName = String.Format(CultureInfo.InvariantCulture, "!(bind.assemblyName.{0}), Version=!(bind.assemblyVersion.{0}), Culture=!(bind.assemblyCulture.{0}), PublicKeyToken=!(bind.assemblyPublicKeyToken.{0})", fileId);
199 this.Core.CreateRegistryRow(sourceLineNumbers, registryRoot, registryKey, "AssemblyName", assemblyName, componentId, false);
200
201 if (null != customSnapInType)
202 {
203 this.Core.CreateRegistryRow(sourceLineNumbers, registryRoot, registryKey, "CustomPSSnapInType", customSnapInType, componentId, false);
204 }
205
206 if (null != description)
207 {
208 this.Core.CreateRegistryRow(sourceLineNumbers, registryRoot, registryKey, "Description", description, componentId, false);
209 }
210
211 if (null != descriptionIndirect)
212 {
213 this.Core.CreateRegistryRow(sourceLineNumbers, registryRoot, registryKey, "DescriptionIndirect", descriptionIndirect, componentId, false);
214 }
215
216 this.Core.CreateRegistryRow(sourceLineNumbers, registryRoot, registryKey, "ModuleName", String.Format(CultureInfo.InvariantCulture, "[#{0}]", fileId), componentId, false);
217
218 this.Core.CreateRegistryRow(sourceLineNumbers, registryRoot, registryKey, "PowerShellVersion", requiredPowerShellVersion.ToString(2), componentId, false);
219
220 if (null != vendor)
221 {
222 this.Core.CreateRegistryRow(sourceLineNumbers, registryRoot, registryKey, "Vendor", vendor, componentId, false);
223 }
224
225 if (null != vendorIndirect)
226 {
227 this.Core.CreateRegistryRow(sourceLineNumbers, registryRoot, registryKey, "VendorIndirect", vendorIndirect, componentId, false);
228 }
229
230 if (null != version)
231 {
232 this.Core.CreateRegistryRow(sourceLineNumbers, registryRoot, registryKey, "Version", version, componentId, false);
233 }
234 }
235
236 /// <summary>
237 /// Parses a FormatsFile and TypesFile element.
238 /// </summary>
239 /// <param name="node">Element to parse.</param>
240 /// <param name="valueName">Registry value name.</param>
241 /// <param name="id">Idendifier for parent file or snap-in.</param>
242 /// <param name="componentId">Identifier for parent component.</param>
243 private void ParseExtensionsFile(XElement node, string valueName, string id, string componentId)
244 {
245 SourceLineNumber sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
246 string fileId = null;
247 string snapIn = null;
248
249 foreach (XAttribute attrib in node.Attributes())
250 {
251 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
252 {
253 switch (attrib.Name.LocalName)
254 {
255 case "FileId":
256 fileId = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
257 snapIn = id;
258 break;
259
260 case "SnapIn":
261 fileId = id;
262 snapIn = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
263 break;
264
265 default:
266 this.Core.UnexpectedAttribute(node, attrib);
267 break;
268 }
269 }
270 else
271 {
272 this.Core.ParseExtensionAttribute(node, attrib);
273 }
274 }
275
276 if (null == fileId && null == snapIn)
277 {
278 this.Core.OnMessage(PSErrors.NeitherIdSpecified(sourceLineNumbers, valueName));
279 }
280
281 this.Core.ParseForExtensionElements(node);
282
283 int registryRoot = 2; // HKLM
284 string registryKey = String.Format(CultureInfo.InvariantCulture, KeyFormat, String.Format(CultureInfo.InvariantCulture, "!(wix.{0}_{1})", VarPrefix, snapIn), snapIn);
285
286 this.Core.CreateSimpleReference(sourceLineNumbers, "File", fileId);
287 this.Core.CreateRegistryRow(sourceLineNumbers, registryRoot, registryKey, valueName, String.Format(CultureInfo.InvariantCulture, "[~][#{0}]", fileId), componentId, false);
288 }
289 }
290}
diff --git a/src/wixext/PSExtensionData.cs b/src/wixext/PSExtensionData.cs
new file mode 100644
index 00000000..578bda91
--- /dev/null
+++ b/src/wixext/PSExtensionData.cs
@@ -0,0 +1,34 @@
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.Extensions
4{
5 using System;
6 using System.Reflection;
7 using WixToolset.Data;
8 using WixToolset.Extensibility;
9
10 /// <summary>
11 /// The WiX Toolset PowerShell Extension.
12 /// </summary>
13 public sealed class PSExtensionData : ExtensionData
14 {
15 /// <summary>
16 /// Gets the library associated with this extension.
17 /// </summary>
18 /// <param name="tableDefinitions">The table definitions to use while loading the library.</param>
19 /// <returns>The loaded library.</returns>
20 public override Library GetLibrary(TableDefinitionCollection tableDefinitions)
21 {
22 return PSExtensionData.GetExtensionLibrary(tableDefinitions);
23 }
24
25 /// <summary>
26 /// Internal mechanism to access the extension's library.
27 /// </summary>
28 /// <returns>Extension's library.</returns>
29 internal static Library GetExtensionLibrary(TableDefinitionCollection tableDefinitions)
30 {
31 return ExtensionData.LoadLibraryHelper(Assembly.GetExecutingAssembly(), "WixToolset.Extensions.Data.ps.wixlib", tableDefinitions);
32 }
33 }
34}
diff --git a/src/wixext/WixPSExtension.csproj b/src/wixext/WixPSExtension.csproj
new file mode 100644
index 00000000..f9349ef1
--- /dev/null
+++ b/src/wixext/WixPSExtension.csproj
@@ -0,0 +1,43 @@
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
5<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
6 <PropertyGroup>
7 <ProjectGuid>{6F1482DF-1598-4D88-BDAA-B9D0E0242139}</ProjectGuid>
8 <AssemblyName>WixPSExtension</AssemblyName>
9 <OutputType>Library</OutputType>
10 <RootNamespace>WixToolset.Extensions</RootNamespace>
11 </PropertyGroup>
12 <ItemGroup>
13 <Compile Include="AssemblyInfo.cs" />
14 <Compile Include="PSCompiler.cs" />
15 <Compile Include="PSExtensionData.cs" />
16 <MsgGenSource Include="Data\messages.xml">
17 <ResourcesLogicalName>$(RootNamespace).Data.Messages.resources</ResourcesLogicalName>
18 </MsgGenSource>
19 <EmbeddedFlattenedResource Include="Xsd\ps.xsd">
20 <LogicalName>$(RootNamespace).Xsd.ps.xsd</LogicalName>
21 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
22 </EmbeddedFlattenedResource>
23 <XsdGenSource Include="Xsd\ps.xsd">
24 <CommonNamespace>WixToolset.Data.Serialize</CommonNamespace>
25 <Namespace>WixToolset.Extensions.Serialize.PS</Namespace>
26 </XsdGenSource>
27 <EmbeddedResource Include="$(OutputPath)\ps.wixlib">
28 <Link>Data\ps.wixlib</Link>
29 </EmbeddedResource>
30 </ItemGroup>
31 <ItemGroup>
32 <Reference Include="System" />
33 <Reference Include="System.Xml" />
34 <ProjectReference Include="..\..\..\libs\WixToolset.Data\WixToolset.Data.csproj" />
35 <ProjectReference Include="..\..\..\libs\WixToolset.Extensibility\WixToolset.Extensibility.csproj" />
36 <ProjectReference Include="..\..\..\tools\wix\Wix.csproj" />
37 <ProjectReference Include="..\wixlib\PSExtension.wixproj">
38 <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
39 </ProjectReference>
40 <Reference Include="System.Xml.Linq" />
41 </ItemGroup>
42 <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), wix.proj))\tools\WixBuild.targets" />
43</Project>
diff --git a/src/wixext/messages.xml b/src/wixext/messages.xml
new file mode 100644
index 00000000..ef715640
--- /dev/null
+++ b/src/wixext/messages.xml
@@ -0,0 +1,20 @@
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
5<Messages Namespace="WixToolset.Extensions" Resources="Data.Messages" xmlns="http://schemas.microsoft.com/genmsgs/2004/07/messages">
6 <Class Name="PSErrors" ContainerName="PSErrorEventArgs" BaseContainerName="WixErrorEventArgs">
7 <Message Id="NeitherIdSpecified" Number="5301">
8 <Instance>Either the {0}/@FileId attribute must be specified if nested under a SnapIn element, or the {0}/@SnapIn attribute must be specified if nested under under a File element.
9 <Parameter Type="System.String" Name="element" />
10 </Instance>
11 </Message>
12 </Class>
13 <Class Name="PSWarnings" ContainerName="PSWarningEventArgs" BaseContainerName="WixWarningEventArgs">
14 <Message Id="DeprecatedAssemblyNameAttribute" Number="5350">
15 <Instance>The SnapIn/@AssemblyName attribute is deprecated. It is assigned automatically.</Instance>
16 </Message>
17 </Class>
18 <Class Name="PSVerboses" ContainerName="PSVerboseEventArgs" BaseContainerName="WixVerboseEventArgs">
19 </Class>
20</Messages>
diff --git a/src/wixext/ps.xsd b/src/wixext/ps.xsd
new file mode 100644
index 00000000..0c4c2bef
--- /dev/null
+++ b/src/wixext/ps.xsd
@@ -0,0 +1,191 @@
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
5<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
6 xmlns:xse=" http://wixtoolset.org/schemas/XmlSchemaExtension"
7 xmlns:html="http://www.w3.org/1999/xhtml"
8 xmlns:wix="http://wixtoolset.org/schemas/v4/wxs"
9 targetNamespace="http://wixtoolset.org/schemas/v4/wxs/powershell"
10 xmlns="http://wixtoolset.org/schemas/v4/wxs/powershell">
11 <xs:annotation>
12 <xs:documentation>
13 The source code schema for the WiX Toolset PowerShell Extension.
14 </xs:documentation>
15 </xs:annotation>
16 <xs:import namespace="http://wixtoolset.org/schemas/v4/wxs" />
17 <xs:element name="FormatsFile">
18 <xs:annotation>
19 <xs:documentation>
20 Identifies the parent File as a formats XML file for the referenced PowerShell snap-in.
21 </xs:documentation>
22 <xs:appinfo>
23 <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="File" />
24 <xse:remarks>
25 A formats XML file that defines output formats for objects on the pipeline.
26 </xse:remarks>
27 </xs:appinfo>
28 </xs:annotation>
29 <xs:complexType>
30 <xs:attribute name="FileId" type="xs:string">
31 <xs:annotation>
32 <xs:documentation>
33 Reference to the formats File ID. This is required when nested under the SnapIn element.
34 </xs:documentation>
35 </xs:annotation>
36 </xs:attribute>
37 <xs:attribute name="SnapIn" type="xs:string">
38 <xs:annotation>
39 <xs:documentation>
40 Reference to the PowerShell snap-in ID for which this formats file is associated. This is required when nested under the File element.
41 </xs:documentation>
42 </xs:annotation>
43 </xs:attribute>
44 </xs:complexType>
45 </xs:element>
46 <xs:element name="TypesFile">
47 <xs:annotation>
48 <xs:documentation>
49 Identifies the parent File as a types XML file for the referenced PowerShell snap-in.
50 </xs:documentation>
51 <xs:appinfo>
52 <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="File" />
53 <xse:remarks>
54 A types XML file used by the extensible type system.
55 </xse:remarks>
56 </xs:appinfo>
57 </xs:annotation>
58 <xs:complexType>
59 <xs:attribute name="FileId" type="xs:string">
60 <xs:annotation>
61 <xs:documentation>
62 Reference to the types File ID. This is required when nested under the SnapIn element.
63 </xs:documentation>
64 </xs:annotation>
65 </xs:attribute>
66 <xs:attribute name="SnapIn" type="xs:string">
67 <xs:annotation>
68 <xs:documentation>
69 Reference to the PowerShell snap-in ID for which this types file is associated. This is required when nested under the File element.
70 </xs:documentation>
71 </xs:annotation>
72 </xs:attribute>
73 </xs:complexType>
74 </xs:element>
75 <xs:element name="SnapIn">
76 <xs:annotation>
77 <xs:documentation>
78 Identifies the parent File as a PowerShell snap-in to be registered on the system.
79 </xs:documentation>
80 <xs:appinfo>
81 <xse:parent namespace="http://wixtoolset.org/schemas/v4/wxs" ref="File" />
82 <xse:remarks>
83 <html:a href="http://www.microsoft.com/powershell">PowerShell</html:a> snap-ins
84 allow developers to extend the functionality of of the PowerShell engine.
85 Add this element to identify the parent File as a PowerShell snap-in that will
86 get registered on the system.
87 </xse:remarks>
88 </xs:appinfo>
89 </xs:annotation>
90 <xs:complexType>
91 <xs:choice minOccurs="0" maxOccurs="unbounded">
92 <xs:element ref="FormatsFile" />
93 <xs:element ref="TypesFile" />
94 </xs:choice>
95 <xs:attribute name="Id" type="xs:string" use="required">
96 <xs:annotation>
97 <xs:documentation>
98 The identifier for this PowerShell snap-in.
99 </xs:documentation>
100 </xs:annotation>
101 </xs:attribute>
102 <xs:attribute name="AssemblyName" type="xs:string">
103 <xs:annotation>
104 <xs:documentation>
105 The fully-qualified name of the assembly.
106 </xs:documentation>
107 <xs:appinfo>
108 <xse:deprecated />
109 </xs:appinfo>
110 </xs:annotation>
111 </xs:attribute>
112 <xs:attribute name="CustomSnapInType" type="xs:string">
113 <xs:annotation>
114 <xs:documentation>
115 The full type name of a class that is used to register a list of cmdlets and providers.
116 </xs:documentation>
117 </xs:annotation>
118 </xs:attribute>
119 <xs:attribute name="Description" type="xs:string">
120 <xs:annotation>
121 <xs:documentation>
122 A brief description of the snap-in.
123 </xs:documentation>
124 </xs:annotation>
125 </xs:attribute>
126 <xs:attribute name="DescriptionIndirect" type="EmbeddedResource">
127 <xs:annotation>
128 <xs:documentation>
129 An embedded resource that contains a brief description of the snap-in.
130 This resource must be embedded in the current snap-in assembly.
131 </xs:documentation>
132 </xs:annotation>
133 </xs:attribute>
134 <xs:attribute name="RequiredPowerShellVersion" type="VersionType">
135 <xs:annotation>
136 <xs:documentation>
137 The required version of PowerShell that must be installed and is associated with the
138 snap-in registration. The default value is "1.0".
139 </xs:documentation>
140 </xs:annotation>
141 </xs:attribute>
142 <xs:attribute name="Vendor" type="xs:string">
143 <xs:annotation>
144 <xs:documentation>
145 The name of the snap-in vendor.
146 </xs:documentation>
147 </xs:annotation>
148 </xs:attribute>
149 <xs:attribute name="VendorIndirect" type="EmbeddedResource">
150 <xs:annotation>
151 <xs:documentation>
152 An embedded resource that contains the name of the snap-in vendor.
153 This resource must be embedded in the current snap-in assembly.
154 </xs:documentation>
155 </xs:annotation>
156 </xs:attribute>
157 <xs:attribute name="Version" type="VersionType">
158 <xs:annotation>
159 <xs:documentation>
160 The version of the snapin. If not specified, this is taken from the assembly name.
161 </xs:documentation>
162 </xs:annotation>
163 </xs:attribute>
164 </xs:complexType>
165 </xs:element>
166 <xs:simpleType name="EmbeddedResource">
167 <xs:annotation>
168 <xs:documentation>
169 <html:p>
170 Values should be in the format <html:i>ResourceName,StringName</html:i>, where <html:i>ResourceName</html:i>
171 is the name of the embedded resource in your assembly sans the ".resources" extension, and <html:i>StringName</html:i>
172 is the name of the string resource in the embedded resource.
173 </html:p>
174 <html:p>
175 Example: UtilityMshSnapInResources,Description
176 </html:p>
177 </xs:documentation>
178 </xs:annotation>
179 <xs:restriction base="xs:string" />
180 </xs:simpleType>
181 <xs:simpleType name="VersionType">
182 <xs:annotation>
183 <xs:documentation>
184 Values of this type will look like: "x", "x.x", "x.x.x", or "x.x.x.x" where x is an integer from 0 to 65534.
185 </xs:documentation>
186 </xs:annotation>
187 <xs:restriction base="xs:string">
188 <xs:pattern value="\d{1,5}(\.\d{1,5}){0,3}"/>
189 </xs:restriction>
190 </xs:simpleType>
191</xs:schema>
diff --git a/src/wixlib/PSExtension.wixproj b/src/wixlib/PSExtension.wixproj
new file mode 100644
index 00000000..da2b6463
--- /dev/null
+++ b/src/wixlib/PSExtension.wixproj
@@ -0,0 +1,19 @@
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
5<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
6 <PropertyGroup>
7 <ProjectGuid>{9d4ccdfc-840c-4d4e-a9b0-3d6015480645}</ProjectGuid>
8 <OutputName>ps</OutputName>
9 <OutputType>Library</OutputType>
10 <BindFiles>true</BindFiles>
11 <Pedantic>true</Pedantic>
12 </PropertyGroup>
13
14 <ItemGroup>
15 <Compile Include="PSExtension.wxs" />
16 </ItemGroup>
17
18 <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), wix.proj))\tools\WixBuild.targets" />
19</Project>
diff --git a/src/wixlib/PSExtension.wxs b/src/wixlib/PSExtension.wxs
new file mode 100644
index 00000000..a1f16ee6
--- /dev/null
+++ b/src/wixlib/PSExtension.wxs
@@ -0,0 +1,12 @@
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
5<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
6 <!-- Gets the version of PowerShell installed. v1 and v2 share this key. -->
7 <Fragment>
8 <Property Id="POWERSHELLVERSION" Secure="yes">
9 <RegistrySearch Id="PowerShellVersionSearch" Root="HKLM" Key="SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine" Name="PowerShellVersion" Type="raw" />
10 </Property>
11 </Fragment>
12</Wix>