aboutsummaryrefslogtreecommitdiff
path: root/src/dtf/WixToolset.Dtf.WindowsInstaller/SummaryInfo.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/dtf/WixToolset.Dtf.WindowsInstaller/SummaryInfo.cs612
1 files changed, 612 insertions, 0 deletions
diff --git a/src/dtf/WixToolset.Dtf.WindowsInstaller/SummaryInfo.cs b/src/dtf/WixToolset.Dtf.WindowsInstaller/SummaryInfo.cs
new file mode 100644
index 00000000..4dbff93f
--- /dev/null
+++ b/src/dtf/WixToolset.Dtf.WindowsInstaller/SummaryInfo.cs
@@ -0,0 +1,612 @@
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.Dtf.WindowsInstaller
4{
5 using System;
6 using System.IO;
7 using System.Text;
8 using System.Globalization;
9 using System.Runtime.InteropServices;
10
11 /// <summary>
12 /// Provides access to summary information of a Windows Installer database.
13 /// </summary>
14 public class SummaryInfo : InstallerHandle
15 {
16 internal const int MAX_PROPERTIES = 20;
17
18 /// <summary>
19 /// Gets a SummaryInfo object that can be used to examine, update, and add
20 /// properties to the summary information stream of a package or transform.
21 /// </summary>
22 /// <param name="packagePath">Path to the package (database) or transform</param>
23 /// <param name="enableWrite">True to reserve resources for writing summary information properties.</param>
24 /// <exception cref="FileNotFoundException">the package does not exist or could not be read</exception>
25 /// <exception cref="InstallerException">the package is an invalid format</exception>
26 /// <remarks><p>
27 /// The SummaryInfo object should be <see cref="InstallerHandle.Close"/>d after use.
28 /// It is best that the handle be closed manually as soon as it is no longer
29 /// needed, as leaving lots of unused handles open can degrade performance.
30 /// </p><p>
31 /// Win32 MSI API:
32 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msigetsummaryinformation.asp">MsiGetSummaryInformation</a>
33 /// </p></remarks>
34 public SummaryInfo(string packagePath, bool enableWrite)
35 : base((IntPtr) SummaryInfo.OpenSummaryInfo(packagePath, enableWrite), true)
36 {
37 }
38
39 internal SummaryInfo(IntPtr handle, bool ownsHandle) : base(handle, ownsHandle)
40 {
41 }
42
43 /// <summary>Gets or sets the Title summary information property.</summary>
44 /// <remarks><p>
45 /// The Title summary information property briefly describes the type of installer package. Phrases
46 /// such as "Installation Database" or "Transform" or "Patch" may be used for this property.
47 /// </p><p>
48 /// Win32 MSI APIs:
49 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfogetproperty.asp">MsiSummaryInfoGetProperty</a>,
50 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfosetproperty.asp">MsiSummaryInfoSetProperty</a>
51 /// </p></remarks>
52 public string Title
53 {
54 get { return this[2]; }
55 set { this[2] = value; }
56 }
57
58 /// <summary>Gets or sets the Subject summary information property.</summary>
59 /// <remarks><p>
60 /// The Subject summary information property conveys to a file browser the product that can be installed using
61 /// the logic and data in this installer database. For example, the value of the summary property for
62 /// Microsoft Office 97 would be "Microsoft Office 97 Professional". This value is typically set from the
63 /// installer property ProductName.
64 /// </p><p>
65 /// Win32 MSI APIs:
66 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfogetproperty.asp">MsiSummaryInfoGetProperty</a>,
67 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfosetproperty.asp">MsiSummaryInfoSetProperty</a>
68 /// </p></remarks>
69 public string Subject
70 {
71 get { return this[3]; }
72 set { this[3] = value; }
73 }
74
75 /// <summary>Gets or sets the Author summary information property.</summary>
76 /// <remarks><p>
77 /// The Author summary information property conveys to a file browser the manufacturer of the installation
78 /// database. This value is typically set from the installer property Manufacturer.
79 /// </p><p>
80 /// Win32 MSI APIs:
81 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfogetproperty.asp">MsiSummaryInfoGetProperty</a>,
82 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfosetproperty.asp">MsiSummaryInfoSetProperty</a>
83 /// </p></remarks>
84 public string Author
85 {
86 get { return this[4]; }
87 set { this[4] = value; }
88 }
89
90 /// <summary>Gets or sets the Keywords summary information property.</summary>
91 /// <remarks><p>
92 /// The Keywords summary information property is used by file browsers to hold keywords that permit the
93 /// database file to be found in a keyword search. The set of keywords typically includes "Installer" as
94 /// well as product-specific keywords, and may be localized.
95 /// </p><p>
96 /// Win32 MSI APIs:
97 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfogetproperty.asp">MsiSummaryInfoGetProperty</a>,
98 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfosetproperty.asp">MsiSummaryInfoSetProperty</a>
99 /// </p></remarks>
100 public string Keywords
101 {
102 get { return this[5]; }
103 set { this[5] = value; }
104 }
105
106 /// <summary>Gets or sets the Comments summary information property.</summary>
107 /// <remarks><p>
108 /// The Comments summary information property conveys the general purpose of the installer database. By convention,
109 /// the value for this summary property is set to the following:
110 /// </p><p>
111 /// "This installer database contains the logic and data required to install &lt;product name&gt;."
112 /// </p><p>
113 /// where &lt;product name&gt; is the name of the product being installed. In general the value for this summary
114 /// property only changes in the product name, nothing else.
115 /// </p><p>
116 /// Win32 MSI APIs:
117 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfogetproperty.asp">MsiSummaryInfoGetProperty</a>,
118 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfosetproperty.asp">MsiSummaryInfoSetProperty</a>
119 /// </p></remarks>
120 public string Comments
121 {
122 get { return this[6]; }
123 set { this[6] = value; }
124 }
125
126 /// <summary>Gets or sets the Template summary information property.</summary>
127 /// <remarks><p>
128 /// The Template summary information propery indicates the platform and language versions supported by the database.
129 /// </p><p>
130 /// The syntax of the Template Summary property information is:
131 /// [platform property][,platform property][,...];[language id][,language id][,...]
132 /// </p><p>
133 /// For example, the following are all valid values for the Template Summary property:
134 /// <list type="bullet">
135 /// <item>Intel;1033</item>
136 /// <item>Intel64;1033</item>
137 /// <item>;1033</item>
138 /// <item>;</item>
139 /// <item>Intel ;1033,2046</item>
140 /// <item>Intel64;1033,2046</item>
141 /// <item>Intel;0</item>
142 /// </list>
143 /// </p><p>
144 /// If this is a 64-bit Windows Installer, enter Intel64 in the Template summary information property. Note that an
145 /// installation package cannot have both the Intel and Intel64 properties set.
146 /// </p><p>
147 /// If the current platform does not match one of the platforms specified then the installer will not process the
148 /// package. Not specifying a platform implies that the package is platform-independent.
149 /// </p><p>
150 /// Entering 0 in the language ID field of the Template summary information property, or leaving this field empty,
151 /// indicates that the package is language neutral.
152 /// </p><p>
153 /// There are variations of this property depending on whether it is in a source installer database or a transform.
154 /// </p><p>
155 /// Source Installer Database - Only one language can be specified in a source installer database. Merge Modules are
156 /// the only packages that may have multiple languages. For more information, see Multiple Language Merge Modules.
157 /// </p><p>
158 /// Transform - In a transform file, only one language may be specified. The specified platform and language determine
159 /// whether a transform can be applied to a particular database. The platform property and the language property can
160 /// be left blank if no transform restriction relies on them to validate the transform.
161 /// </p><p>
162 /// This summary property is REQUIRED.
163 /// </p><p>
164 /// Win32 MSI APIs:
165 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfogetproperty.asp">MsiSummaryInfoGetProperty</a>,
166 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfosetproperty.asp">MsiSummaryInfoSetProperty</a>
167 /// </p></remarks>
168 public string Template
169 {
170 get { return this[7]; }
171 set { this[7] = value; }
172 }
173
174 /// <summary>Gets or sets the LastSavedBy summary information property.</summary>
175 /// <remarks><p>
176 /// The installer sets the Last Saved By summary information property to the value of the LogonUser property during
177 /// an administrative installation. The installer never uses this property and a user never needs to modify it.
178 /// Developers of a database editing tool may use this property to track the last person to modify the database.
179 /// This property should be left set to null in a final shipping database.
180 /// </p><p>
181 /// In a transform, this summary property contains the platform and language ID(s) that a database should have
182 /// after it has been transformed. The property specifies to what the Template should be set in the new database.
183 /// </p><p>
184 /// Win32 MSI APIs:
185 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfogetproperty.asp">MsiSummaryInfoGetProperty</a>,
186 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfosetproperty.asp">MsiSummaryInfoSetProperty</a>
187 /// </p></remarks>
188 public string LastSavedBy
189 {
190 get { return this[8]; }
191 set { this[8] = value; }
192 }
193
194 /// <summary>Gets or sets the RevisionNumber summary information property.</summary>
195 /// <remarks><p>
196 /// The Revision Number summary information property contains the package code for the installer package. The
197 /// package code is a unique identifier of the installer package.
198 /// </p><p>
199 /// The Revision Number summary information property of a patch package specifies the GUID patch code for
200 /// the patch. This is followed by a list of patch code GUIDs for obsolete patches that are removed when this
201 /// patch is applied. The patch codes are concatenated with no delimiters separating GUIDs in the list.
202 /// </p><p>
203 /// The Revision Number summary information property of a transform package lists the product code GUIDs
204 /// and version of the new and original products and the upgrade code GUID. The list is separated with
205 /// semicolons as follows.
206 /// </p><p>
207 /// Original-Product-Code Original-Product-Version ; New-Product Code New-Product-Version; Upgrade-Code
208 /// </p><p>
209 /// This summary property is REQUIRED.
210 /// </p><p>
211 /// Win32 MSI APIs:
212 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfogetproperty.asp">MsiSummaryInfoGetProperty</a>,
213 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfosetproperty.asp">MsiSummaryInfoSetProperty</a>
214 /// </p></remarks>
215 public string RevisionNumber
216 {
217 get { return this[9]; }
218 set { this[9] = value; }
219 }
220
221 /// <summary>Gets or sets the CreatingApp summary information property.</summary>
222 /// <remarks><p>
223 /// The CreatingApp summary information property conveys which application created the installer database.
224 /// In general the value for this summary property is the name of the software used to author this database.
225 /// </p><p>
226 /// Win32 MSI APIs:
227 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfogetproperty.asp">MsiSummaryInfoGetProperty</a>,
228 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfosetproperty.asp">MsiSummaryInfoSetProperty</a>
229 /// </p></remarks>
230 public string CreatingApp
231 {
232 get { return this[18]; }
233 set { this[18] = value; }
234 }
235
236 /// <summary>Gets or sets the LastPrintTime summary information property.</summary>
237 /// <remarks><p>
238 /// The LastPrintTime summary information property can be set to the date and time during an administrative
239 /// installation to record when the administrative image was created. For non-administrative installations
240 /// this property is the same as the CreateTime summary information property.
241 /// </p><p>
242 /// Win32 MSI APIs:
243 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfogetproperty.asp">MsiSummaryInfoGetProperty</a>,
244 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfosetproperty.asp">MsiSummaryInfoSetProperty</a>
245 /// </p></remarks>
246 public DateTime LastPrintTime
247 {
248 get { return (DateTime) this[11, typeof(DateTime)]; }
249 set { this[11, typeof(DateTime)] = value; }
250 }
251
252 /// <summary>Gets or sets the CreateTime summary information property.</summary>
253 /// <remarks><p>
254 /// The CreateTime summary information property conveys when the installer database was created.
255 /// </p><p>
256 /// Win32 MSI APIs:
257 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfogetproperty.asp">MsiSummaryInfoGetProperty</a>,
258 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfosetproperty.asp">MsiSummaryInfoSetProperty</a>
259 /// </p></remarks>
260 public DateTime CreateTime
261 {
262 get { return (DateTime) this[12, typeof(DateTime)]; }
263 set { this[12, typeof(DateTime)] = value; }
264 }
265
266 /// <summary>Gets or sets the LastSaveTime summary information property.</summary>
267 /// <remarks><p>
268 /// The LastSaveTime summary information property conveys when the last time the installer database was
269 /// modified. Each time a user changes an installation the value for this summary property is updated to
270 /// the current system time/date at the time the installer database was saved. Initially the value for
271 /// this summary property is set to null to indicate that no changes have yet been made.
272 /// </p><p>
273 /// Win32 MSI APIs:
274 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfogetproperty.asp">MsiSummaryInfoGetProperty</a>,
275 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfosetproperty.asp">MsiSummaryInfoSetProperty</a>
276 /// </p></remarks>
277 public DateTime LastSaveTime
278 {
279 get { return (DateTime) this[13, typeof(DateTime)]; }
280 set { this[13, typeof(DateTime)] = value; }
281 }
282
283 /// <summary>Gets or sets the CodePage summary information property.</summary>
284 /// <remarks><p>
285 /// The Codepage summary information property is the numeric value of the ANSI code page used for any
286 /// strings that are stored in the summary information. Note that this is not the same code page for
287 /// strings in the installation database. The Codepage summary information property is used to translate
288 /// the strings in the summary information into Unicode when calling the Unicode API functions. The
289 /// Codepage summary information property must be set before any string properties are set in the
290 /// summary information.
291 /// </p><p>
292 /// Win32 MSI APIs:
293 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfogetproperty.asp">MsiSummaryInfoGetProperty</a>,
294 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfosetproperty.asp">MsiSummaryInfoSetProperty</a>
295 /// </p></remarks>
296 public short CodePage
297 {
298 get { return (short) this[1, typeof(short)]; }
299 set { this[1, typeof(short)] = value; }
300 }
301
302 /// <summary>Gets or sets the PageCount summary information property.</summary>
303 /// <remarks><p>
304 /// For an installation package, the PageCount summary information property contains the minimum
305 /// installer version required. For Windows Installer version 1.0, this property must be set to the
306 /// integer 100. For 64-bit Windows Installer Packages, this property must be set to the integer 200.
307 /// </p><p>
308 /// For a transform package, the PageCount summary information property contains minimum installer
309 /// version required to process the transform. Set to the greater of the two PageCount summary information
310 /// property values belonging to the databases used to generate the transform.
311 /// </p><p>
312 /// The PageCount summary information property is set to null in patch packages.
313 /// </p><p>
314 /// This summary property is REQUIRED.
315 /// </p><p>
316 /// Win32 MSI APIs:
317 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfogetproperty.asp">MsiSummaryInfoGetProperty</a>,
318 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfosetproperty.asp">MsiSummaryInfoSetProperty</a>
319 /// </p></remarks>
320 public int PageCount
321 {
322 get { return (int) this[14, typeof(int)]; }
323 set { this[14, typeof(int)] = value; }
324 }
325
326 /// <summary>Gets or sets the WordCount summary information property.</summary>
327 /// <remarks><p>
328 /// The WordCount summary information property indicates the type of source file image. If this property is
329 /// not present, it defaults to 0. Note that this property is stored in place of the standard Count property.
330 /// </p><p>
331 /// This property is a bit field. New bits may be added in the future. At present the following bits are
332 /// available:
333 /// <list type="bullet">
334 /// <item>Bit 0: 0 = long file names, 1 = short file names</item>
335 /// <item>Bit 1: 0 = source is uncompressed, 1 = source is compressed</item>
336 /// <item>Bit 2: 0 = source is original media, 1 = source is administrative installation</item>
337 /// <item>[MSI 4.0] Bit 3: 0 = elevated privileges can be required to install, 1 = elevated privileges are not required to install</item>
338 /// </list>
339 /// </p><p>
340 /// These are combined to give the WordCount summary information property one of the following values
341 /// indicating a type of source file image:
342 /// <list type="bullet">
343 /// <item>0 - Original source using long file names. Matches tree in Directory table.</item>
344 /// <item>1 - Original source using short file names. Matches tree in Directory table.</item>
345 /// <item>2 - Compressed source files using long file names. Matches cabinets and files in the Media table.</item>
346 /// <item>3 - Compressed source files using short file names. Matches cabinets and files in the Media table.</item>
347 /// <item>4 - Administrative image using long file names. Matches tree in Directory table.</item>
348 /// <item>5 - Administrative image using short file names. Matches tree in Directory table.</item>
349 /// </list>
350 /// </p><p>
351 /// Note that if the package is marked as compressed (bit 1 is set), the installer only installs files
352 /// located at the root of the source. In this case, even files marked as uncompressed in the File table must
353 /// be located at the root to be installed. To specify a source image that has both a cabinet file (compressed
354 /// files) and uncompressed files that match the tree in the Directory table, mark the package as uncompressed
355 /// by leaving bit 1 unset (value=0) in the WordCount summary information property and set
356 /// <see cref="FileAttributes.Compressed"/> (value=16384) in the Attributes column of the File table
357 /// for each file in the cabinet.
358 /// </p><p>
359 /// For a patch package, the WordCount summary information property specifies the patch engine that was used
360 /// to create the patch files. The default value is 1 and indicates that MSPATCH was used to create the patch
361 /// A value of "2" means that the patch is using smaller, optimized, files available only with Windows Installer
362 /// version 1.2 or later. A patch with a WordCount of "2" fails immediately if used with a Windows Installer
363 /// version earlier than 1.2. A patch with a WordCount of "3" fails immediately if used with a Windows Installer
364 /// version earlier than 2.0.
365 /// </p><p>
366 /// This summary property is REQUIRED.
367 /// </p><p>
368 /// Win32 MSI APIs:
369 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfogetproperty.asp">MsiSummaryInfoGetProperty</a>,
370 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfosetproperty.asp">MsiSummaryInfoSetProperty</a>
371 /// </p></remarks>
372 public int WordCount
373 {
374 get { return (int) this[15, typeof(int)]; }
375 set { this[15, typeof(int)] = value; }
376 }
377
378 /// <summary>Gets or sets the CharacterCount summary information property.</summary>
379 /// <remarks><p>
380 /// The CharacterCount summary information property is only used in transforms. This part of the summary
381 /// information stream is divided into two 16-bit words. The upper word contains the transform validation
382 /// flags. The lower word contains the transform error condition flags.
383 /// </p><p>
384 /// Win32 MSI APIs:
385 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfogetproperty.asp">MsiSummaryInfoGetProperty</a>,
386 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfosetproperty.asp">MsiSummaryInfoSetProperty</a>
387 /// </p></remarks>
388 public int CharacterCount
389 {
390 get { return (int) this[16, typeof(int)]; }
391 set { this[16, typeof(int)] = value; }
392 }
393
394 /// <summary>Gets or sets the Security summary information property.</summary>
395 /// <remarks><p>
396 /// The Security summary information property conveys whether the package should be opened as read-only. The database
397 /// editing tool should not modify a read-only enforced database and should issue a warning at attempts to modify a
398 /// read-only recommended database. The following values of this property are applicable to Windows Installer files:
399 /// <list type="bullet">
400 /// <item>0 - no restriction</item>
401 /// <item>2 - read only recommended</item>
402 /// <item>4 - read only enforced</item>
403 /// </list>
404 /// </p><p>
405 /// This property should be set to read-only recommended (2) for an installation database and to read-only
406 /// enforced (4) for a transform or patch.
407 /// </p><p>
408 /// Win32 MSI APIs:
409 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfogetproperty.asp">MsiSummaryInfoGetProperty</a>,
410 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfosetproperty.asp">MsiSummaryInfoSetProperty</a>
411 /// </p></remarks>
412 public int Security
413 {
414 get { return (int) this[19, typeof(int)]; }
415 set { this[19, typeof(int)] = value; }
416 }
417
418 private object this[uint property, Type type]
419 {
420 get
421 {
422 uint dataType;
423 StringBuilder stringValue = new StringBuilder("");
424 uint bufSize = 0;
425 int intValue;
426 long timeValue = 0;
427
428 uint ret = RemotableNativeMethods.MsiSummaryInfoGetProperty(
429 (int) this.Handle,
430 property,
431 out dataType,
432 out intValue,
433 ref timeValue,
434 stringValue,
435 ref bufSize);
436 if (ret != 0 && dataType != (uint) VarEnum.VT_LPSTR)
437 {
438 throw InstallerException.ExceptionFromReturnCode(ret);
439 }
440
441 switch ((VarEnum) dataType)
442 {
443 case VarEnum.VT_EMPTY:
444 {
445 if (type == typeof(DateTime))
446 {
447 return DateTime.MinValue;
448 }
449 else if (type == typeof(string))
450 {
451 return String.Empty;
452 }
453 else if (type == typeof(short))
454 {
455 return (short) 0;
456 }
457 else
458 {
459 return (int) 0;
460 }
461 }
462
463 case VarEnum.VT_LPSTR:
464 {
465 if (ret == (uint) NativeMethods.Error.MORE_DATA)
466 {
467 stringValue.Capacity = (int) ++bufSize;
468 ret = RemotableNativeMethods.MsiSummaryInfoGetProperty(
469 (int) this.Handle,
470 property,
471 out dataType,
472 out intValue,
473 ref timeValue,
474 stringValue,
475 ref bufSize);
476 }
477 if (ret != 0)
478 {
479 throw InstallerException.ExceptionFromReturnCode(ret);
480 }
481 return stringValue.ToString();
482 }
483
484 case VarEnum.VT_I2:
485 case VarEnum.VT_I4:
486 {
487 if (type == typeof(string))
488 {
489 return intValue.ToString(CultureInfo.InvariantCulture);
490 }
491 else if (type == typeof(short))
492 {
493 return (short) intValue;
494 }
495 else
496 {
497 return intValue;
498 }
499 }
500
501 case VarEnum.VT_FILETIME:
502 {
503 if (type == typeof(string))
504 {
505 return DateTime.FromFileTime(timeValue).ToString(CultureInfo.InvariantCulture);
506 }
507 else
508 {
509 return DateTime.FromFileTime(timeValue);
510 }
511 }
512
513 default:
514 {
515 throw new InstallerException();
516 }
517 }
518 }
519
520 set
521 {
522 uint dataType = (uint) VarEnum.VT_NULL;
523 string stringValue = "";
524 int intValue = 0;
525 long timeValue = 0;
526
527 if (type == typeof(short))
528 {
529 dataType = (uint) VarEnum.VT_I2;
530 intValue = (int)(short) value; // Double cast because value is a *boxed* short.
531 }
532 else if (type == typeof(int))
533 {
534 dataType = (uint) VarEnum.VT_I4;
535 intValue = (int) value;
536 }
537 else if (type == typeof(string))
538 {
539 dataType = (uint) VarEnum.VT_LPSTR;
540 stringValue = (string) value;
541 }
542 else // (type == typeof(DateTime))
543 {
544 dataType = (uint) VarEnum.VT_FILETIME;
545 timeValue = ((DateTime) value).ToFileTime();
546 }
547
548 uint ret = NativeMethods.MsiSummaryInfoSetProperty(
549 (int) this.Handle,
550 property,
551 dataType,
552 intValue,
553 ref timeValue,
554 stringValue);
555 if (ret != 0)
556 {
557 throw InstallerException.ExceptionFromReturnCode(ret);
558 }
559 }
560 }
561
562 private string this[uint property]
563 {
564 get { return (string) this[property, typeof(string)]; }
565 set { this[property, typeof(string)] = value; }
566 }
567
568 /// <summary>
569 /// Formats and writes the previously stored properties into the standard summary information stream.
570 /// </summary>
571 /// <exception cref="InstallerException">The stream cannot be successfully written.</exception>
572 /// <remarks><p>
573 /// This method may only be called once after all the property values have been set. Properties may
574 /// still be read after the stream is written.
575 /// </p><p>
576 /// Win32 MSI API:
577 /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msisummaryinfopersist.asp">MsiSummaryInfoPersist</a>
578 /// </p></remarks>
579 public void Persist()
580 {
581 uint ret = NativeMethods.MsiSummaryInfoPersist((int) this.Handle);
582 if (ret != 0)
583 {
584 throw InstallerException.ExceptionFromReturnCode(ret);
585 }
586 }
587
588 private static int OpenSummaryInfo(string packagePath, bool enableWrite)
589 {
590 int summaryInfoHandle;
591 int maxProperties = !enableWrite ? 0 : SummaryInfo.MAX_PROPERTIES;
592 uint ret = RemotableNativeMethods.MsiGetSummaryInformation(
593 0,
594 packagePath,
595 (uint) maxProperties,
596 out summaryInfoHandle);
597 if (ret != 0)
598 {
599 if (ret == (uint) NativeMethods.Error.FILE_NOT_FOUND ||
600 ret == (uint) NativeMethods.Error.ACCESS_DENIED)
601 {
602 throw new FileNotFoundException(null, packagePath);
603 }
604 else
605 {
606 throw InstallerException.ExceptionFromReturnCode(ret);
607 }
608 }
609 return summaryInfoHandle;
610 }
611 }
612}