@joebigelow / wix / commits / e28fcc90

Add support using mergmod.dll and its interfaces

Rob Mensching committed May 21, 2020 at 23:08 UTC e28fcc906046ed12a867b621fc0eabf75fd9db09
10 files changed +545 -14
WixToolset.Core.Native.v3.ncrunchsolution new
+6
@@ -0,0 +1,6 @@
1 +<SolutionConfiguration>
2 + <Settings>
3 + <AllowParallelTestExecution>True</AllowParallelTestExecution>
4 + <SolutionConfigured>True</SolutionConfigured>
5 + </Settings>
6 +</SolutionConfiguration>
\ No newline at end of file
src/WixToolset.Core.Native/MsmInterop.cs new
+507
@@ -0,0 +1,507 @@
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
4 +{
5 + using System;
6 + using System.IO;
7 + using System.Reflection;
8 + using System.Runtime.InteropServices;
9 +
10 + /// <summary>
11 + /// Errors returned by merge operations.
12 + /// </summary>
13 + [Guid("0ADDA825-2C26-11D2-AD65-00A0C9AF11A6")]
14 + public enum MsmErrorType
15 + {
16 + /// <summary>
17 + /// A request was made to open a module with a language not supported by the module.
18 + /// No more general language is supported by the module.
19 + /// Adds msmErrorLanguageUnsupported to the Type property and the requested language
20 + /// to the Language Property (Error Object). All Error object properties are empty.
21 + /// The OpenModule function returns ERROR_INSTALL_LANGUAGE_UNSUPPORTED (as HRESULT).
22 + /// </summary>
23 + msmErrorLanguageUnsupported = 1,
24 +
25 + /// <summary>
26 + /// A request was made to open a module with a supported language but the module has
27 + /// an invalid language transform. Adds msmErrorLanguageFailed to the Type property
28 + /// and the applied transform's language to the Language Property of the Error object.
29 + /// This may not be the requested language if a more general language was used.
30 + /// All other properties of the Error object are empty. The OpenModule function
31 + /// returns ERROR_INSTALL_LANGUAGE_UNSUPPORTED (as HRESULT).
32 + /// </summary>
33 + msmErrorLanguageFailed = 2,
34 +
35 + /// <summary>
36 + /// The module cannot be merged because it excludes, or is excluded by, another module
37 + /// in the database. Adds msmErrorExclusion to the Type property of the Error object.
38 + /// The ModuleKeys property or DatabaseKeys property contains the primary keys of the
39 + /// excluded module's row in the ModuleExclusion table. If an existing module excludes
40 + /// the module being merged, the excluded module's ModuleSignature information is added
41 + /// to ModuleKeys. If the module being merged excludes an existing module, DatabaseKeys
42 + /// contains the excluded module's ModuleSignature information. All other properties
43 + /// are empty (or -1).
44 + /// </summary>
45 + msmErrorExclusion = 3,
46 +
47 + /// <summary>
48 + /// Merge conflict during merge. The value of the Type property is set to
49 + /// msmErrorTableMerge. The DatabaseTable property and DatabaseKeys property contain
50 + /// the table name and primary keys of the conflicting row in the database. The
51 + /// ModuleTable property and ModuleKeys property contain the table name and primary keys
52 + /// of the conflicting row in the module. The ModuleTable and ModuleKeys entries may be
53 + /// null if the row does not exist in the database. For example, if the conflict is in a
54 + /// generated FeatureComponents table entry. On Windows Installer version 2.0, when
55 + /// merging a configurable merge module, configuration may cause these properties to
56 + /// refer to rows that do not exist in the module.
57 + /// </summary>
58 + msmErrorTableMerge = 4,
59 +
60 + /// <summary>
61 + /// There was a problem resequencing a sequence table to contain the necessary merged
62 + /// actions. The Type property is set to msmErrorResequenceMerge. The DatabaseTable
63 + /// and DatabaseKeys properties contain the sequence table name and primary keys
64 + /// (action name) of the conflicting row. The ModuleTable and ModuleKeys properties
65 + /// contain the sequence table name and primary key (action name) of the conflicting row.
66 + /// On Windows Installer version 2.0, when merging a configurable merge module,
67 + /// configuration may cause these properties to refer to rows that do not exist in the module.
68 + /// </summary>
69 + msmErrorResequenceMerge = 5,
70 +
71 + /// <summary>
72 + /// Not used.
73 + /// </summary>
74 + msmErrorFileCreate = 6,
75 +
76 + /// <summary>
77 + /// There was a problem creating a directory to extract a file to disk. The Path property
78 + /// contains the directory that could not be created. All other properties are empty or -1.
79 + /// Not available with Windows Installer version 1.0.
80 + /// </summary>
81 + msmErrorDirCreate = 7,
82 +
83 + /// <summary>
84 + /// A feature name is required to complete the merge, but no feature name was provided.
85 + /// The Type property is set to msmErrorFeatureRequired. The DatabaseTable and DatabaseKeys
86 + /// contain the table name and primary keys of the conflicting row. The ModuleTable and
87 + /// ModuleKeys properties contain the table name and primary keys of the row cannot be merged.
88 + /// On Windows Installer version 2.0, when merging a configurable merge module, configuration
89 + /// may cause these properties to refer to rows that do not exist in the module.
90 + /// If the failure is in a generated FeatureComponents table, the DatabaseTable and
91 + /// DatabaseKeys properties are empty and the ModuleTable and ModuleKeys properties refer to
92 + /// the row in the Component table causing the failure.
93 + /// </summary>
94 + msmErrorFeatureRequired = 8,
95 +
96 + /// <summary>
97 + /// Available with Window Installer version 2.0. Substitution of a Null value into a
98 + /// non-nullable column. This enters msmErrorBadNullSubstitution in the Type property and
99 + /// enters "ModuleSubstitution" and the keys from the ModuleSubstitution table for this row
100 + /// into the ModuleTable property and ModuleKeys property. All other properties of the Error
101 + /// object are set to an empty string or -1. This error causes the immediate failure of the
102 + /// merge and the MergeEx function to return E_FAIL.
103 + /// </summary>
104 + msmErrorBadNullSubstitution = 9,
105 +
106 + /// <summary>
107 + /// Available with Window Installer version 2.0. Substitution of Text Format Type or Integer
108 + /// Format Type into a Binary Type data column. This type of error returns
109 + /// msmErrorBadSubstitutionType in the Type property and enters "ModuleSubstitution" and the
110 + /// keys from the ModuleSubstitution table for this row into the ModuleTable property.
111 + /// All other properties of the Error object are set to an empty string or -1. This error
112 + /// causes the immediate failure of the merge and the MergeEx function to return E_FAIL.
113 + /// </summary>
114 + msmErrorBadSubstitutionType = 10,
115 +
116 + /// <summary>
117 + /// Available with Window Installer Version 2.0. A row in the ModuleSubstitution table
118 + /// references a configuration item not defined in the ModuleConfiguration table.
119 + /// This type of error returns msmErrorMissingConfigItem in the Type property and enters
120 + /// "ModuleSubstitution" and the keys from the ModuleSubstitution table for this row into
121 + /// the ModuleTable property. All other properties of the Error object are set to an empty
122 + /// string or -1. This error causes the immediate failure of the merge and the MergeEx
123 + /// function to return E_FAIL.
124 + /// </summary>
125 + msmErrorMissingConfigItem = 11,
126 +
127 + /// <summary>
128 + /// Available with Window Installer version 2.0. The authoring tool has returned a Null
129 + /// value for an item marked with the msmConfigItemNonNullable attribute. An error of this
130 + /// type returns msmErrorBadNullResponse in the Type property and enters "ModuleSubstitution"
131 + /// and the keys from the ModuleSubstitution table for for the item into the ModuleTable property.
132 + /// All other properties of the Error object are set to an empty string or -1. This error
133 + /// causes the immediate failure of the merge and the MergeEx function to return E_FAIL.
134 + /// </summary>
135 + msmErrorBadNullResponse = 12,
136 +
137 + /// <summary>
138 + /// Available with Window Installer version 2.0. The authoring tool returned a failure code
139 + /// (not S_OK or S_FALSE) when asked for data. An error of this type will return
140 + /// msmErrorDataRequestFailed in the Type property and enters "ModuleSubstitution"
141 + /// and the keys from the ModuleSubstitution table for the item into the ModuleTable property.
142 + /// All other properties of the Error object are set to an empty string or -1. This error
143 + /// causes the immediate failure of the merge and the MergeEx function to return E_FAIL.
144 + /// </summary>
145 + msmErrorDataRequestFailed = 13,
146 +
147 + /// <summary>
148 + /// Available with Windows Installer 2.0 and later versions. Indicates that an attempt was
149 + /// made to merge a 64-bit module into a package that was not a 64-bit package. An error of
150 + /// this type returns msmErrorPlatformMismatch in the Type property. All other properties of
151 + /// the error object are set to an empty string or -1. This error causes the immediate failure
152 + /// of the merge and causes the Merge function or MergeEx function to return E_FAIL.
153 + /// </summary>
154 + msmErrorPlatformMismatch = 14,
155 + }
156 +
157 + /// <summary>
158 + /// IMsmMerge2 interface.
159 + /// </summary>
160 + [ComImport, Guid("351A72AB-21CB-47ab-B7AA-C4D7B02EA305")]
161 + public interface IMsmMerge2
162 + {
163 + /// <summary>
164 + /// The OpenDatabase method of the Merge object opens a Windows Installer installation
165 + /// database, located at a specified path, that is to be merged with a module.
166 + /// </summary>
167 + /// <param name="path">Path to the database being opened.</param>
168 + void OpenDatabase(string path);
169 +
170 + /// <summary>
171 + /// The OpenModule method of the Merge object opens a Windows Installer merge module
172 + /// in read-only mode. A module must be opened before it can be merged with an installation database.
173 + /// </summary>
174 + /// <param name="fileName">Fully qualified file name pointing to a merge module.</param>
175 + /// <param name="language">A valid language identifier (LANGID).</param>
176 + void OpenModule(string fileName, short language);
177 +
178 + /// <summary>
179 + /// The CloseDatabase method of the Merge object closes the currently open Windows Installer database.
180 + /// </summary>
181 + /// <param name="commit">true if changes should be saved, false otherwise.</param>
182 + void CloseDatabase(bool commit);
183 +
184 + /// <summary>
185 + /// The CloseModule method of the Merge object closes the currently open Windows Installer merge module.
186 + /// </summary>
187 + void CloseModule();
188 +
189 + /// <summary>
190 + /// The OpenLog method of the Merge object opens a log file that receives progress and error messages.
191 + /// If the log file already exists, the installer appends new messages. If the log file does not exist,
192 + /// the installer creates a log file.
193 + /// </summary>
194 + /// <param name="fileName">Fully qualified filename pointing to a file to open or create.</param>
195 + void OpenLog(string fileName);
196 +
197 + /// <summary>
198 + /// The CloseLog method of the Merge object closes the current log file.
199 + /// </summary>
200 + void CloseLog();
201 +
202 + /// <summary>
203 + /// The Log method of the Merge object writes a text string to the currently open log file.
204 + /// </summary>
205 + /// <param name="message">The text string to display.</param>
206 + void Log(string message);
207 +
208 + /// <summary>
209 + /// Gets the errors from the last merge operation.
210 + /// </summary>
211 + /// <value>The errors from the last merge operation.</value>
212 + IMsmErrors Errors
213 + {
214 + get;
215 + }
216 +
217 + /// <summary>
218 + /// Gets a collection of Dependency objects that enumerates a set of unsatisfied dependencies for the current database.
219 + /// </summary>
220 + /// <value>A collection of Dependency objects that enumerates a set of unsatisfied dependencies for the current database.</value>
221 + object Dependencies
222 + {
223 + get;
224 + }
225 +
226 + /// <summary>
227 + /// The Merge method of the Merge object executes a merge of the current database and current
228 + /// module. The merge attaches the components in the module to the feature identified by Feature.
229 + /// The root of the module's directory tree is redirected to the location given by RedirectDir.
230 + /// </summary>
231 + /// <param name="feature">The name of a feature in the database.</param>
232 + /// <param name="redirectDir">The key of an entry in the Directory table of the database.
233 + /// This parameter may be NULL or an empty string.</param>
234 + void Merge(string feature, string redirectDir);
235 +
236 + /// <summary>
237 + /// The Connect method of the Merge object connects a module to an additional feature.
238 + /// The module must have already been merged into the database or will be merged into the database.
239 + /// The feature must exist before calling this function.
240 + /// </summary>
241 + /// <param name="feature">The name of a feature already existing in the database.</param>
242 + void Connect(string feature);
243 +
244 + /// <summary>
245 + /// The ExtractCAB method of the Merge object extracts the embedded .cab file from a module and
246 + /// saves it as the specified file. The installer creates this file if it does not already exist
247 + /// and overwritten if it does exist.
248 + /// </summary>
249 + /// <param name="fileName">The fully qualified destination file.</param>
250 + void ExtractCAB(string fileName);
251 +
252 + /// <summary>
253 + /// The ExtractFiles method of the Merge object extracts the embedded .cab file from a module
254 + /// and then writes those files to the destination directory.
255 + /// </summary>
256 + /// <param name="path">The fully qualified destination directory.</param>
257 + void ExtractFiles(string path);
258 +
259 + /// <summary>
260 + /// The MergeEx method of the Merge object is equivalent to the Merge function, except that it
261 + /// takes an extra argument. The Merge method executes a merge of the current database and
262 + /// current module. The merge attaches the components in the module to the feature identified
263 + /// by Feature. The root of the module's directory tree is redirected to the location given by RedirectDir.
264 + /// </summary>
265 + /// <param name="feature">The name of a feature in the database.</param>
266 + /// <param name="redirectDir">The key of an entry in the Directory table of the database. This parameter may
267 + /// be NULL or an empty string.</param>
268 + /// <param name="configuration">The pConfiguration argument is an interface implemented by the client. The argument may
269 + /// be NULL. The presence of this argument indicates that the client is capable of supporting the configuration
270 + /// functionality, but does not obligate the client to provide configuration data for any specific configurable item.</param>
271 + void MergeEx(string feature, string redirectDir, IMsmConfigureModule configuration);
272 +
273 + /// <summary>
274 + /// The ExtractFilesEx method of the Merge object extracts the embedded .cab file from a module and
275 + /// then writes those files to the destination directory.
276 + /// </summary>
277 + /// <param name="path">The fully qualified destination directory.</param>
278 + /// <param name="longFileNames">Set to specify using long file names for path segments and final file names.</param>
279 + /// <param name="filePaths">This is a list of fully-qualified paths for the files that were successfully extracted.
280 + /// The list is empty if no files can be extracted. This argument may be null. No list is provided if pFilePaths is null.</param>
281 + void ExtractFilesEx(string path, bool longFileNames, ref IntPtr filePaths);
282 +
283 + /// <summary>
284 + /// Gets a collection ConfigurableItem objects, each of which represents a single row from the ModuleConfiguration table.
285 + /// </summary>
286 + /// <value>A collection ConfigurableItem objects, each of which represents a single row from the ModuleConfiguration table.</value>
287 + /// <remarks>Semantically, each interface in the enumerator represents an item that can be configured by the module consumer.
288 + /// The collection is a read-only collection and implements the standard read-only collection interfaces of Item(), Count() and _NewEnum().
289 + /// The IEnumMsmConfigItems enumerator implements Next(), Skip(), Reset(), and Clone() with the standard semantics.</remarks>
290 + object ConfigurableItems
291 + {
292 + get;
293 + }
294 +
295 + /// <summary>
296 + /// The CreateSourceImage method of the Merge object allows the client to extract the files from a module to
297 + /// a source image on disk after a merge, taking into account changes to the module that might have been made
298 + /// during module configuration. The list of files to be extracted is taken from the file table of the module
299 + /// during the merge process. The list of files consists of every file successfully copied from the file table
300 + /// of the module to the target database. File table entries that were not copied due to primary key conflicts
301 + /// with existing rows in the database are not a part of this list. At image creation time, the directory for
302 + /// each of these files comes from the open (post-merge) database. The path specified in the Path parameter is
303 + /// the root of the source image for the install. fLongFileNames determines whether or not long file names are
304 + /// used for both path segments and final file names. The function fails if no database is open, no module is
305 + /// open, or no merge has been performed.
306 + /// </summary>
307 + /// <param name="path">The path of the root of the source image for the install.</param>
308 + /// <param name="longFileNames">Determines whether or not long file names are used for both path segments and final file names. </param>
309 + /// <param name="filePaths">This is a list of fully-qualified paths for the files that were successfully extracted.
310 + /// The list is empty if no files can be extracted. This argument may be null. No list is provided if pFilePaths is null.</param>
311 + void CreateSourceImage(string path, bool longFileNames, ref IntPtr filePaths);
312 +
313 + /// <summary>
314 + /// The get_ModuleFiles function implements the ModuleFiles property of the GetFiles object. This function
315 + /// returns the primary keys in the File table of the currently open module. The primary keys are returned
316 + /// as a collection of strings. The module must be opened by a call to the OpenModule function before calling get_ModuleFiles.
317 + /// </summary>
318 + IMsmStrings ModuleFiles
319 + {
320 + get;
321 + }
322 + }
323 +
324 + /// <summary>
325 + /// Collection of merge errors.
326 + /// </summary>
327 + [ComImport, Guid("0ADDA82A-2C26-11D2-AD65-00A0C9AF11A6")]
328 + public interface IMsmErrors
329 + {
330 + /// <summary>
331 + /// Gets the IMsmError at the specified index.
332 + /// </summary>
333 + /// <param name="index">The one-based index of the IMsmError to get.</param>
334 + IMsmError this[int index]
335 + {
336 + get;
337 + }
338 +
339 + /// <summary>
340 + /// Gets the count of IMsmErrors in this collection.
341 + /// </summary>
342 + /// <value>The count of IMsmErrors in this collection.</value>
343 + int Count
344 + {
345 + get;
346 + }
347 + }
348 +
349 + /// <summary>
350 + /// A merge error.
351 + /// </summary>
352 + [ComImport, Guid("0ADDA828-2C26-11D2-AD65-00A0C9AF11A6")]
353 + public interface IMsmError
354 + {
355 + /// <summary>
356 + /// Gets the type of merge error.
357 + /// </summary>
358 + /// <value>The type of merge error.</value>
359 + MsmErrorType Type
360 + {
361 + get;
362 + }
363 +
364 + /// <summary>
365 + /// Gets the path information from the merge error.
366 + /// </summary>
367 + /// <value>The path information from the merge error.</value>
368 + string Path
369 + {
370 + get;
371 + }
372 +
373 + /// <summary>
374 + /// Gets the language information from the merge error.
375 + /// </summary>
376 + /// <value>The language information from the merge error.</value>
377 + short Language
378 + {
379 + get;
380 + }
381 +
382 + /// <summary>
383 + /// Gets the database table from the merge error.
384 + /// </summary>
385 + /// <value>The database table from the merge error.</value>
386 + string DatabaseTable
387 + {
388 + get;
389 + }
390 +
391 + /// <summary>
392 + /// Gets the collection of database keys from the merge error.
393 + /// </summary>
394 + /// <value>The collection of database keys from the merge error.</value>
395 + IMsmStrings DatabaseKeys
396 + {
397 + get;
398 + }
399 +
400 + /// <summary>
401 + /// Gets the module table from the merge error.
402 + /// </summary>
403 + /// <value>The module table from the merge error.</value>
404 + string ModuleTable
405 + {
406 + get;
407 + }
408 +
409 + /// <summary>
410 + /// Gets the collection of module keys from the merge error.
411 + /// </summary>
412 + /// <value>The collection of module keys from the merge error.</value>
413 + IMsmStrings ModuleKeys
414 + {
415 + get;
416 + }
417 + }
418 +
419 + /// <summary>
420 + /// A collection of strings.
421 + /// </summary>
422 + [ComImport, Guid("0ADDA827-2C26-11D2-AD65-00A0C9AF11A6")]
423 + public interface IMsmStrings
424 + {
425 + /// <summary>
426 + /// Gets the string at the specified index.
427 + /// </summary>
428 + /// <param name="index">The one-based index of the string to get.</param>
429 + string this[int index]
430 + {
431 + get;
432 + }
433 +
434 + /// <summary>
435 + /// Gets the count of strings in this collection.
436 + /// </summary>
437 + /// <value>The count of strings in this collection.</value>
438 + int Count
439 + {
440 + get;
441 + }
442 + }
443 +
444 + /// <summary>
445 + /// Callback for configurable merge modules.
446 + /// </summary>
447 + [ComImport, Guid("AC013209-18A7-4851-8A21-2353443D70A0"), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
448 + public interface IMsmConfigureModule
449 + {
450 + /// <summary>
451 + /// Callback to retrieve text data for configurable merge modules.
452 + /// </summary>
453 + /// <param name="name">Name of the data to be retrieved.</param>
454 + /// <param name="configData">The data corresponding to the name.</param>
455 + /// <returns>The error code (HRESULT).</returns>
456 + [PreserveSig]
457 + int ProvideTextData([In, MarshalAs(UnmanagedType.BStr)] string name, [MarshalAs(UnmanagedType.BStr)] out string configData);
458 +
459 + /// <summary>
460 + /// Callback to retrieve integer data for configurable merge modules.
461 + /// </summary>
462 + /// <param name="name">Name of the data to be retrieved.</param>
463 + /// <param name="configData">The data corresponding to the name.</param>
464 + /// <returns>The error code (HRESULT).</returns>
465 + [PreserveSig]
466 + int ProvideIntegerData([In, MarshalAs(UnmanagedType.BStr)] string name, out int configData);
467 + }
468 +
469 + /// <summary>
470 + /// Merge merge modules into an MSI file.
471 + /// </summary>
472 + [ComImport, Guid("F94985D5-29F9-4743-9805-99BC3F35B678")]
473 + public class MsmMerge2
474 + {
475 + }
476 +
477 + /// <summary>
478 + /// Defines the standard COM IClassFactory interface.
479 + /// </summary>
480 + [ComImport, Guid("00000001-0000-0000-C000-000000000046")]
481 + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
482 + public interface IClassFactory
483 + {
484 + [return: MarshalAs(UnmanagedType.IUnknown)]
485 + object CreateInstance(IntPtr unkOuter, [MarshalAs(UnmanagedType.LPStruct)] Guid iid);
486 + }
487 +
488 + /// <summary>
489 + /// Contains native methods for merge operations.
490 + /// </summary>
491 + public class MsmInterop
492 + {
493 + [DllImport("mergemod.dll", EntryPoint = "DllGetClassObject", PreserveSig = false)]
494 + [return: MarshalAs(UnmanagedType.IUnknown)]
495 + private static extern object MergeModGetClassObject([MarshalAs(UnmanagedType.LPStruct)] Guid clsid, [MarshalAs(UnmanagedType.LPStruct)] Guid iid);
496 +
497 + /// <summary>
498 + /// Load the merge object directly from a local mergemod.dll without going through COM registration.
499 + /// </summary>
500 + /// <returns>Merge interface.</returns>
501 + public IMsmMerge2 GetMsmMerge()
502 + {
503 + var classFactory = (IClassFactory)MergeModGetClassObject(typeof(MsmMerge2).GUID, typeof(IClassFactory).GUID);
504 + return (IMsmMerge2)classFactory.CreateInstance(IntPtr.Zero, typeof(IMsmMerge2).GUID);
505 + }
506 + }
507 +}
src/WixToolset.Core.Native/WixToolset.Core.Native.csproj
+3 -3
@@ -23,13 +23,13 @@
23 </PropertyGroup>
24
25 <Target Name="BuildWixNative" BeforeTargets="GetCopyToOutputDirectoryItems" Condition=" '$(NCrunch)'=='' ">
26 - <MSBuild Projects="..\wixnative\wixnative.vcxproj" Properties="Platform=Win32" Targets="Build;BuiltProjectOutputGroup;DebugSymbolsProjectOutputGroup">
26 + <MSBuild Projects="..\wixnative\wixnative.vcxproj" Properties="Platform=Win32" Targets="Build;BuiltProjectOutputGroup;ContentFilesProjectOutputGroup;DebugSymbolsProjectOutputGroup">
27 <Output TaskParameter="TargetOutputs" ItemName="_NativeProjectOutput" />
28 </MSBuild>
29 - <MSBuild Projects="..\wixnative\wixnative.vcxproj" Properties="Platform=x64" Targets="Build;BuiltProjectOutputGroup;DebugSymbolsProjectOutputGroup">
29 + <MSBuild Projects="..\wixnative\wixnative.vcxproj" Properties="Platform=x64" Targets="Build;BuiltProjectOutputGroup;ContentFilesProjectOutputGroup;DebugSymbolsProjectOutputGroup">
30 <Output TaskParameter="TargetOutputs" ItemName="_NativeProjectOutput" />
31 </MSBuild>
32 -
32 +
33 <WriteLinesToFile File="$(NativeFileListPath)" Lines="@(_NativeProjectOutput)" Overwrite="true" />
34
35 <ItemGroup>
src/WixToolset.Core.Native/WixToolset.Core.Native.v3.ncrunchproject deleted
-10
@@ -1,10 +0,0 @@
1 -<ProjectConfiguration>
2 - <Settings>
3 - <AdditionalFilesToIncludeForProject>
4 - <Value>..\..\build\Debug\Win32\wixnative.x86.exe</Value>
5 - <Value>..\..\build\Debug\Win32\wixnative.x86.pdb</Value>
6 - <Value>..\..\build\Debug\x64\wixnative.amd64.exe</Value>
7 - <Value>..\..\build\Debug\x64\wixnative.amd64.pdb</Value>
8 - </AdditionalFilesToIncludeForProject>
9 - </Settings>
10 -</ProjectConfiguration>
\ No newline at end of file
src/test/WixToolsetTest.Core.Native/MsmFixture.cs new
+18
@@ -0,0 +1,18 @@
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 WixToolsetTest.CoreNative
4 +{
5 + using WixToolset.Core.Native;
6 + using Xunit;
7 +
8 + public class MsmFixture
9 + {
10 + [Fact]
11 + public void CanCreateMsmInterface()
12 + {
13 + var msm = new MsmInterop();
14 + var merge = msm.GetMsmMerge();
15 + Assert.NotNull(merge);
16 + }
17 + }
18 +}
src/test/WixToolsetTest.Core.Native/WixToolsetTest.Core.Native.csproj
+1 -1
@@ -3,7 +3,7 @@
3
4 <Project Sdk="Microsoft.NET.Sdk">
5 <PropertyGroup>
6 - <TargetFramework>netcoreapp2.0</TargetFramework>
6 + <TargetFramework>netcoreapp2.1</TargetFramework>
7 <IsPackable>false</IsPackable>
8 </PropertyGroup>
9
src/wixnative/Win32/mergemod.dll
Binary files /dev/null and b/src/wixnative/Win32/mergemod.dll differ
src/wixnative/runtime.win.WixToolset.Core.Native.nuspec
+2
@@ -14,8 +14,10 @@
14 </metadata>
15
16 <files>
17 + <file src="Win32\mergemod.dll" target="runtimes\win-x86\native" />
18 <file src="Win32\wixnative.exe" target="runtimes\win-x86\native" />
19 <file src="Win32\wixnative.pdb" target="runtimes\win-x86\native" />
20 + <file src="x64\mergemod.dll" target="runtimes\win-x64\native" />
21 <file src="x64\wixnative.exe" target="runtimes\win-x64\native" />
22 <file src="x64\wixnative.pdb" target="runtimes\win-x64\native" />
23 </files>
src/wixnative/wixnative.vcxproj
+8
@@ -69,6 +69,14 @@
69 <None Include="packages.config" />
70 </ItemGroup>
71
72 + <ItemGroup>
73 + <None Include="$(Platform)\mergemod.dll">
74 + <DeploymentContent>true</DeploymentContent>
75 + <Link>%(Filename)%(Extension)</Link>
76 + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
77 + </None>
78 + </ItemGroup>
79 +
80 <Target Name="Pack" DependsOnTargets="GetBuildVersion">
81 <Exec Command='nuget pack runtime.win.WixToolset.Core.Native.nuspec -BasePath "$(BaseOutputPath)$(Configuration)" -OutputDirectory "$(BaseOutputPath)$(Configuration)" -NoPackageAnalysis -Properties Configuration=$(Configuration);Id=runtime.win.WixToolset.Core.Native;Version="$(BuildVersionSimple)";Platform=$(PlatformTarget);Authors="$(Authors)";Copyright="$(Copyright)";Description="$(Description)";Title="$(Title)"' />
82 </Target>
src/wixnative/x64/mergemod.dll
Binary files /dev/null and b/src/wixnative/x64/mergemod.dll differ