aboutsummaryrefslogtreecommitdiff
path: root/src/dtf/WixToolset.Dtf.WindowsInstaller/InstallerAdvertise.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/dtf/WixToolset.Dtf.WindowsInstaller/InstallerAdvertise.cs')
-rw-r--r--src/dtf/WixToolset.Dtf.WindowsInstaller/InstallerAdvertise.cs270
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
3namespace 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}