diff options
Diffstat (limited to 'src/dtf/WixToolset.Dtf.WindowsInstaller/InstallerAdvertise.cs')
-rw-r--r-- | src/dtf/WixToolset.Dtf.WindowsInstaller/InstallerAdvertise.cs | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/src/dtf/WixToolset.Dtf.WindowsInstaller/InstallerAdvertise.cs b/src/dtf/WixToolset.Dtf.WindowsInstaller/InstallerAdvertise.cs new file mode 100644 index 00000000..9da593d9 --- /dev/null +++ b/src/dtf/WixToolset.Dtf.WindowsInstaller/InstallerAdvertise.cs | |||
@@ -0,0 +1,270 @@ | |||
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.Dtf.WindowsInstaller | ||
4 | { | ||
5 | using System; | ||
6 | using System.IO; | ||
7 | using System.Text; | ||
8 | using System.Reflection; | ||
9 | using System.Globalization; | ||
10 | using System.Collections.Generic; | ||
11 | using System.Diagnostics.CodeAnalysis; | ||
12 | |||
13 | public static partial class Installer | ||
14 | { | ||
15 | /// <summary> | ||
16 | /// Advertises a product to the local computer. | ||
17 | /// </summary> | ||
18 | /// <param name="packagePath">Path to the package of the product being advertised</param> | ||
19 | /// <param name="perUser">True if the product is user-assigned; false if it is machine-assigned.</param> | ||
20 | /// <param name="transforms">Semi-colon delimited list of transforms to be applied. This parameter may be null.</param> | ||
21 | /// <param name="locale">The language to use if the source supports multiple languages</param> | ||
22 | /// <exception cref="FileNotFoundException">the specified package file does not exist</exception> | ||
23 | /// <seealso cref="GenerateAdvertiseScript(string,string,string,int,ProcessorArchitecture,bool)"/> | ||
24 | /// <remarks><p> | ||
25 | /// Win32 MSI APIs: | ||
26 | /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msiadvertiseproduct.asp">MsiAdvertiseProduct</a>, | ||
27 | /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msiadvertiseproductex.asp">MsiAdvertiseProductEx</a> | ||
28 | /// </p></remarks> | ||
29 | public static void AdvertiseProduct(string packagePath, bool perUser, string transforms, int locale) | ||
30 | { | ||
31 | if (String.IsNullOrEmpty(packagePath)) | ||
32 | { | ||
33 | throw new ArgumentNullException("packagePath"); | ||
34 | } | ||
35 | |||
36 | if (!File.Exists(packagePath)) | ||
37 | { | ||
38 | throw new FileNotFoundException(null, packagePath); | ||
39 | } | ||
40 | |||
41 | uint ret = NativeMethods.MsiAdvertiseProduct(packagePath, new IntPtr(perUser ? 1 : 0), transforms, (ushort) locale); | ||
42 | if (ret != 0) | ||
43 | { | ||
44 | throw InstallerException.ExceptionFromReturnCode(ret); | ||
45 | } | ||
46 | } | ||
47 | |||
48 | /// <summary> | ||
49 | /// Generates an advertise script. The method enables the installer to write to a | ||
50 | /// script the registry and shortcut information used to assign or publish a product. | ||
51 | /// </summary> | ||
52 | /// <param name="packagePath">Path to the package of the product being advertised</param> | ||
53 | /// <param name="scriptFilePath">path to script file to be created with the advertise information</param> | ||
54 | /// <param name="transforms">Semi-colon delimited list of transforms to be applied. This parameter may be null.</param> | ||
55 | /// <param name="locale">The language to use if the source supports multiple languages</param> | ||
56 | /// <exception cref="FileNotFoundException">the specified package file does not exist</exception> | ||
57 | /// <seealso cref="AdvertiseProduct"/> | ||
58 | /// <remarks><p> | ||
59 | /// Win32 MSI APIs: | ||
60 | /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msiadvertiseproduct.asp">MsiAdvertiseProduct</a>, | ||
61 | /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msiadvertiseproductex.asp">MsiAdvertiseProductEx</a> | ||
62 | /// </p></remarks> | ||
63 | public static void GenerateAdvertiseScript(string packagePath, string scriptFilePath, string transforms, int locale) | ||
64 | { | ||
65 | if (String.IsNullOrEmpty(packagePath)) | ||
66 | { | ||
67 | throw new ArgumentNullException("packagePath"); | ||
68 | } | ||
69 | |||
70 | if (!File.Exists(packagePath)) | ||
71 | { | ||
72 | throw new FileNotFoundException(null, packagePath); | ||
73 | } | ||
74 | |||
75 | uint ret = NativeMethods.MsiAdvertiseProduct(packagePath, scriptFilePath, transforms, (ushort) locale); | ||
76 | if (ret != 0) | ||
77 | { | ||
78 | throw InstallerException.ExceptionFromReturnCode(ret); | ||
79 | } | ||
80 | } | ||
81 | |||
82 | /// <summary> | ||
83 | /// Generates an advertise script. The method enables the installer to write to a | ||
84 | /// script the registry and shortcut information used to assign or publish a product. | ||
85 | /// </summary> | ||
86 | /// <param name="packagePath">Path to the package of the product being advertised</param> | ||
87 | /// <param name="scriptFilePath">path to script file to be created with the advertise information</param> | ||
88 | /// <param name="transforms">Semi-colon delimited list of transforms to be applied. This parameter may be null.</param> | ||
89 | /// <param name="locale">The language to use if the source supports multiple languages</param> | ||
90 | /// <param name="processor">Targeted processor architecture.</param> | ||
91 | /// <param name="instance">True to install multiple instances through product code changing transform. | ||
92 | /// Advertises a new instance of the product. Requires that the <paramref name="transforms"/> parameter | ||
93 | /// includes the instance transform that changes the product code.</param> | ||
94 | /// <seealso cref="AdvertiseProduct"/> | ||
95 | /// <remarks><p> | ||
96 | /// Win32 MSI APIs: | ||
97 | /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msiadvertiseproduct.asp">MsiAdvertiseProduct</a>, | ||
98 | /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msiadvertiseproductex.asp">MsiAdvertiseProductEx</a> | ||
99 | /// </p></remarks> | ||
100 | public static void GenerateAdvertiseScript( | ||
101 | string packagePath, | ||
102 | string scriptFilePath, | ||
103 | string transforms, | ||
104 | int locale, | ||
105 | ProcessorArchitecture processor, | ||
106 | bool instance) | ||
107 | { | ||
108 | if (String.IsNullOrEmpty(packagePath)) | ||
109 | { | ||
110 | throw new ArgumentNullException("packagePath"); | ||
111 | } | ||
112 | |||
113 | if (String.IsNullOrEmpty(scriptFilePath)) | ||
114 | { | ||
115 | throw new ArgumentNullException("scriptFilePath"); | ||
116 | } | ||
117 | |||
118 | if (!File.Exists(packagePath)) | ||
119 | { | ||
120 | throw new FileNotFoundException(null, packagePath); | ||
121 | } | ||
122 | |||
123 | uint platform = 0; | ||
124 | switch (processor) | ||
125 | { | ||
126 | case ProcessorArchitecture.X86: platform = (uint) 1; break; | ||
127 | case ProcessorArchitecture.IA64: platform = (uint) 2; break; | ||
128 | case ProcessorArchitecture.Amd64: platform = (uint) 4; break; | ||
129 | } | ||
130 | |||
131 | uint ret = NativeMethods.MsiAdvertiseProductEx( | ||
132 | packagePath, | ||
133 | scriptFilePath, | ||
134 | transforms, | ||
135 | (ushort) locale, | ||
136 | platform, | ||
137 | instance ? (uint) 1 : 0); | ||
138 | if (ret != 0) | ||
139 | { | ||
140 | throw InstallerException.ExceptionFromReturnCode(ret); | ||
141 | } | ||
142 | } | ||
143 | |||
144 | /// <summary> | ||
145 | /// Copies an advertise script file to the local computer. | ||
146 | /// </summary> | ||
147 | /// <param name="scriptFile">Path to a script file generated by | ||
148 | /// <see cref="GenerateAdvertiseScript(string,string,string,int,ProcessorArchitecture,bool)"/></param> | ||
149 | /// <param name="flags">Flags controlling advertisement</param> | ||
150 | /// <param name="removeItems">True if specified items are to be removed instead of being created</param> | ||
151 | /// <remarks><p> | ||
152 | /// The process calling this function must be running under the LocalSystem account. To advertise an | ||
153 | /// application for per-user installation to a targeted user, the thread that calls this function must | ||
154 | /// impersonate the targeted user. If the thread calling this function is not impersonating a targeted | ||
155 | /// user, the application is advertised to all users for installation with elevated privileges. | ||
156 | /// </p></remarks> | ||
157 | [SuppressMessage("Microsoft.Naming", "CA1726:UsePreferredTerms", MessageId = "flags")] | ||
158 | public static void AdvertiseScript(string scriptFile, int flags, bool removeItems) | ||
159 | { | ||
160 | uint ret = NativeMethods.MsiAdvertiseScript(scriptFile, (uint) flags, IntPtr.Zero, removeItems); | ||
161 | if (ret != 0) | ||
162 | { | ||
163 | throw InstallerException.ExceptionFromReturnCode(ret); | ||
164 | } | ||
165 | } | ||
166 | |||
167 | /// <summary> | ||
168 | /// Processes an advertise script file into the specified locations. | ||
169 | /// </summary> | ||
170 | /// <param name="scriptFile">Path to a script file generated by | ||
171 | /// <see cref="GenerateAdvertiseScript(string,string,string,int,ProcessorArchitecture,bool)"/></param> | ||
172 | /// <param name="iconFolder">An optional path to a folder in which advertised icon files and transform | ||
173 | /// files are located. If this parameter is null, no icon or transform files are written.</param> | ||
174 | /// <param name="shortcuts">True if shortcuts should be created</param> | ||
175 | /// <param name="removeItems">True if specified items are to be removed instead of created</param> | ||
176 | /// <remarks><p> | ||
177 | /// The process calling this function must be running under the LocalSystem account. To advertise an | ||
178 | /// application for per-user installation to a targeted user, the thread that calls this function must | ||
179 | /// impersonate the targeted user. If the thread calling this function is not impersonating a targeted | ||
180 | /// user, the application is advertised to all users for installation with elevated privileges. | ||
181 | /// </p><p> | ||
182 | /// Win32 MSI API: | ||
183 | /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msiprocessadvertisescript.asp">MsiProcessAdvertiseScript</a> | ||
184 | /// </p></remarks> | ||
185 | public static void ProcessAdvertiseScript(string scriptFile, string iconFolder, bool shortcuts, bool removeItems) | ||
186 | { | ||
187 | uint ret = NativeMethods.MsiProcessAdvertiseScript(scriptFile, iconFolder, IntPtr.Zero, shortcuts, removeItems); | ||
188 | if (ret != 0) | ||
189 | { | ||
190 | throw InstallerException.ExceptionFromReturnCode(ret); | ||
191 | } | ||
192 | } | ||
193 | |||
194 | /// <summary> | ||
195 | /// Gets product information for an installer script file. | ||
196 | /// </summary> | ||
197 | /// <param name="scriptFile">Path to a script file generated by | ||
198 | /// <see cref="GenerateAdvertiseScript(string,string,string,int,ProcessorArchitecture,bool)"/></param> | ||
199 | /// <returns>ProductInstallation stub with advertise-related properties filled in.</returns> | ||
200 | /// <exception cref="ArgumentOutOfRangeException">An invalid product property was requested</exception> | ||
201 | /// <remarks><p> | ||
202 | /// Only the following properties will be filled in in the returned object:<ul> | ||
203 | /// <li><see cref="ProductInstallation.ProductCode"/></li> | ||
204 | /// <li><see cref="ProductInstallation.AdvertisedLanguage"/></li> | ||
205 | /// <li><see cref="ProductInstallation.AdvertisedVersion"/></li> | ||
206 | /// <li><see cref="ProductInstallation.AdvertisedProductName"/></li> | ||
207 | /// <li><see cref="ProductInstallation.AdvertisedPackageName"/></li> | ||
208 | /// </ul>Other properties will be null. | ||
209 | /// </p><p> | ||
210 | /// Win32 MSI API: | ||
211 | /// <a href="http://msdn.microsoft.com/library/en-us/msi/setup/msigetproductinfofromscript.asp">MsiGetProductInfoFromScript</a> | ||
212 | /// </p></remarks> | ||
213 | public static ProductInstallation GetProductInfoFromScript(string scriptFile) | ||
214 | { | ||
215 | if (String.IsNullOrEmpty(scriptFile)) | ||
216 | { | ||
217 | throw new ArgumentNullException("scriptFile"); | ||
218 | } | ||
219 | StringBuilder productCodeBuf = new StringBuilder(40); | ||
220 | ushort lang; | ||
221 | uint ver; | ||
222 | StringBuilder productNameBuf = new StringBuilder(100); | ||
223 | StringBuilder packageNameBuf = new StringBuilder(40); | ||
224 | uint productCodeBufSize = (uint) productCodeBuf.Capacity; | ||
225 | uint productNameBufSize = (uint) productNameBuf.Capacity; | ||
226 | uint packageNameBufSize = (uint) packageNameBuf.Capacity; | ||
227 | uint ret = NativeMethods.MsiGetProductInfoFromScript( | ||
228 | scriptFile, | ||
229 | productCodeBuf, | ||
230 | out lang, | ||
231 | out ver, | ||
232 | productNameBuf, | ||
233 | ref productNameBufSize, | ||
234 | packageNameBuf, | ||
235 | ref packageNameBufSize); | ||
236 | if (ret == (uint) NativeMethods.Error.MORE_DATA) | ||
237 | { | ||
238 | productCodeBuf.Capacity = (int) ++productCodeBufSize; | ||
239 | productNameBuf.Capacity = (int) ++productNameBufSize; | ||
240 | packageNameBuf.Capacity = (int) ++packageNameBufSize; | ||
241 | ret = NativeMethods.MsiGetProductInfoFromScript( | ||
242 | scriptFile, | ||
243 | productCodeBuf, | ||
244 | out lang, | ||
245 | out ver, | ||
246 | productNameBuf, | ||
247 | ref productNameBufSize, | ||
248 | packageNameBuf, | ||
249 | ref packageNameBufSize); | ||
250 | } | ||
251 | |||
252 | if (ret != 0) | ||
253 | { | ||
254 | throw InstallerException.ExceptionFromReturnCode(ret); | ||
255 | } | ||
256 | uint verPart1 = ver >> 24; | ||
257 | uint verPart2 = (ver & 0x00FFFFFF) >> 16; | ||
258 | uint verPart3 = ver & 0x0000FFFF; | ||
259 | Version version = new Version((int) verPart1, (int) verPart2, (int) verPart3); | ||
260 | |||
261 | IDictionary<string, string> props = new Dictionary<string, string>(); | ||
262 | props["ProductCode"] = productCodeBuf.ToString(); | ||
263 | props["Language"] = lang.ToString(CultureInfo.InvariantCulture); | ||
264 | props["Version"] = version.ToString(); | ||
265 | props["ProductName"] = productNameBuf.ToString(); | ||
266 | props["PackageName"] = packageNameBuf.ToString(); | ||
267 | return new ProductInstallation(props); | ||
268 | } | ||
269 | } | ||
270 | } | ||