aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Data.WindowsInstaller/Output.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Data.WindowsInstaller/Output.cs')
-rw-r--r--src/WixToolset.Data.WindowsInstaller/Output.cs337
1 files changed, 0 insertions, 337 deletions
diff --git a/src/WixToolset.Data.WindowsInstaller/Output.cs b/src/WixToolset.Data.WindowsInstaller/Output.cs
deleted file mode 100644
index 26772872..00000000
--- a/src/WixToolset.Data.WindowsInstaller/Output.cs
+++ /dev/null
@@ -1,337 +0,0 @@
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.Data
4{
5 using System;
6 using System.Collections.Generic;
7 using System.Globalization;
8 using System.IO;
9 using System.Linq;
10 using System.Xml;
11
12 /// <summary>
13 /// Output is generated by the linker.
14 /// </summary>
15 public sealed class Output
16 {
17 public const string XmlNamespaceUri = "http://wixtoolset.org/schemas/v4/wixout";
18 private static readonly Version CurrentVersion = new Version("4.0.0.0");
19
20 /// <summary>
21 /// Creates a new empty output object.
22 /// </summary>
23 /// <param name="sourceLineNumbers">The source line information for the output.</param>
24 public Output(SourceLineNumber sourceLineNumbers)
25 {
26 this.SourceLineNumbers = sourceLineNumbers;
27 this.SubStorages = new List<SubStorage>();
28 this.Tables = new TableIndexedCollection();
29 }
30
31 /// <summary>
32 /// Gets the type of the output.
33 /// </summary>
34 /// <value>Type of the output.</value>
35 public OutputType Type { get; set; }
36
37 /// <summary>
38 /// Gets or sets the codepage for this output.
39 /// </summary>
40 /// <value>Codepage of the output.</value>
41 public int Codepage { get; set; }
42
43 /// <summary>
44 /// Gets the source line information for this output.
45 /// </summary>
46 /// <value>The source line information for this output.</value>
47 public SourceLineNumber SourceLineNumbers { get; private set; }
48
49 /// <summary>
50 /// Gets the substorages in this output.
51 /// </summary>
52 /// <value>The substorages in this output.</value>
53 public ICollection<SubStorage> SubStorages { get; private set; }
54
55 /// <summary>
56 /// Gets the tables contained in this output.
57 /// </summary>
58 /// <value>Collection of tables.</value>
59 public TableIndexedCollection Tables { get; private set; }
60
61 /// <summary>
62 /// Gets the output type corresponding to a given output filename extension.
63 /// </summary>
64 /// <param name="extension">Case-insensitive output filename extension.</param>
65 /// <returns>Output type for the extension.</returns>
66 public static OutputType GetOutputType(string extension)
67 {
68 if (extension.Equals(".exe", StringComparison.OrdinalIgnoreCase))
69 {
70 return OutputType.Bundle;
71 }
72 if (extension.Equals(".msi", StringComparison.OrdinalIgnoreCase))
73 {
74 return OutputType.Product;
75 }
76 else if (extension.Equals(".msm", StringComparison.OrdinalIgnoreCase))
77 {
78 return OutputType.Module;
79 }
80 else if (extension.Equals(".msp", StringComparison.OrdinalIgnoreCase))
81 {
82 return OutputType.Patch;
83 }
84 else if (extension.Equals(".mst", StringComparison.OrdinalIgnoreCase))
85 {
86 return OutputType.Transform;
87 }
88 else if (extension.Equals(".pcp", StringComparison.OrdinalIgnoreCase))
89 {
90 return OutputType.PatchCreation;
91 }
92 else
93 {
94 return OutputType.Unknown;
95 }
96 }
97
98 /// <summary>
99 /// Gets the filename extension corresponding to a given output type.
100 /// </summary>
101 /// <param name="type">One of the WiX output types.</param>
102 /// <returns>Filename extension for the output type, for example ".msi".</returns>
103 public static string GetExtension(OutputType type)
104 {
105 switch (type)
106 {
107 case OutputType.Bundle:
108 return ".exe";
109 case OutputType.Product:
110 return ".msi";
111 case OutputType.Module:
112 return ".msm";
113 case OutputType.Patch:
114 return ".msp";
115 case OutputType.Transform:
116 return ".mst";
117 case OutputType.PatchCreation:
118 return ".pcp";
119 default:
120 return ".wix";
121 }
122 }
123
124 /// <summary>
125 /// Loads an output from a path on disk.
126 /// </summary>
127 /// <param name="path">Path to output file saved on disk.</param>
128 /// <param name="suppressVersionCheck">Suppresses wix.dll version mismatch check.</param>
129 /// <returns>Output object.</returns>
130 public static Output Load(string path, bool suppressVersionCheck)
131 {
132 using (FileStream stream = File.OpenRead(path))
133 using (FileStructure fs = FileStructure.Read(stream))
134 {
135 if (FileFormat.Wixout != fs.FileFormat)
136 {
137 throw new WixUnexpectedFileFormatException(path, FileFormat.Wixout, fs.FileFormat);
138 }
139
140 Uri uri = new Uri(Path.GetFullPath(path));
141 using (XmlReader reader = XmlReader.Create(fs.GetDataStream(), null, uri.AbsoluteUri))
142 {
143 try
144 {
145 reader.MoveToContent();
146 return Output.Read(reader, suppressVersionCheck);
147 }
148 catch (XmlException xe)
149 {
150 throw new WixCorruptFileException(path, fs.FileFormat, xe);
151 }
152 }
153 }
154 }
155
156 /// <summary>
157 /// Saves an output to a path on disk.
158 /// </summary>
159 /// <param name="path">Path to save output file to on disk.</param>
160 public void Save(string path)
161 {
162 Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(path)));
163
164 using (FileStream stream = File.Create(path))
165 using (FileStructure fs = FileStructure.Create(stream, FileFormat.Wixout, null))
166 using (XmlWriter writer = XmlWriter.Create(fs.GetDataStream()))
167 {
168 writer.WriteStartDocument();
169 this.Write(writer);
170 writer.WriteEndDocument();
171 }
172 }
173
174 /// <summary>
175 /// Processes an XmlReader and builds up the output object.
176 /// </summary>
177 /// <param name="reader">Reader to get data from.</param>
178 /// <param name="suppressVersionCheck">Suppresses wix.dll version mismatch check.</param>
179 /// <returns>The Output represented by the Xml.</returns>
180 internal static Output Read(XmlReader reader, bool suppressVersionCheck)
181 {
182 if (!reader.LocalName.Equals("wixOutput"))
183 {
184 throw new XmlException();
185 }
186
187 bool empty = reader.IsEmptyElement;
188 Output output = new Output(SourceLineNumber.CreateFromUri(reader.BaseURI));
189 Version version = null;
190
191 while (reader.MoveToNextAttribute())
192 {
193 switch (reader.LocalName)
194 {
195 case "codepage":
196 output.Codepage = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture.NumberFormat);
197 break;
198 case "type":
199 switch (reader.Value)
200 {
201 case "Bundle":
202 output.Type = OutputType.Bundle;
203 break;
204 case "Module":
205 output.Type = OutputType.Module;
206 break;
207 case "Patch":
208 output.Type = OutputType.Patch;
209 break;
210 case "PatchCreation":
211 output.Type = OutputType.PatchCreation;
212 break;
213 case "Product":
214 output.Type = OutputType.Product;
215 break;
216 case "Transform":
217 output.Type = OutputType.Transform;
218 break;
219 default:
220 throw new XmlException();
221 }
222 break;
223 case "version":
224 version = new Version(reader.Value);
225 break;
226 }
227 }
228
229 if (!suppressVersionCheck && null != version && !Output.CurrentVersion.Equals(version))
230 {
231 throw new WixException(WixDataErrors.VersionMismatch(SourceLineNumber.CreateFromUri(reader.BaseURI), "wixOutput", version.ToString(), Output.CurrentVersion.ToString()));
232 }
233
234 // loop through the rest of the xml building up the Output object
235 TableDefinitionCollection tableDefinitions = null;
236 List<Table> tables = new List<Table>();
237 if (!empty)
238 {
239 bool done = false;
240
241 // loop through all the fields in a row
242 while (!done && reader.Read())
243 {
244 switch (reader.NodeType)
245 {
246 case XmlNodeType.Element:
247 switch (reader.LocalName)
248 {
249 case "subStorage":
250 output.SubStorages.Add(SubStorage.Read(reader));
251 break;
252 case "table":
253 if (null == tableDefinitions)
254 {
255 throw new XmlException();
256 }
257 tables.Add(Table.Read(reader, tableDefinitions));
258 break;
259 case "tableDefinitions":
260 tableDefinitions = TableDefinitionCollection.Read(reader);
261 break;
262 default:
263 throw new XmlException();
264 }
265 break;
266 case XmlNodeType.EndElement:
267 done = true;
268 break;
269 }
270 }
271
272 if (!done)
273 {
274 throw new XmlException();
275 }
276 }
277
278 output.Tables = new TableIndexedCollection(tables);
279 return output;
280 }
281
282 /// <summary>
283 /// Ensure this output contains a particular table.
284 /// </summary>
285 /// <param name="tableDefinition">Definition of the table that should exist.</param>
286 /// <param name="section">Optional section to use for the table. If one is not provided, the entry section will be used.</param>
287 /// <returns>The table in this output.</returns>
288 public Table EnsureTable(TableDefinition tableDefinition)
289 {
290 if (!this.Tables.TryGetTable(tableDefinition.Name, out Table table))
291 {
292 table = new Table(tableDefinition);
293 this.Tables.Add(table);
294 }
295
296 return table;
297 }
298
299 /// <summary>
300 /// Persists an output in an XML format.
301 /// </summary>
302 /// <param name="writer">XmlWriter where the Output should persist itself as XML.</param>
303 internal void Write(XmlWriter writer)
304 {
305 writer.WriteStartElement("wixOutput", XmlNamespaceUri);
306
307 writer.WriteAttributeString("type", this.Type.ToString());
308
309 if (0 != this.Codepage)
310 {
311 writer.WriteAttributeString("codepage", this.Codepage.ToString(CultureInfo.InvariantCulture));
312 }
313
314 writer.WriteAttributeString("version", Output.CurrentVersion.ToString());
315
316 // Collect all the table definitions and write them.
317 TableDefinitionCollection tableDefinitions = new TableDefinitionCollection();
318 foreach (Table table in this.Tables)
319 {
320 tableDefinitions.Add(table.Definition);
321 }
322 tableDefinitions.Write(writer);
323
324 foreach (Table table in this.Tables.OrderBy(t => t.Name))
325 {
326 table.Write(writer);
327 }
328
329 foreach (SubStorage subStorage in this.SubStorages)
330 {
331 subStorage.Write(writer);
332 }
333
334 writer.WriteEndElement();
335 }
336 }
337}