main
cs 139 lines 6.24 KB
Raw
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
3 namespace WixToolset.Core.Native.Msi
4 {
5 using System;
6 using System.Diagnostics;
7 using System.Runtime.InteropServices;
8 using System.Text;
9
10 /// <summary>
11 /// A callback function that the installer calls for progress notification and error messages.
12 /// </summary>
13 /// <param name="context">Pointer to an application context.
14 /// This parameter can be used for error checking.</param>
15 /// <param name="messageType">Specifies a combination of one message box style,
16 /// one message box icon type, one default button, and one installation message type.</param>
17 /// <param name="message">Specifies the message text.</param>
18 /// <returns>-1 for an error, 0 if no action was taken, 1 if OK, 3 to abort.</returns>
19 public delegate int InstallUIHandler(IntPtr context, uint messageType, [MarshalAs(UnmanagedType.LPWStr)] string message);
20
21 /// <summary>
22 /// Represents the Windows Installer, provides wrappers to
23 /// create the top-level objects and access their methods.
24 /// </summary>
25 public static class Installer
26 {
27 /// <summary>
28 /// Extacts the patch metadata as XML.
29 /// </summary>
30 /// <param name="path">Path to patch.</param>
31 /// <returns>String XML.</returns>
32 public static string ExtractPatchXml(string path)
33 {
34 var buffer = new StringBuilder(65535);
35 var size = buffer.Capacity;
36
37 var error = MsiInterop.MsiExtractPatchXMLData(path, 0, buffer, ref size);
38 if (234 == error)
39 {
40 buffer.EnsureCapacity(++size);
41 error = MsiInterop.MsiExtractPatchXMLData(path, 0, buffer, ref size);
42 }
43
44 if (error != 0)
45 {
46 throw new MsiException(error);
47 }
48
49 return buffer.ToString();
50 }
51
52 /// <summary>
53 /// Takes the path to a file and returns a 128-bit hash of that file.
54 /// </summary>
55 /// <param name="filePath">Path to file that is to be hashed.</param>
56 /// <param name="options">The value in this column must be 0. This parameter is reserved for future use.</param>
57 /// <param name="hash">Int array that receives the returned file hash information.</param>
58 public static void GetFileHash(string filePath, int options, out int[] hash)
59 {
60 var hashInterop = new MSIFILEHASHINFO();
61 hashInterop.FileHashInfoSize = 20;
62
63 var error = MsiInterop.MsiGetFileHash(filePath, Convert.ToUInt32(options), hashInterop);
64 if (0 != error)
65 {
66 throw new MsiException(error);
67 }
68
69 Debug.Assert(20 == hashInterop.FileHashInfoSize);
70
71 hash = new int[4];
72 hash[0] = hashInterop.Data0;
73 hash[1] = hashInterop.Data1;
74 hash[2] = hashInterop.Data2;
75 hash[3] = hashInterop.Data3;
76 }
77
78 /// <summary>
79 /// Returns the version string and language string in the format that the installer
80 /// expects to find them in the database. If you just want version information, set
81 /// lpLangBuf and pcchLangBuf to zero. If you just want language information, set
82 /// lpVersionBuf and pcchVersionBuf to zero.
83 /// </summary>
84 /// <param name="filePath">Specifies the path to the file.</param>
85 /// <param name="version">Returns the file version. Set to 0 for language information only.</param>
86 /// <param name="language">Returns the file language. Set to 0 for version information only.</param>
87 public static void GetFileVersion(string filePath, out string version, out string language)
88 {
89 var versionLength = 20;
90 var languageLength = 20;
91 var versionBuffer = new StringBuilder(versionLength);
92 var languageBuffer = new StringBuilder(languageLength);
93
94 var error = MsiInterop.MsiGetFileVersion(filePath, versionBuffer, ref versionLength, languageBuffer, ref languageLength);
95 if (234 == error)
96 {
97 versionBuffer.EnsureCapacity(++versionLength);
98 languageBuffer.EnsureCapacity(++languageLength);
99 error = MsiInterop.MsiGetFileVersion(filePath, versionBuffer, ref versionLength, languageBuffer, ref languageLength);
100 }
101 else if (1006 == error)
102 {
103 // file has no version or language, so no error
104 error = 0;
105 }
106
107 if (0 != error)
108 {
109 throw new MsiException(error);
110 }
111
112 version = versionBuffer.ToString();
113 language = languageBuffer.ToString();
114 }
115
116 /// <summary>
117 /// Enables an external user-interface handler.
118 /// </summary>
119 /// <param name="installUIHandler">Specifies a callback function.</param>
120 /// <param name="messageFilter">Specifies which messages to handle using the external message handler.</param>
121 /// <param name="context">Pointer to an application context that is passed to the callback function.</param>
122 /// <returns>The return value is the previously set external handler, or null if there was no previously set handler.</returns>
123 public static InstallUIHandler SetExternalUI(InstallUIHandler installUIHandler, int messageFilter, IntPtr context)
124 {
125 return MsiInterop.MsiSetExternalUI(installUIHandler, messageFilter, context);
126 }
127
128 /// <summary>
129 /// Enables the installer's internal user interface.
130 /// </summary>
131 /// <param name="uiLevel">Specifies the level of complexity of the user interface.</param>
132 /// <param name="hwnd">Pointer to a window. This window becomes the owner of any user interface created.</param>
133 /// <returns>The previous user interface level is returned. If an invalid dwUILevel is passed, then INSTALLUILEVEL_NOCHANGE is returned.</returns>
134 public static int SetInternalUI(int uiLevel, ref IntPtr hwnd)
135 {
136 return MsiInterop.MsiSetInternalUI(uiLevel, ref hwnd);
137 }
138 }
139 }