aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core.WindowsInstaller/Msi/Installer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/WixToolset.Core.WindowsInstaller/Msi/Installer.cs')
-rw-r--r--src/WixToolset.Core.WindowsInstaller/Msi/Installer.cs363
1 files changed, 363 insertions, 0 deletions
diff --git a/src/WixToolset.Core.WindowsInstaller/Msi/Installer.cs b/src/WixToolset.Core.WindowsInstaller/Msi/Installer.cs
new file mode 100644
index 00000000..f8bce602
--- /dev/null
+++ b/src/WixToolset.Core.WindowsInstaller/Msi/Installer.cs
@@ -0,0 +1,363 @@
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.Msi
4{
5 using System;
6 using System.Diagnostics;
7 using System.Text;
8 using WixToolset.Core.Native;
9
10 /// <summary>
11 /// Windows Installer message types.
12 /// </summary>
13 [Flags]
14 internal enum InstallMessage
15 {
16 /// <summary>
17 /// Premature termination, possibly fatal out of memory.
18 /// </summary>
19 FatalExit = 0x00000000,
20
21 /// <summary>
22 /// Formatted error message, [1] is message number in Error table.
23 /// </summary>
24 Error = 0x01000000,
25
26 /// <summary>
27 /// Formatted warning message, [1] is message number in Error table.
28 /// </summary>
29 Warning = 0x02000000,
30
31 /// <summary>
32 /// User request message, [1] is message number in Error table.
33 /// </summary>
34 User = 0x03000000,
35
36 /// <summary>
37 /// Informative message for log, not to be displayed.
38 /// </summary>
39 Info = 0x04000000,
40
41 /// <summary>
42 /// List of files in use that need to be replaced.
43 /// </summary>
44 FilesInUse = 0x05000000,
45
46 /// <summary>
47 /// Request to determine a valid source location.
48 /// </summary>
49 ResolveSource = 0x06000000,
50
51 /// <summary>
52 /// Insufficient disk space message.
53 /// </summary>
54 OutOfDiskSpace = 0x07000000,
55
56 /// <summary>
57 /// Progress: start of action, [1] action name, [2] description, [3] template for ACTIONDATA messages.
58 /// </summary>
59 ActionStart = 0x08000000,
60
61 /// <summary>
62 /// Action data. Record fields correspond to the template of ACTIONSTART message.
63 /// </summary>
64 ActionData = 0x09000000,
65
66 /// <summary>
67 /// Progress bar information. See the description of record fields below.
68 /// </summary>
69 Progress = 0x0A000000,
70
71 /// <summary>
72 /// To enable the Cancel button set [1] to 2 and [2] to 1. To disable the Cancel button set [1] to 2 and [2] to 0.
73 /// </summary>
74 CommonData = 0x0B000000,
75
76 /// <summary>
77 /// Sent prior to UI initialization, no string data.
78 /// </summary>
79 Initilize = 0x0C000000,
80
81 /// <summary>
82 /// Sent after UI termination, no string data.
83 /// </summary>
84 Terminate = 0x0D000000,
85
86 /// <summary>
87 /// Sent prior to display or authored dialog or wizard.
88 /// </summary>
89 ShowDialog = 0x0E000000
90 }
91
92 /// <summary>
93 /// Windows Installer log modes.
94 /// </summary>
95 [Flags]
96 internal enum InstallLogModes
97 {
98 /// <summary>
99 /// Premature termination of installation.
100 /// </summary>
101 FatalExit = (1 << ((int)InstallMessage.FatalExit >> 24)),
102
103 /// <summary>
104 /// The error messages are logged.
105 /// </summary>
106 Error = (1 << ((int)InstallMessage.Error >> 24)),
107
108 /// <summary>
109 /// The warning messages are logged.
110 /// </summary>
111 Warning = (1 << ((int)InstallMessage.Warning >> 24)),
112
113 /// <summary>
114 /// The user requests are logged.
115 /// </summary>
116 User = (1 << ((int)InstallMessage.User >> 24)),
117
118 /// <summary>
119 /// The status messages that are not displayed are logged.
120 /// </summary>
121 Info = (1 << ((int)InstallMessage.Info >> 24)),
122
123 /// <summary>
124 /// Request to determine a valid source location.
125 /// </summary>
126 ResolveSource = (1 << ((int)InstallMessage.ResolveSource >> 24)),
127
128 /// <summary>
129 /// The was insufficient disk space.
130 /// </summary>
131 OutOfDiskSpace = (1 << ((int)InstallMessage.OutOfDiskSpace >> 24)),
132
133 /// <summary>
134 /// The start of new installation actions are logged.
135 /// </summary>
136 ActionStart = (1 << ((int)InstallMessage.ActionStart >> 24)),
137
138 /// <summary>
139 /// The data record with the installation action is logged.
140 /// </summary>
141 ActionData = (1 << ((int)InstallMessage.ActionData >> 24)),
142
143 /// <summary>
144 /// The parameters for user-interface initialization are logged.
145 /// </summary>
146 CommonData = (1 << ((int)InstallMessage.CommonData >> 24)),
147
148 /// <summary>
149 /// Logs the property values at termination.
150 /// </summary>
151 PropertyDump = (1 << ((int)InstallMessage.Progress >> 24)),
152
153 /// <summary>
154 /// Sends large amounts of information to a log file not generally useful to users.
155 /// May be used for technical support.
156 /// </summary>
157 Verbose = (1 << ((int)InstallMessage.Initilize >> 24)),
158
159 /// <summary>
160 /// Sends extra debugging information, such as handle creation information, to the log file.
161 /// </summary>
162 ExtraDebug = (1 << ((int)InstallMessage.Terminate >> 24)),
163
164 /// <summary>
165 /// Progress bar information. This message includes information on units so far and total number of units.
166 /// See MsiProcessMessage for an explanation of the message format.
167 /// This message is only sent to an external user interface and is not logged.
168 /// </summary>
169 Progress = (1 << ((int)InstallMessage.Progress >> 24)),
170
171 /// <summary>
172 /// If this is not a quiet installation, then the basic UI has been initialized.
173 /// If this is a full UI installation, the full UI is not yet initialized.
174 /// This message is only sent to an external user interface and is not logged.
175 /// </summary>
176 Initialize = (1 << ((int)InstallMessage.Initilize >> 24)),
177
178 /// <summary>
179 /// If a full UI is being used, the full UI has ended.
180 /// If this is not a quiet installation, the basic UI has not yet ended.
181 /// This message is only sent to an external user interface and is not logged.
182 /// </summary>
183 Terminate = (1 << ((int)InstallMessage.Terminate >> 24)),
184
185 /// <summary>
186 /// Sent prior to display of the full UI dialog.
187 /// This message is only sent to an external user interface and is not logged.
188 /// </summary>
189 ShowDialog = (1 << ((int)InstallMessage.ShowDialog >> 24)),
190
191 /// <summary>
192 /// Files in use information. When this message is received, a FilesInUse Dialog should be displayed.
193 /// </summary>
194 FilesInUse = (1 << ((int)InstallMessage.FilesInUse >> 24))
195 }
196
197 /// <summary>
198 /// Windows Installer UI levels.
199 /// </summary>
200 [Flags]
201 internal enum InstallUILevels
202 {
203 /// <summary>
204 /// No change in the UI level. However, if phWnd is not Null, the parent window can change.
205 /// </summary>
206 NoChange = 0,
207
208 /// <summary>
209 /// The installer chooses an appropriate user interface level.
210 /// </summary>
211 Default = 1,
212
213 /// <summary>
214 /// Completely silent installation.
215 /// </summary>
216 None = 2,
217
218 /// <summary>
219 /// Simple progress and error handling.
220 /// </summary>
221 Basic = 3,
222
223 /// <summary>
224 /// Authored user interface with wizard dialog boxes suppressed.
225 /// </summary>
226 Reduced = 4,
227
228 /// <summary>
229 /// Authored user interface with wizards, progress, and errors.
230 /// </summary>
231 Full = 5,
232
233 /// <summary>
234 /// If combined with the Basic value, the installer shows simple progress dialog boxes but
235 /// does not display a Cancel button on the dialog. This prevents users from canceling the install.
236 /// Available with Windows Installer version 2.0.
237 /// </summary>
238 HideCancel = 0x20,
239
240 /// <summary>
241 /// If combined with the Basic value, the installer shows simple progress
242 /// dialog boxes but does not display any modal dialog boxes or error dialog boxes.
243 /// </summary>
244 ProgressOnly = 0x40,
245
246 /// <summary>
247 /// If combined with any above value, the installer displays a modal dialog
248 /// box at the end of a successful installation or if there has been an error.
249 /// No dialog box is displayed if the user cancels.
250 /// </summary>
251 EndDialog = 0x80,
252
253 /// <summary>
254 /// If this value is combined with the None value, the installer displays only the dialog
255 /// boxes used for source resolution. No other dialog boxes are shown. This value has no
256 /// effect if the UI level is not INSTALLUILEVEL_NONE. It is used with an external user
257 /// interface designed to handle all of the UI except for source resolution. In this case,
258 /// the installer handles source resolution. This value is only available with Windows Installer 2.0 and later.
259 /// </summary>
260 SourceResOnly = 0x100
261 }
262
263 /// <summary>
264 /// Represents the Windows Installer, provides wrappers to
265 /// create the top-level objects and access their methods.
266 /// </summary>
267 internal sealed class Installer
268 {
269 /// <summary>
270 /// Protect the constructor.
271 /// </summary>
272 private Installer()
273 {
274 }
275
276 /// <summary>
277 /// Takes the path to a file and returns a 128-bit hash of that file.
278 /// </summary>
279 /// <param name="filePath">Path to file that is to be hashed.</param>
280 /// <param name="options">The value in this column must be 0. This parameter is reserved for future use.</param>
281 /// <param name="hash">Int array that receives the returned file hash information.</param>
282 internal static void GetFileHash(string filePath, int options, out int[] hash)
283 {
284 MsiInterop.MSIFILEHASHINFO hashInterop = new MsiInterop.MSIFILEHASHINFO();
285 hashInterop.FileHashInfoSize = 20;
286
287 int error = MsiInterop.MsiGetFileHash(filePath, Convert.ToUInt32(options), hashInterop);
288 if (0 != error)
289 {
290 throw new MsiException(error);
291 }
292
293 Debug.Assert(20 == hashInterop.FileHashInfoSize);
294
295 hash = new int[4];
296 hash[0] = hashInterop.Data0;
297 hash[1] = hashInterop.Data1;
298 hash[2] = hashInterop.Data2;
299 hash[3] = hashInterop.Data3;
300 }
301
302 /// <summary>
303 /// Returns the version string and language string in the format that the installer
304 /// expects to find them in the database. If you just want version information, set
305 /// lpLangBuf and pcchLangBuf to zero. If you just want language information, set
306 /// lpVersionBuf and pcchVersionBuf to zero.
307 /// </summary>
308 /// <param name="filePath">Specifies the path to the file.</param>
309 /// <param name="version">Returns the file version. Set to 0 for language information only.</param>
310 /// <param name="language">Returns the file language. Set to 0 for version information only.</param>
311 internal static void GetFileVersion(string filePath, out string version, out string language)
312 {
313 int versionLength = 20;
314 int languageLength = 20;
315 StringBuilder versionBuffer = new StringBuilder(versionLength);
316 StringBuilder languageBuffer = new StringBuilder(languageLength);
317
318 int error = MsiInterop.MsiGetFileVersion(filePath, versionBuffer, ref versionLength, languageBuffer, ref languageLength);
319 if (234 == error)
320 {
321 versionBuffer.EnsureCapacity(++versionLength);
322 languageBuffer.EnsureCapacity(++languageLength);
323 error = MsiInterop.MsiGetFileVersion(filePath, versionBuffer, ref versionLength, languageBuffer, ref languageLength);
324 }
325 else if (1006 == error)
326 {
327 // file has no version or language, so no error
328 error = 0;
329 }
330
331 if (0 != error)
332 {
333 throw new MsiException(error);
334 }
335
336 version = versionBuffer.ToString();
337 language = languageBuffer.ToString();
338 }
339
340 /// <summary>
341 /// Enables an external user-interface handler.
342 /// </summary>
343 /// <param name="installUIHandler">Specifies a callback function.</param>
344 /// <param name="messageFilter">Specifies which messages to handle using the external message handler.</param>
345 /// <param name="context">Pointer to an application context that is passed to the callback function.</param>
346 /// <returns>The return value is the previously set external handler, or null if there was no previously set handler.</returns>
347 internal static InstallUIHandler SetExternalUI(InstallUIHandler installUIHandler, int messageFilter, IntPtr context)
348 {
349 return MsiInterop.MsiSetExternalUI(installUIHandler, messageFilter, context);
350 }
351
352 /// <summary>
353 /// Enables the installer's internal user interface.
354 /// </summary>
355 /// <param name="uiLevel">Specifies the level of complexity of the user interface.</param>
356 /// <param name="hwnd">Pointer to a window. This window becomes the owner of any user interface created.</param>
357 /// <returns>The previous user interface level is returned. If an invalid dwUILevel is passed, then INSTALLUILEVEL_NOCHANGE is returned.</returns>
358 internal static int SetInternalUI(int uiLevel, ref IntPtr hwnd)
359 {
360 return MsiInterop.MsiSetInternalUI(uiLevel, ref hwnd);
361 }
362 }
363}