@joebigelow / wix / commits / 71c52d5a

Fix source path and cabinet processing

Rob Mensching committed Nov 29, 2017 at 22:03 UTC 71c52d5af2293d3eb79882ce36b0411f81185c11
33 files changed +352 -932
src/WixToolset.Core.Burn/Bundles/BurnReader.cs
+5 -9
@@ -7,7 +7,7 @@ namespace WixToolset.Core.Burn.Bundles
7 using System.Collections.Generic;
8 using System.IO;
9 using System.Xml;
10 - using WixToolset.Core.Cab;
10 + using WixToolset.Core.Native;
11
12 /// <summary>
13 /// Burn PE reader for the WiX toolset.
@@ -101,10 +101,8 @@ namespace WixToolset.Core.Burn.Bundles
101 BurnCommon.CopyStream(this.binaryReader.BaseStream, tempCab, (int)this.UXSize);
102 }
103
104 - using (var extract = new WixExtractCab())
105 - {
106 - extract.Extract(tempCabPath, outputDirectory);
107 - }
104 + var cabinet = new Cabinet(tempCabPath);
105 + cabinet.Extract(outputDirectory);
106
107 Directory.CreateDirectory(Path.GetDirectoryName(manifestPath));
108 File.Delete(manifestPath);
@@ -181,10 +179,8 @@ namespace WixToolset.Core.Burn.Bundles
179 BurnCommon.CopyStream(this.binaryReader.BaseStream, tempCab, (int)this.AttachedContainerSize);
180 }
181
184 - using (WixExtractCab extract = new WixExtractCab())
185 - {
186 - extract.Extract(tempCabPath, outputDirectory);
187 - }
182 + var cabinet = new Cabinet(tempCabPath);
183 + cabinet.Extract(outputDirectory);
184
185 foreach (DictionaryEntry entry in this.attachedContainerPayloadNames)
186 {
src/WixToolset.Core.Burn/Bundles/CreateContainerCommand.cs
-1
@@ -7,7 +7,6 @@ namespace WixToolset.Core.Burn.Bundles
7 using System.Diagnostics;
8 using System.IO;
9 using System.Linq;
10 - using WixToolset.Core.Cab;
10 using WixToolset.Data;
11 using WixToolset.Data.Rows;
12
src/WixToolset.Core.Burn/WixToolset.Core.Burn.csproj
+1 -1
@@ -20,9 +20,9 @@
20 <PackageReference Include="WixToolset.Extensibility" Version="4.0.*" Condition=" '$(Configuration)' == 'Release' Or !Exists('$(WixToolsetRootFolder)\Extensibility\src\WixToolset.Extensibility\WixToolset.Extensibility.csproj') " />
21
22 <ProjectReference Include="$(WixToolsetRootFolder)\Core.Native\src\WixToolset.Core.Native\WixToolset.Core.Native.csproj" Condition=" '$(Configuration)' == 'Debug' And Exists('$(WixToolsetRootFolder)\Core.Native\src\WixToolset.Core.Native\WixToolset.Core.Native.csproj') " />
23 + <PackageReference Include="WixToolset.Core.Native" Version="4.0.*" Condition=" '$(Configuration)' == 'Release' Or !Exists('$(WixToolsetRootFolder)\Core.Native\src\WixToolset.Core.Native\WixToolset.Core.Native.csproj') " />
24
25 <ProjectReference Include="..\WixToolset.Core\WixToolset.Core.csproj" />
25 - <PackageReference Include="WixToolset.Core.Native" Version="4.0.*" Condition=" '$(Configuration)' == 'Release' Or !Exists('$(WixToolsetRootFolder)\Core.Native\src\WixToolset.Core.Native\WixToolset.Core.Native.csproj') " />
26 </ItemGroup>
27
28 <ItemGroup>
src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
+4 -3
@@ -123,7 +123,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
123 {
124 propertyRow.Value = Common.GenerateGuid();
125
126 -#if TODO_FIX_INSTANCE_TRANSFORM
126 +#if TODO_FIX_INSTANCE_TRANSFORM // Is this still necessary?
127 +
128 // Update the target ProductCode in any instance transforms.
129 foreach (SubStorage subStorage in this.Output.SubStorages)
130 {
@@ -391,7 +392,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
392 command.ResolveMedia = this.ResolveMedia;
393 command.TableDefinitions = this.TableDefinitions;
394 command.TempFilesLocation = this.IntermediateFolder;
394 - command.WixMediaTable = output.Tables["WixMedia"];
395 + command.WixMediaTuples = section.Tuples.OfType<WixMediaTuple>();
396 command.Execute();
397
398 fileTransfers.AddRange(command.FileTransfers);
@@ -526,7 +527,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
527 }
528
529 this.FileTransfers = fileTransfers;
529 - this.ContentFilePaths = fileFacades.Select(r => r.WixFile.Source).ToList();
530 + this.ContentFilePaths = fileFacades.Select(r => r.WixFile.Source.Path).ToList();
531
532 // TODO: Eventually this gets removed
533 var intermediate = new Intermediate(this.Intermediate.Id, new[] { section }, this.Intermediate.Localizations.ToDictionary(l => l.Culture, StringComparer.OrdinalIgnoreCase), this.Intermediate.EmbedFilePaths);
src/WixToolset.Core.WindowsInstaller/Bind/CabinetBuilder.cs
+20 -12
@@ -4,11 +4,12 @@ namespace WixToolset.Core.WindowsInstaller.Bind
4 {
5 using System;
6 using System.Collections;
7 + using System.Collections.Generic;
8 using System.IO;
9 using System.Linq;
10 using System.Threading;
11 using WixToolset.Core.Bind;
11 - using WixToolset.Core.Cab;
12 + using WixToolset.Core.Native;
13 using WixToolset.Data;
14
15 /// <summary>
@@ -137,7 +138,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
138 int maxCabinetSize = 0; // The value of 0 corresponds to default of 2GB which means no cabinet splitting
139 ulong maxPreCompressedSizeInBytes = 0;
140
140 - if (MaximumCabinetSizeForLargeFileSplitting != 0)
141 + if (this.MaximumCabinetSizeForLargeFileSplitting != 0)
142 {
143 // User Specified Max Cab Size for File Splitting, So Check if this cabinet has a single file larger than MaximumUncompressedFileSize
144 // If a file is larger than MaximumUncompressedFileSize, then the cabinet containing it will have only this file
@@ -152,26 +153,33 @@ namespace WixToolset.Core.WindowsInstaller.Bind
153 if ((ulong)facade.File.FileSize >= maxPreCompressedSizeInBytes)
154 {
155 // If file is larger than MaximumUncompressedFileSize set Maximum Cabinet Size for Cabinet Splitting
155 - maxCabinetSize = MaximumCabinetSizeForLargeFileSplitting;
156 + maxCabinetSize = this.MaximumCabinetSizeForLargeFileSplitting;
157 }
158 }
159 }
160 }
161
162 // create the cabinet file
163 + var cabinetPath = Path.GetFullPath(cabinetWorkItem.CabinetFile);
164 string cabinetFileName = Path.GetFileName(cabinetWorkItem.CabinetFile);
165 string cabinetDirectory = Path.GetDirectoryName(cabinetWorkItem.CabinetFile);
166
165 - using (WixCreateCab cab = new WixCreateCab(cabinetFileName, cabinetDirectory, cabinetWorkItem.FileFacades.Count(), maxCabinetSize, cabinetWorkItem.MaxThreshold, cabinetWorkItem.CompressionLevel))
166 - {
167 - foreach (FileFacade facade in cabinetWorkItem.FileFacades)
168 - {
169 - cab.AddFile(facade);
170 - }
167 + //using (WixCreateCab cab = new WixCreateCab(cabinetFileName, cabinetDirectory, cabinetWorkItem.FileFacades.Count(), maxCabinetSize, cabinetWorkItem.MaxThreshold, cabinetWorkItem.CompressionLevel))
168 + //{
169 + // foreach (FileFacade facade in cabinetWorkItem.FileFacades)
170 + // {
171 + // cab.AddFile(facade);
172 + // }
173
172 - cab.Complete(newCabNamesCallBackAddress);
173 - }
174 + // cab.Complete(newCabNamesCallBackAddress);
175 + //}
176 +
177 + var files = cabinetWorkItem.FileFacades.Select(facade => new CabinetCompressFile(facade.WixFile.Source.Path, facade.File.File, facade.Hash.HashPart1, facade.Hash.HashPart2, facade.Hash.HashPart3, facade.Hash.HashPart4)).ToList();
178 +
179 + var cabinetCompressionLevel = (CabinetCompressionLevel)cabinetWorkItem.CompressionLevel;
180 +
181 + var cab = new Cabinet(cabinetPath);
182 + cab.Compress(files, cabinetCompressionLevel, maxCabinetSize, cabinetWorkItem.MaxThreshold);
183 }
184 }
185 }
177 -
src/WixToolset.Core.WindowsInstaller/Bind/CabinetResolver.cs
+27 -33
@@ -6,8 +6,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind
6 using System.Collections.Generic;
7 using System.IO;
8 using System.Linq;
9 - using WixToolset.Core.Cab;
9 using WixToolset.Core.Bind;
10 + using WixToolset.Core.Native;
11 using WixToolset.Data;
12 using WixToolset.Extensibility;
13
@@ -26,7 +26,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
26
27 public ResolvedCabinet ResolveCabinet(string cabinetPath, IEnumerable<FileFacade> fileFacades)
28 {
29 - var filesWithPath = fileFacades.Select(f => new BindFileWithPath() { Id = f.File.File, Path = f.WixFile.Source }).ToList();
29 + var filesWithPath = fileFacades.Select(f => new BindFileWithPath() { Id = f.File.File, Path = f.WixFile.Source.Path }).ToList();
30
31 ResolvedCabinet resolved = null;
32
@@ -58,45 +58,39 @@ namespace WixToolset.Core.WindowsInstaller.Bind
58 // 3. modified time changed
59 bool cabinetValid = true;
60
61 - // Need to force garbage collection of WixEnumerateCab to ensure the handle
62 - // associated with it is closed before it is reused.
63 - using (var wixEnumerateCab = new WixEnumerateCab())
64 - {
65 - List<CabinetFileInfo> fileList = wixEnumerateCab.Enumerate(resolved.Path);
61 + var cabinet = new Cabinet(resolved.Path);
62 + List<CabinetFileInfo> fileList = cabinet.Enumerate();
63
67 - if (filesWithPath.Count() != fileList.Count)
68 - {
69 - cabinetValid = false;
70 - }
71 - else
64 + if (filesWithPath.Count() != fileList.Count)
65 + {
66 + cabinetValid = false;
67 + }
68 + else
69 + {
70 + int i = 0;
71 + foreach (BindFileWithPath file in filesWithPath)
72 {
73 - int i = 0;
74 - foreach (BindFileWithPath file in filesWithPath)
73 + // First check that the file identifiers match because that is quick and easy.
74 + CabinetFileInfo cabFileInfo = fileList[i];
75 + cabinetValid = (cabFileInfo.FileId == file.Id);
76 + if (cabinetValid)
77 {
76 - // First check that the file identifiers match because that is quick and easy.
77 - CabinetFileInfo cabFileInfo = fileList[i];
78 - cabinetValid = (cabFileInfo.FileId == file.Id);
78 + // Still valid so ensure the file sizes are the same.
79 + FileInfo fileInfo = new FileInfo(file.Path);
80 + cabinetValid = (cabFileInfo.Size == fileInfo.Length);
81 if (cabinetValid)
82 {
81 - // Still valid so ensure the file sizes are the same.
82 - FileInfo fileInfo = new FileInfo(file.Path);
83 - cabinetValid = (cabFileInfo.Size == fileInfo.Length);
84 - if (cabinetValid)
85 - {
86 - // Still valid so ensure the source time stamp hasn't changed. Thus we need
87 - // to convert the source file time stamp into a cabinet compatible data/time.
88 - Native.CabInterop.DateTimeToCabDateAndTime(fileInfo.LastWriteTime, out var sourceCabDate, out var sourceCabTime);
89 - cabinetValid = (cabFileInfo.Date == sourceCabDate && cabFileInfo.Time == sourceCabTime);
90 - }
91 - }
92 -
93 - if (!cabinetValid)
94 - {
95 - break;
83 + // Still valid so ensure the source time stamp hasn't changed.
84 + cabinetValid = cabFileInfo.SameAsDateTime(fileInfo.LastWriteTime);
85 }
86 + }
87
98 - i++;
88 + if (!cabinetValid)
89 + {
90 + break;
91 }
92 +
93 + i++;
94 }
95 }
96
src/WixToolset.Core.WindowsInstaller/Bind/CreateCabinetsCommand.cs
+6 -6
@@ -66,7 +66,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
66
67 public TableDefinitionCollection TableDefinitions { private get; set; }
68
69 - public Table WixMediaTable { private get; set; }
69 + public IEnumerable<WixMediaTuple> WixMediaTuples { private get; set; }
70
71 public IEnumerable<FileTransfer> FileTransfers => this.fileTransfers;
72
@@ -77,7 +77,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
77 /// <returns>The uncompressed file rows.</returns>
78 public void Execute()
79 {
80 - var wixMediaRows = new RowDictionary<WixMediaRow>(this.WixMediaTable);
80 + var wixMediaTuples = this.WixMediaTuples.ToDictionary(t => t.DiskId_);
81
82 this.lastCabinetAddedToMediaTable = new Dictionary<string, string>();
83
@@ -93,13 +93,13 @@ namespace WixToolset.Core.WindowsInstaller.Bind
93
94 foreach (var entry in this.FileRowsByCabinet)
95 {
96 - var mediaRow = entry.Key;
96 + var mediaTuple = entry.Key;
97 IEnumerable<FileFacade> files = entry.Value;
98 CompressionLevel compressionLevel = this.DefaultCompressionLevel;
99
100 string mediaLayoutFolder = null;
101
102 - if (wixMediaRows.TryGetValue(mediaRow.Id.Id, out var wixMediaRow))
102 + if (wixMediaTuples.TryGetValue(mediaTuple.DiskId, out var wixMediaRow))
103 {
104 mediaLayoutFolder = wixMediaRow.Layout;
105
@@ -109,9 +109,9 @@ namespace WixToolset.Core.WindowsInstaller.Bind
109 }
110 }
111
112 - string cabinetDir = this.ResolveMedia(mediaRow, mediaLayoutFolder, this.LayoutDirectory);
112 + string cabinetDir = this.ResolveMedia(mediaTuple, mediaLayoutFolder, this.LayoutDirectory);
113
114 - CabinetWorkItem cabinetWorkItem = this.CreateCabinetWorkItem(this.Output, cabinetDir, mediaRow, compressionLevel, files, this.fileTransfers);
114 + CabinetWorkItem cabinetWorkItem = this.CreateCabinetWorkItem(this.Output, cabinetDir, mediaTuple, compressionLevel, files, this.fileTransfers);
115 if (null != cabinetWorkItem)
116 {
117 cabinetBuilder.Enqueue(cabinetWorkItem);
src/WixToolset.Core.WindowsInstaller/Bind/CreateOutputFromIRCommand.cs
+41 -1
@@ -44,9 +44,21 @@ namespace WixToolset.Core.WindowsInstaller.Bind
44 this.AddFileTuple((FileTuple)tuple, output);
45 break;
46
47 + case TupleDefinitionType.Media:
48 + this.AddMediaTuple((MediaTuple)tuple, output);
49 + break;
50 +
51 + case TupleDefinitionType.Property:
52 + this.AddPropertyTuple((PropertyTuple)tuple, output);
53 + break;
54 +
55 case TupleDefinitionType.WixAction:
56 this.AddWixActionTuple((WixActionTuple)tuple, output);
49 - break;
57 + break;
58 +
59 + case TupleDefinitionType.WixMedia:
60 + // Ignored.
61 + break;
62
63 default:
64 this.AddTupleDefaultly(tuple, output);
@@ -76,6 +88,34 @@ namespace WixToolset.Core.WindowsInstaller.Bind
88 row.Attributes = attributes;
89 }
90
91 + private void AddMediaTuple(MediaTuple tuple, Output output)
92 + {
93 + if (this.Section.Type != SectionType.Module)
94 + {
95 + var table = output.EnsureTable(this.TableDefinitions["Media"]);
96 + var row = (MediaRow)table.CreateRow(tuple.SourceLineNumbers);
97 + row.DiskId = tuple.DiskId;
98 + row.LastSequence = tuple.LastSequence;
99 + row.DiskPrompt = tuple.DiskPrompt;
100 + row.Cabinet = tuple.Cabinet;
101 + row.VolumeLabel = tuple.VolumeLabel;
102 + row.Source = tuple.Source;
103 + }
104 + }
105 +
106 + private void AddPropertyTuple(PropertyTuple tuple, Output output)
107 + {
108 + if (String.IsNullOrEmpty(tuple.Value))
109 + {
110 + return;
111 + }
112 +
113 + var table = output.EnsureTable(this.TableDefinitions["Property"]);
114 + var row = (PropertyRow)table.CreateRow(tuple.SourceLineNumbers);
115 + row.Property = tuple.Property;
116 + row.Value = tuple.Value;
117 + }
118 +
119 private void AddWixActionTuple(WixActionTuple actionRow, Output output)
120 {
121 // Get the table definition for the action (and ensure the proper table exists for a module).
src/WixToolset.Core.WindowsInstaller/Bind/ExtractMergeModuleFilesCommand.cs
+12 -15
@@ -14,7 +14,6 @@ namespace WixToolset.Core.WindowsInstaller.Bind
14 using WixToolset.Msi;
15 using WixToolset.Core.Native;
16 using WixToolset.Core.Bind;
17 - using WixToolset.Core.Cab;
17 using WixToolset.Data.Tuples;
18
19 /// <summary>
@@ -110,7 +109,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
109 wixFileRow.Directory_ = record[2];
110 wixFileRow.DiskId = wixMergeRow.DiskId;
111 wixFileRow.PatchGroup = -1;
113 - wixFileRow.Source = Path.Combine(this.IntermediateFolder, wixMergeRow.Id.Id, record[1]);
112 + wixFileRow.Source = new IntermediateFieldPathValue { Path = Path.Combine(this.IntermediateFolder, wixMergeRow.Id.Id, record[1]) };
113 //WixFileRow wixFileRow = (WixFileRow)this.WixFileTable.CreateRow(wixMergeRow.SourceLineNumbers, false);
114 //wixFileRow.Directory = record[2];
115 //wixFileRow.DiskId = wixMergeRow.DiskId;
@@ -204,20 +203,18 @@ namespace WixToolset.Core.WindowsInstaller.Bind
203 string mergeIdPath = Path.Combine(this.IntermediateFolder, mergeId);
204 Directory.CreateDirectory(mergeIdPath);
205
207 - using (var extractCab = new WixExtractCab())
206 + try
207 {
209 - try
210 - {
211 - extractCab.Extract(moduleCabPath, mergeIdPath);
212 - }
213 - catch (FileNotFoundException)
214 - {
215 - throw new WixException(WixErrors.CabFileDoesNotExist(moduleCabPath, wixMergeRow.SourceFile, mergeIdPath));
216 - }
217 - catch
218 - {
219 - throw new WixException(WixErrors.CabExtractionFailed(moduleCabPath, wixMergeRow.SourceFile, mergeIdPath));
220 - }
208 + var cabinet = new Cabinet(moduleCabPath);
209 + cabinet.Extract(mergeIdPath);
210 + }
211 + catch (FileNotFoundException)
212 + {
213 + throw new WixException(WixErrors.CabFileDoesNotExist(moduleCabPath, wixMergeRow.SourceFile, mergeIdPath));
214 + }
215 + catch
216 + {
217 + throw new WixException(WixErrors.CabExtractionFailed(moduleCabPath, wixMergeRow.SourceFile, mergeIdPath));
218 }
219 }
220 catch (COMException ce)
src/WixToolset.Core.WindowsInstaller/Bind/ProcessUncompressedFilesCommand.cs
+1 -1
@@ -105,7 +105,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
105
106 // finally put together the base media layout path and the relative file layout path
107 string fileLayoutPath = Path.Combine(mediaLayoutDirectory, relativeFileLayoutPath);
108 - if (FileTransfer.TryCreate(facade.WixFile.Source, fileLayoutPath, false, "File", facade.File.SourceLineNumbers, out var transfer))
108 + if (FileTransfer.TryCreate(facade.WixFile.Source.Path, fileLayoutPath, false, "File", facade.File.SourceLineNumbers, out var transfer))
109 {
110 fileTransfers.Add(transfer);
111 }
src/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs
+10 -10
@@ -57,27 +57,27 @@ namespace WixToolset.Core.WindowsInstaller.Bind
57 FileInfo fileInfo = null;
58 try
59 {
60 - fileInfo = new FileInfo(file.WixFile.Source);
60 + fileInfo = new FileInfo(file.WixFile.Source.Path);
61 }
62 catch (ArgumentException)
63 {
64 - Messaging.Instance.OnMessage(WixDataErrors.InvalidFileName(file.File.SourceLineNumbers, file.WixFile.Source));
64 + Messaging.Instance.OnMessage(WixDataErrors.InvalidFileName(file.File.SourceLineNumbers, file.WixFile.Source.Path));
65 return;
66 }
67 catch (PathTooLongException)
68 {
69 - Messaging.Instance.OnMessage(WixDataErrors.InvalidFileName(file.File.SourceLineNumbers, file.WixFile.Source));
69 + Messaging.Instance.OnMessage(WixDataErrors.InvalidFileName(file.File.SourceLineNumbers, file.WixFile.Source.Path));
70 return;
71 }
72 catch (NotSupportedException)
73 {
74 - Messaging.Instance.OnMessage(WixDataErrors.InvalidFileName(file.File.SourceLineNumbers, file.WixFile.Source));
74 + Messaging.Instance.OnMessage(WixDataErrors.InvalidFileName(file.File.SourceLineNumbers, file.WixFile.Source.Path));
75 return;
76 }
77
78 if (!fileInfo.Exists)
79 {
80 - Messaging.Instance.OnMessage(WixErrors.CannotFindFile(file.File.SourceLineNumbers, file.File.File, file.File.LongFileName, file.WixFile.Source));
80 + Messaging.Instance.OnMessage(WixErrors.CannotFindFile(file.File.SourceLineNumbers, file.File.File, file.File.LongFileName, file.WixFile.Source.Path));
81 return;
82 }
83
@@ -85,7 +85,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
85 {
86 if (Int32.MaxValue < fileStream.Length)
87 {
88 - throw new WixException(WixErrors.FileTooLarge(file.File.SourceLineNumbers, file.WixFile.Source));
88 + throw new WixException(WixErrors.FileTooLarge(file.File.SourceLineNumbers, file.WixFile.Source.Path));
89 }
90
91 file.File.FileSize = Convert.ToInt32(fileStream.Length, CultureInfo.InvariantCulture);
@@ -372,7 +372,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
372 // Navigator is cheaper than dom. Perhaps there is a cheaper API still.
373 try
374 {
375 - XPathDocument doc = new XPathDocument(fileManifest.WixFile.Source);
375 + XPathDocument doc = new XPathDocument(fileManifest.WixFile.Source.Path);
376 XPathNavigator nav = doc.CreateNavigator();
377 nav.MoveToRoot();
378
@@ -396,7 +396,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
396 }
397 if (!hasNextSibling)
398 {
399 - Messaging.Instance.OnMessage(WixErrors.InvalidManifestContent(file.File.SourceLineNumbers, fileManifest.WixFile.Source));
399 + Messaging.Instance.OnMessage(WixErrors.InvalidManifestContent(file.File.SourceLineNumbers, fileManifest.WixFile.Source.Path));
400 return;
401 }
402
@@ -434,11 +434,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind
434 }
435 catch (FileNotFoundException fe)
436 {
437 - Messaging.Instance.OnMessage(WixErrors.FileNotFound(new SourceLineNumber(fileManifest.WixFile.Source), fe.FileName, "AssemblyManifest"));
437 + Messaging.Instance.OnMessage(WixErrors.FileNotFound(new SourceLineNumber(fileManifest.WixFile.Source.Path), fe.FileName, "AssemblyManifest"));
438 }
439 catch (XmlException xe)
440 {
441 - Messaging.Instance.OnMessage(WixErrors.InvalidXml(new SourceLineNumber(fileManifest.WixFile.Source), "manifest", xe.Message));
441 + Messaging.Instance.OnMessage(WixErrors.InvalidXml(new SourceLineNumber(fileManifest.WixFile.Source.Path), "manifest", xe.Message));
442 }
443
444 if (!String.IsNullOrEmpty(win32Name))
src/WixToolset.Core.WindowsInstaller/Unbind/ExtractCabinetsCommand.cs
+10 -12
@@ -7,7 +7,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
7 using System.Collections.Specialized;
8 using System.Globalization;
9 using System.IO;
10 - using WixToolset.Core.Cab;
10 + using WixToolset.Core.Native;
11 using WixToolset.Data;
12 using WixToolset.Data.Rows;
13 using WixToolset.Msi;
@@ -88,9 +88,9 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
88 string cabinetFile = Path.Combine(this.IntermediateFolder, String.Concat("Media", Path.DirectorySeparatorChar, diskId.ToString(CultureInfo.InvariantCulture), ".cab"));
89
90 // ensure the parent directory exists
91 - System.IO.Directory.CreateDirectory(Path.GetDirectoryName(cabinetFile));
91 + Directory.CreateDirectory(Path.GetDirectoryName(cabinetFile));
92
93 - using (FileStream fs = System.IO.File.Create(cabinetFile))
93 + using (FileStream fs = File.Create(cabinetFile))
94 {
95 int bytesRead;
96 byte[] buffer = new byte[512];
@@ -128,16 +128,14 @@ namespace WixToolset.Core.WindowsInstaller.Unbind
128
129 foreach (string cabinetFile in cabinetFiles)
130 {
131 - using (var extractCab = new WixExtractCab())
131 + try
132 {
133 - try
134 - {
135 - extractCab.Extract(cabinetFile, fileDirectory);
136 - }
137 - catch (FileNotFoundException)
138 - {
139 - throw new WixException(WixErrors.FileNotFound(new SourceLineNumber(this.InputFilePath), cabinetFile));
140 - }
133 + var cabinet = new Cabinet(cabinetFile);
134 + cabinet.Extract(fileDirectory);
135 + }
136 + catch (FileNotFoundException)
137 + {
138 + throw new WixException(WixErrors.FileNotFound(new SourceLineNumber(this.InputFilePath), cabinetFile));
139 }
140 }
141 }
src/WixToolset.Core/Cab/CabinetFileInfo.cs deleted
-45
@@ -1,45 +0,0 @@
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.Cab
4 -{
5 - /// <summary>
6 - /// Properties of a file in a cabinet.
7 - /// </summary>
8 - public sealed class CabinetFileInfo
9 - {
10 - /// <summary>
11 - /// Constructs CabinetFileInfo
12 - /// </summary>
13 - /// <param name="fileId">File Id</param>
14 - /// <param name="date">Last modified date (MS-DOS time)</param>
15 - /// <param name="time">Last modified time (MS-DOS time)</param>
16 - public CabinetFileInfo(string fileId, ushort date, ushort time, int size)
17 - {
18 - this.FileId = fileId;
19 - this.Date = date;
20 - this.Time = time;
21 - this.Size = size;
22 - }
23 -
24 - /// <summary>
25 - /// Gets the file Id of the file.
26 - /// </summary>
27 - /// <value>file Id</value>
28 - public string FileId { get; }
29 -
30 - /// <summary>
31 - /// Gets modified date (DOS format).
32 - /// </summary>
33 - public ushort Date { get; }
34 -
35 - /// <summary>
36 - /// Gets modified time (DOS format).
37 - /// </summary>
38 - public ushort Time { get; }
39 -
40 - /// <summary>
41 - /// Gets the size of the file in bytes.
42 - /// </summary>
43 - public int Size { get; }
44 - }
45 -}
src/WixToolset.Core/Cab/Interop/CabInterop.cs deleted
-316
@@ -1,316 +0,0 @@
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 -#if false
4 -
5 -namespace WixToolset.Cab.Interop
6 -{
7 - using System;
8 - using System.Diagnostics.CodeAnalysis;
9 - using System.Text;
10 - using System.Runtime.InteropServices;
11 - using WixToolset.Msi;
12 - using WixToolset.Msi.Interop;
13 -
14 - /// <summary>
15 - /// The native methods.
16 - /// </summary>
17 - public sealed class NativeMethods
18 - {
19 - /// <summary>
20 - /// Starts creating a cabinet.
21 - /// </summary>
22 - /// <param name="cabinetName">Name of cabinet to create.</param>
23 - /// <param name="cabinetDirectory">Directory to create cabinet in.</param>
24 - /// <param name="maxFiles">Maximum number of files that will be added to cabinet.</param>
25 - /// <param name="maxSize">Maximum size of the cabinet.</param>
26 - /// <param name="maxThreshold">Maximum threshold in the cabinet.</param>
27 - /// <param name="compressionType">Type of compression to use in the cabinet.</param>
28 - /// <param name="contextHandle">Handle to opened cabinet.</param>
29 - [DllImport("winterop.dll", EntryPoint = "CreateCabBegin", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
30 - internal static extern void CreateCabBegin(string cabinetName, string cabinetDirectory, uint maxFiles, uint maxSize, uint maxThreshold, uint compressionType, out IntPtr contextHandle);
31 -
32 - /// <summary>
33 - /// Adds a file to an open cabinet.
34 - /// </summary>
35 - /// <param name="file">Full path to file to add to cabinet.</param>
36 - /// <param name="token">Name of file in cabinet.</param>
37 - /// <param name="contextHandle">Handle to open cabinet.</param>
38 - [DllImport("winterop.dll", EntryPoint = "CreateCabAddFile", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
39 - internal static extern void CreateCabAddFile(string file, string token, MsiInterop.MSIFILEHASHINFO fileHash, IntPtr contextHandle);
40 -
41 - /// <summary>
42 - /// Closes a cabinet.
43 - /// </summary>
44 - /// <param name="contextHandle">Handle to open cabinet to close.</param>
45 - /// <param name="newCabNamesCallBackAddress">Address of Binder's cabinet split callback</param>
46 - [DllImport("winterop.dll", EntryPoint = "CreateCabFinish", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
47 - internal static extern void CreateCabFinish(IntPtr contextHandle, IntPtr newCabNamesCallBackAddress);
48 -
49 - /// <summary>
50 - /// Cancels cabinet creation.
51 - /// </summary>
52 - /// <param name="contextHandle">Handle to open cabinet to cancel.</param>
53 - [DllImport("winterop.dll", EntryPoint = "CreateCabCancel", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
54 - internal static extern void CreateCabCancel(IntPtr contextHandle);
55 -
56 - /// <summary>
57 - /// Initializes cabinet extraction.
58 - /// </summary>
59 - [DllImport("winterop.dll", EntryPoint = "ExtractCabBegin", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
60 - internal static extern void ExtractCabBegin();
61 -
62 - /// <summary>
63 - /// Extracts files from cabinet.
64 - /// </summary>
65 - /// <param name="cabinet">Path to cabinet to extract files from.</param>
66 - /// <param name="extractDirectory">Directory to extract files to.</param>
67 - [DllImport("winterop.dll", EntryPoint = "ExtractCab", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true, PreserveSig = false)]
68 - internal static extern void ExtractCab(string cabinet, string extractDirectory);
69 -
70 - /// <summary>
71 - /// Cleans up after cabinet extraction.
72 - /// </summary>
73 - [DllImport("winterop.dll", EntryPoint = "ExtractCabFinish", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
74 - internal static extern void ExtractCabFinish();
75 -
76 - /// <summary>
77 - /// Initializes cabinet enumeration.
78 - /// </summary>
79 - [DllImport("winterop.dll", EntryPoint = "EnumerateCabBegin", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
80 - internal static extern void EnumerateCabBegin();
81 -
82 - /// <summary>
83 - /// Enumerates files from cabinet.
84 - /// </summary>
85 - /// <param name="cabinet">Path to cabinet to enumerate files from.</param>
86 - /// <param name="notify">callback that gets each file.</param>
87 - [DllImport("winterop.dll", EntryPoint = "EnumerateCab", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true, PreserveSig = false)]
88 - internal static extern void EnumerateCab(string cabinet, CabInterop.PFNNOTIFY notify);
89 -
90 - /// <summary>
91 - /// Cleans up after cabinet enumeration.
92 - /// </summary>
93 - [DllImport("winterop.dll", EntryPoint = "EnumerateCabFinish", CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
94 - internal static extern void EnumerateCabFinish();
95 -
96 - /// <summary>
97 - /// Resets the DACL on an array of files to "empty".
98 - /// </summary>
99 - /// <param name="files">Array of file reset ACL to "empty".</param>
100 - /// <param name="fileCount">Number of file paths in array.</param>
101 - [DllImport("winterop.dll", EntryPoint = "ResetAcls", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
102 - internal static extern void ResetAcls(string[] files, uint fileCount);
103 -
104 - /// <summary>
105 - /// Gets the hash of the pCertContext->pCertInfo->SubjectPublicKeyInfo using ::CryptHashPublicKeyInfo() which does not seem
106 - /// to be exposed by .NET Frameowkr.
107 - /// </summary>
108 - /// <param name="certContext">Pointer to a CERT_CONTEXT struct with public key information to hash.</param>
109 - /// <param name="fileCount">Number of file paths in array.</param>
110 - [DllImport("winterop.dll", EntryPoint = "HashPublicKeyInfo", CharSet = CharSet.Unicode, ExactSpelling = true, PreserveSig = false)]
111 - internal static extern void HashPublicKeyInfo(IntPtr certContext, byte[] publicKeyInfoHashed, ref uint sizePublicKeyInfoHashed);
112 -
113 - /// <summary>
114 - /// Converts file time to a local file time.
115 - /// </summary>
116 - /// <param name="fileTime">file time</param>
117 - /// <param name="localTime">local file time</param>
118 - /// <returns>true if successful, false otherwise</returns>
119 - [DllImport("kernel32.dll", SetLastError = true)]
120 - [return: MarshalAs(UnmanagedType.Bool)]
121 - internal static extern bool FileTimeToLocalFileTime(ref long fileTime, ref long localTime);
122 -
123 - /// <summary>
124 - /// Converts file time to a MS-DOS time.
125 - /// </summary>
126 - /// <param name="fileTime">file time</param>
127 - /// <param name="wFatDate">MS-DOS date</param>
128 - /// <param name="wFatTime">MS-DOS time</param>
129 - /// <returns>true if successful, false otherwise</returns>
130 - [DllImport("kernel32.dll", SetLastError = true)]
131 - [return: MarshalAs(UnmanagedType.Bool)]
132 - internal static extern bool FileTimeToDosDateTime(ref long fileTime, out ushort wFatDate, out ushort wFatTime);
133 - }
134 -
135 - /// <summary>
136 - /// Interop class for the winterop.dll.
137 - /// </summary>
138 - internal static class CabInterop
139 - {
140 - /// <summary>
141 - /// Delegate type that's called by cabinet api for every file in cabinet.
142 - /// </summary>
143 - /// <param name="fdint">NOTIFICATIONTYPE</param>
144 - /// <param name="pfdin">NOTIFICATION</param>
145 - /// <returns>0 for success, -1 otherwise</returns>
146 - public delegate Int32 PFNNOTIFY(NOTIFICATIONTYPE fdint, NOTIFICATION pfdin);
147 -
148 - /// <summary>
149 - /// Wraps FDINOTIFICATIONTYPE.
150 - /// </summary>
151 - public enum NOTIFICATIONTYPE : int
152 - {
153 - /// <summary>Info about the cabinet.</summary>
154 - CABINET_INFO,
155 - /// <summary>One or more files are continued.</summary>
156 - PARTIAL_FILE,
157 - /// <summary>Called for each file in cabinet.</summary>
158 - COPY_FILE,
159 - /// <summary>Called after all of the data has been written to a target file.</summary>
160 - CLOSE_FILE_INFO,
161 - /// <summary>A file is continued to the next cabinet.</summary>
162 - NEXT_CABINET,
163 - /// <summary>Called once after a call to FDICopy() starts scanning a CAB's CFFILE entries, and again when there are no more CFFILE entries.</summary>
164 - ENUMERATE,
165 - }
166 -
167 - /// <summary>
168 - /// Converts DateTime to MS-DOS date and time which cabinet uses.
169 - /// </summary>
170 - /// <param name="dateTime">DateTime</param>
171 - /// <param name="cabDate">MS-DOS date</param>
172 - /// <param name="cabTime">MS-DOS time</param>
173 - public static void DateTimeToCabDateAndTime(DateTime dateTime, out ushort cabDate, out ushort cabTime)
174 - {
175 - // dateTime.ToLocalTime() does not match FileTimeToLocalFileTime() for some reason.
176 - // so we need to call FileTimeToLocalFileTime() from kernel32.dll.
177 - long filetime = dateTime.ToFileTime();
178 - long localTime = 0;
179 - NativeMethods.FileTimeToLocalFileTime(ref filetime, ref localTime);
180 - NativeMethods.FileTimeToDosDateTime(ref localTime, out cabDate, out cabTime);
181 - }
182 -
183 - /// <summary>
184 - /// Wraps FDINOTIFICATION.
185 - /// </summary>
186 - [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")]
187 - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
188 - public class NOTIFICATION
189 - {
190 - private int cb;
191 - [MarshalAs(UnmanagedType.LPStr)]
192 - private string psz1;
193 - [MarshalAs(UnmanagedType.LPStr)]
194 - private string psz2;
195 - [MarshalAs(UnmanagedType.LPStr)]
196 - private string psz3;
197 - private IntPtr pv;
198 -
199 - private IntPtr hf;
200 -
201 - private ushort date;
202 - private ushort time;
203 - private ushort attribs;
204 - private ushort setID;
205 - private ushort cabinet;
206 - private ushort folder;
207 - private int fdie;
208 -
209 - /// <summary>
210 - /// Uncompressed size of file.
211 - /// </summary>
212 - public int Cb
213 - {
214 - get { return this.cb; }
215 - }
216 -
217 - /// <summary>
218 - /// File name in cabinet.
219 - /// </summary>
220 - public String Psz1
221 - {
222 - get { return this.psz1; }
223 - }
224 -
225 - /// <summary>
226 - /// Name of next disk.
227 - /// </summary>
228 - public string Psz2
229 - {
230 - get { return this.psz2; }
231 - }
232 -
233 - /// <summary>
234 - /// Points to a 256 character buffer.
235 - /// </summary>
236 - public string Psz3
237 - {
238 - get { return this.psz3; }
239 - }
240 -
241 - /// <summary>
242 - /// Value for client.
243 - /// </summary>
244 - public IntPtr Pv
245 - {
246 - get { return this.pv; }
247 - }
248 -
249 - /// <summary>
250 - /// Not used.
251 - /// </summary>
252 - public Int32 Hf
253 - {
254 - get { return (Int32)this.hf; }
255 - }
256 -
257 - /// <summary>
258 - /// Last modified MS-DOS date.
259 - /// </summary>
260 - public ushort Date
261 - {
262 - get { return this.date; }
263 - }
264 -
265 - /// <summary>
266 - /// Last modified MS-DOS time.
267 - /// </summary>
268 - public ushort Time
269 - {
270 - get { return this.time; }
271 - }
272 -
273 - /// <summary>
274 - /// File attributes.
275 - /// </summary>
276 - public ushort Attribs
277 - {
278 - get { return this.attribs; }
279 - }
280 -
281 - /// <summary>
282 - /// Cabinet set ID (a random 16-bit number).
283 - /// </summary>
284 - public ushort SetID
285 - {
286 - get { return this.setID; }
287 - }
288 -
289 - /// <summary>
290 - /// Cabinet number within cabinet set (0-based).
291 - /// </summary>
292 - public ushort Cabinet
293 - {
294 - get { return this.cabinet; }
295 - }
296 -
297 - /// <summary>
298 - /// File's folder index.
299 - /// </summary>
300 - public ushort Folder
301 - {
302 - get { return this.folder; }
303 - }
304 -
305 - /// <summary>
306 - /// Error code.
307 - /// </summary>
308 - public int Fdie
309 - {
310 - get { return this.fdie; }
311 - }
312 - }
313 - }
314 -}
315 -
316 -#endif
src/WixToolset.Core/Cab/WixCreateCab.cs deleted
-249
@@ -1,249 +0,0 @@
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.Cab
4 -{
5 - using System;
6 - using System.Globalization;
7 - using System.IO;
8 - using System.Runtime.InteropServices;
9 - using WixToolset.Core.Bind;
10 - using WixToolset.Core.Native;
11 - using WixToolset.Data;
12 -
13 - /// <summary>
14 - /// Wrapper class around interop with wixcab.dll to compress files into a cabinet.
15 - /// </summary>
16 - public sealed class WixCreateCab : IDisposable
17 - {
18 - private static readonly string CompressionLevelVariable = "WIX_COMPRESSION_LEVEL";
19 - private IntPtr handle = IntPtr.Zero;
20 - private bool disposed;
21 - private int maxSize;
22 -
23 - /// <summary>
24 - /// Creates a cabinet.
25 - /// </summary>
26 - /// <param name="cabName">Name of cabinet to create.</param>
27 - /// <param name="cabDir">Directory to create cabinet in.</param>
28 - /// <param name="maxFiles">Maximum number of files that will be added to cabinet.</param>
29 - /// <param name="maxSize">Maximum size of cabinet.</param>
30 - /// <param name="maxThresh">Maximum threshold for each cabinet.</param>
31 - /// <param name="compressionLevel">Level of compression to apply.</param>
32 - public WixCreateCab(string cabName, string cabDir, int maxFiles, int maxSize, int maxThresh, CompressionLevel compressionLevel)
33 - {
34 - string compressionLevelVariable = Environment.GetEnvironmentVariable(CompressionLevelVariable);
35 - this.maxSize = maxSize;
36 -
37 - try
38 - {
39 - // Override authored compression level if environment variable is present.
40 - if (!String.IsNullOrEmpty(compressionLevelVariable))
41 - {
42 - compressionLevel = WixCreateCab.CompressionLevelFromString(compressionLevelVariable);
43 - }
44 - }
45 - catch (WixException)
46 - {
47 - throw new WixException(WixErrors.IllegalEnvironmentVariable(CompressionLevelVariable, compressionLevelVariable));
48 - }
49 -
50 - if (String.IsNullOrEmpty(cabDir))
51 - {
52 - cabDir = Directory.GetCurrentDirectory();
53 - }
54 -
55 - try
56 - {
57 - NativeMethods.CreateCabBegin(cabName, cabDir, (uint)maxFiles, (uint)maxSize, (uint)maxThresh, (uint)compressionLevel, out this.handle);
58 - }
59 - catch (COMException ce)
60 - {
61 - // If we get a "the file exists" error, we must have a full temp directory - so report the issue
62 - if (0x80070050 == unchecked((uint)ce.ErrorCode))
63 - {
64 - throw new WixException(WixErrors.FullTempDirectory("WSC", Path.GetTempPath()));
65 - }
66 -
67 - throw;
68 - }
69 - }
70 -
71 - /// <summary>
72 - /// Destructor for cabinet creation.
73 - /// </summary>
74 - ~WixCreateCab()
75 - {
76 - this.Dispose();
77 - }
78 -
79 - /// <summary>
80 - /// Converts a compression level from its string to its enum value.
81 - /// </summary>
82 - /// <param name="compressionLevel">Compression level as a string.</param>
83 - /// <returns>CompressionLevel enum value</returns>
84 - public static CompressionLevel CompressionLevelFromString(string compressionLevel)
85 - {
86 - switch (compressionLevel.ToLower(CultureInfo.InvariantCulture))
87 - {
88 - case "low":
89 - return CompressionLevel.Low;
90 - case "medium":
91 - return CompressionLevel.Medium;
92 - case "high":
93 - return CompressionLevel.High;
94 - case "none":
95 - return CompressionLevel.None;
96 - case "mszip":
97 - return CompressionLevel.Mszip;
98 - default:
99 - throw new WixException(WixErrors.IllegalCompressionLevel(compressionLevel));
100 - }
101 - }
102 -
103 - /// <summary>
104 - /// Adds a file to the cabinet.
105 - /// </summary>
106 - /// <param name="fileFacade">The file facade of the file to add.</param>
107 - public void AddFile(FileFacade fileFacade)
108 - {
109 - MsiInterop.MSIFILEHASHINFO hashInterop = new MsiInterop.MSIFILEHASHINFO();
110 -
111 - if (null != fileFacade.Hash)
112 - {
113 - hashInterop.FileHashInfoSize = 20;
114 - hashInterop.Data0 = (int)fileFacade.Hash[2];
115 - hashInterop.Data1 = (int)fileFacade.Hash[3];
116 - hashInterop.Data2 = (int)fileFacade.Hash[4];
117 - hashInterop.Data3 = (int)fileFacade.Hash[5];
118 -
119 - this.AddFile(fileFacade.WixFile.Source, fileFacade.File.File, hashInterop);
120 - }
121 - else
122 - {
123 - this.AddFile(fileFacade.WixFile.Source, fileFacade.File.File);
124 - }
125 - }
126 -
127 - /// <summary>
128 - /// Adds a file to the cabinet.
129 - /// </summary>
130 - /// <param name="file">The file to add.</param>
131 - /// <param name="token">The token for the file.</param>
132 - public void AddFile(string file, string token)
133 - {
134 - this.AddFile(file, token, null);
135 - }
136 -
137 - /// <summary>
138 - /// Adds a file to the cabinet with an optional MSI file hash.
139 - /// </summary>
140 - /// <param name="file">The file to add.</param>
141 - /// <param name="token">The token for the file.</param>
142 - /// <param name="fileHash">The MSI file hash of the file.</param>
143 - private void AddFile(string file, string token, MsiInterop.MSIFILEHASHINFO fileHash)
144 - {
145 - try
146 - {
147 - NativeMethods.CreateCabAddFile(file, token, fileHash, this.handle);
148 - }
149 - catch (COMException ce)
150 - {
151 - if (0x80004005 == unchecked((uint)ce.ErrorCode)) // E_FAIL
152 - {
153 - throw new WixException(WixErrors.CreateCabAddFileFailed());
154 - }
155 - else if (0x80070070 == unchecked((uint)ce.ErrorCode)) // ERROR_DISK_FULL
156 - {
157 - throw new WixException(WixErrors.CreateCabInsufficientDiskSpace());
158 - }
159 - else
160 - {
161 - throw;
162 - }
163 - }
164 - catch (DirectoryNotFoundException)
165 - {
166 - throw new WixFileNotFoundException(file);
167 - }
168 - catch (FileNotFoundException)
169 - {
170 - throw new WixFileNotFoundException(file);
171 - }
172 - }
173 -
174 - /// <summary>
175 - /// Complete/commit the cabinet - this must be called before Dispose so that errors will be
176 - /// reported on the same thread.
177 - /// This Complete should be used with no Cabinet splitting as it has the split cabinet names callback address as Zero
178 - /// </summary>
179 - public void Complete()
180 - {
181 - this.Complete(IntPtr.Zero);
182 - }
183 -
184 - /// <summary>
185 - /// Complete/commit the cabinet - this must be called before Dispose so that errors will be
186 - /// reported on the same thread.
187 - /// </summary>
188 - /// <param name="newCabNamesCallBackAddress">Address of Binder's callback function for Cabinet Splitting</param>
189 - public void Complete(IntPtr newCabNamesCallBackAddress)
190 - {
191 - if (IntPtr.Zero != this.handle)
192 - {
193 - try
194 - {
195 - if (newCabNamesCallBackAddress != IntPtr.Zero && this.maxSize != 0)
196 - {
197 - NativeMethods.CreateCabFinish(this.handle, newCabNamesCallBackAddress);
198 - }
199 - else
200 - {
201 - NativeMethods.CreateCabFinish(this.handle, IntPtr.Zero);
202 - }
203 -
204 - GC.SuppressFinalize(this);
205 - this.disposed = true;
206 - }
207 - catch (COMException ce)
208 - {
209 - if (0x80004005 == unchecked((uint)ce.ErrorCode)) // E_FAIL
210 - {
211 - // This error seems to happen, among other situations, when cabbing more than 0xFFFF files
212 - throw new WixException(WixErrors.FinishCabFailed());
213 - }
214 - else if (0x80070070 == unchecked((uint)ce.ErrorCode)) // ERROR_DISK_FULL
215 - {
216 - throw new WixException(WixErrors.CreateCabInsufficientDiskSpace());
217 - }
218 - else
219 - {
220 - throw;
221 - }
222 - }
223 - finally
224 - {
225 - this.handle = IntPtr.Zero;
226 - }
227 - }
228 - }
229 -
230 - /// <summary>
231 - /// Cancels ("rolls back") the creation of the cabinet.
232 - /// Don't throw WiX errors from here, because we're in a different thread, and they won't be reported correctly.
233 - /// </summary>
234 - public void Dispose()
235 - {
236 - if (!this.disposed)
237 - {
238 - if (IntPtr.Zero != this.handle)
239 - {
240 - NativeMethods.CreateCabCancel(this.handle);
241 - this.handle = IntPtr.Zero;
242 - }
243 -
244 - GC.SuppressFinalize(this);
245 - this.disposed = true;
246 - }
247 - }
248 - }
249 -}
src/WixToolset.Core/Cab/WixEnumerateCab.cs deleted
-89
@@ -1,89 +0,0 @@
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.Cab
4 -{
5 - using System;
6 - using System.Collections.Generic;
7 - using WixToolset.Core.Native;
8 - using Handle = System.Int32;
9 -
10 - /// <summary>
11 - /// Wrapper class around interop with wixcab.dll to enumerate files from a cabinet.
12 - /// </summary>
13 - public sealed class WixEnumerateCab : IDisposable
14 - {
15 - private bool disposed;
16 - private List<CabinetFileInfo> fileInfoList;
17 - private CabInterop.PFNNOTIFY pfnNotify;
18 -
19 - /// <summary>
20 - /// Creates a cabinet enumerator.
21 - /// </summary>
22 - public WixEnumerateCab()
23 - {
24 - this.pfnNotify = new CabInterop.PFNNOTIFY(this.Notify);
25 - NativeMethods.EnumerateCabBegin();
26 - }
27 -
28 - /// <summary>
29 - /// Destructor for cabinet enumeration.
30 - /// </summary>
31 - ~WixEnumerateCab()
32 - {
33 - this.Dispose();
34 - }
35 -
36 - /// <summary>
37 - /// Enumerates all files in a cabinet.
38 - /// </summary>
39 - /// <param name="cabinetFile">path to cabinet</param>
40 - /// <returns>list of CabinetFileInfo</returns>
41 - public List<CabinetFileInfo> Enumerate(string cabinetFile)
42 - {
43 - this.fileInfoList = new List<CabinetFileInfo>();
44 -
45 - // the callback (this.Notify) will populate the list for each file in cabinet
46 - NativeMethods.EnumerateCab(cabinetFile, this.pfnNotify);
47 -
48 - return this.fileInfoList;
49 - }
50 -
51 - /// <summary>
52 - /// Disposes the managed and unmanaged objects in this object.
53 - /// </summary>
54 - public void Dispose()
55 - {
56 - if (!this.disposed)
57 - {
58 - NativeMethods.EnumerateCabFinish();
59 -
60 - GC.SuppressFinalize(this);
61 - this.disposed = true;
62 - }
63 - }
64 -
65 - /// <summary>
66 - /// Delegate that's called for every file in cabinet.
67 - /// </summary>
68 - /// <param name="fdint">NOTIFICATIONTYPE</param>
69 - /// <param name="pfdin">NOTIFICATION</param>
70 - /// <returns>System.Int32</returns>
71 - internal Handle Notify(CabInterop.NOTIFICATIONTYPE fdint, CabInterop.NOTIFICATION pfdin)
72 - {
73 - // This is FDI's way of notifying us of how many files total are in the cab, accurate even
74 - // if the files are split into multiple folders - use it to allocate the precise size we need
75 - if (CabInterop.NOTIFICATIONTYPE.ENUMERATE == fdint && 0 == this.fileInfoList.Count)
76 - {
77 - this.fileInfoList.Capacity = pfdin.Folder;
78 - }
79 -
80 - if (fdint == CabInterop.NOTIFICATIONTYPE.COPY_FILE)
81 - {
82 - CabinetFileInfo fileInfo = new CabinetFileInfo(pfdin.Psz1, pfdin.Date, pfdin.Time, pfdin.Cb);
83 - this.fileInfoList.Add(fileInfo);
84 - }
85 -
86 - return 0; // tell cabinet api to skip this file.
87 - }
88 - }
89 -}
src/WixToolset.Core/Cab/WixExtractCab.cs deleted
-75
@@ -1,75 +0,0 @@
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.Cab
4 -{
5 - using System;
6 - using WixToolset.Core.Native;
7 -
8 - /// <summary>
9 - /// Wrapper class around interop with wixcab.dll to extract files from a cabinet.
10 - /// </summary>
11 - public sealed class WixExtractCab : IDisposable
12 - {
13 - private bool disposed;
14 -
15 - /// <summary>
16 - /// Creates a cabinet extractor.
17 - /// </summary>
18 - public WixExtractCab()
19 - {
20 - NativeMethods.ExtractCabBegin();
21 - }
22 -
23 - /// <summary>
24 - /// Destructor for cabinet extraction.
25 - /// </summary>
26 - ~WixExtractCab()
27 - {
28 - this.Dispose();
29 - }
30 -
31 - /// <summary>
32 - /// Extracts all the files from a cabinet to a directory.
33 - /// </summary>
34 - /// <param name="cabinetFile">Cabinet file to extract from.</param>
35 - /// <param name="extractDir">Directory to extract files to.</param>
36 - public void Extract(string cabinetFile, string extractDir)
37 - {
38 - if (null == cabinetFile)
39 - {
40 - throw new ArgumentNullException("cabinetFile");
41 - }
42 -
43 - if (null == extractDir)
44 - {
45 - throw new ArgumentNullException("extractDir");
46 - }
47 -
48 - if (this.disposed)
49 - {
50 - throw new ObjectDisposedException("WixExtractCab");
51 - }
52 -
53 - if (!extractDir.EndsWith("\\", StringComparison.Ordinal))
54 - {
55 - extractDir = String.Concat(extractDir, "\\");
56 - }
57 -
58 - NativeMethods.ExtractCab(cabinetFile, extractDir);
59 - }
60 -
61 - /// <summary>
62 - /// Disposes the managed and unmanaged objects in this object.
63 - /// </summary>
64 - public void Dispose()
65 - {
66 - if (!this.disposed)
67 - {
68 - NativeMethods.ExtractCabFinish();
69 -
70 - GC.SuppressFinalize(this);
71 - this.disposed = true;
72 - }
73 - }
74 - }
75 -}
src/WixToolset.Core/Compiler.cs
+1 -1
@@ -5803,7 +5803,7 @@ namespace WixToolset.Core
5803 wixFileRow.File_AssemblyApplication = assemblyApplication;
5804 wixFileRow.Directory_ = directoryId;
5805 wixFileRow.DiskId = (CompilerConstants.IntegerNotSet == diskId) ? 0 : diskId;
5806 - wixFileRow.Source = source;
5806 + wixFileRow.Source = new IntermediateFieldPathValue { Path = source };
5807 wixFileRow.ProcessorArchitecture = procArch;
5808 wixFileRow.PatchGroup = (CompilerConstants.IntegerNotSet != patchGroup ? patchGroup : -1);
5809 wixFileRow.Attributes = (generatedShortFileName ? 0x1 : 0x0);
src/WixToolset.Core/Link/ResolveReferencesCommand.cs
+1 -1
@@ -62,7 +62,7 @@ namespace WixToolset.Link
62 {
63 // If we're building a Merge Module, ignore all references to the Media table
64 // because Merge Modules don't have Media tables.
65 - if (this.BuildingMergeModule && wixSimpleReferenceRow.Definition.Type == TupleDefinitionType.Media)
65 + if (this.BuildingMergeModule && wixSimpleReferenceRow.Table== "Media")
66 {
67 continue;
68 }
src/WixToolset.Core/Preprocess/IfContext.cs
+10 -46
@@ -1,46 +1,21 @@
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.Preprocess
3 +namespace WixToolset.Core.Preprocess
4 {
5 - using System;
6 -
7 - /// <summary>
8 - /// Current state of the if context.
9 - /// </summary>
10 - internal enum IfState
11 - {
12 - /// <summary>Context currently in unknown state.</summary>
13 - Unknown,
14 -
15 - /// <summary>Context currently inside if statement.</summary>
16 - If,
17 -
18 - /// <summary>Context currently inside elseif statement..</summary>
19 - ElseIf,
20 -
21 - /// <summary>Conext currently inside else statement.</summary>
22 - Else,
23 - }
24 -
5 /// <summary>
6 /// Context for an if statement in the preprocessor.
7 /// </summary>
8 internal sealed class IfContext
9 {
30 - private bool active;
10 private bool keep;
32 - private bool everKept;
33 - private IfState state;
11
12 /// <summary>
13 /// Creates a default if context object, which are used for if's within an inactive preprocessor block
14 /// </summary>
15 public IfContext()
16 {
40 - this.active = false;
41 - this.keep = false;
42 - this.everKept = true;
43 - this.state = IfState.If;
17 + this.WasEverTrue = true;
18 + this.IfState = IfState.If;
19 }
20
21 /// <summary>
@@ -51,21 +26,17 @@ namespace WixToolset.Preprocess
26 /// <param name="state">State of context to start in.</param>
27 public IfContext(bool active, bool keep, IfState state)
28 {
54 - this.active = active;
29 + this.Active = active;
30 this.keep = keep;
56 - this.everKept = keep;
57 - this.state = state;
31 + this.WasEverTrue = keep;
32 + this.IfState = IfState.If;
33 }
34
35 /// <summary>
36 /// Gets and sets if this if context is currently active.
37 /// </summary>
38 /// <value>true if context is active.</value>
64 - public bool Active
65 - {
66 - get { return this.active; }
67 - set { this.active = value; }
68 - }
39 + public bool Active { get; set; }
40
41 /// <summary>
42 /// Gets and sets if context is current true.
@@ -83,7 +54,7 @@ namespace WixToolset.Preprocess
54 this.keep = value;
55 if (this.keep)
56 {
86 - this.everKept = true;
57 + this.WasEverTrue = true;
58 }
59 }
60 }
@@ -92,19 +63,12 @@ namespace WixToolset.Preprocess
63 /// Gets if the context was ever true.
64 /// </summary>
65 /// <value>True if context was ever true.</value>
95 - public bool WasEverTrue
96 - {
97 - get { return this.everKept; }
98 - }
66 + public bool WasEverTrue { get; private set; }
67
68 /// <summary>
69 /// Gets the current state of the if context.
70 /// </summary>
71 /// <value>Current state of context.</value>
104 - public IfState IfState
105 - {
106 - get { return this.state; }
107 - set { this.state = value; }
108 - }
72 + public IfState IfState { get; set; }
73 }
74 }
src/WixToolset.Core/Preprocess/IfState.cs new
+22
@@ -0,0 +1,22 @@
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.Preprocess
4 +{
5 + /// <summary>
6 + /// Current state of the if context.
7 + /// </summary>
8 + internal enum IfState
9 + {
10 + /// <summary>Context currently in unknown state.</summary>
11 + Unknown,
12 +
13 + /// <summary>Context currently inside if statement.</summary>
14 + If,
15 +
16 + /// <summary>Context currently inside elseif statement..</summary>
17 + ElseIf,
18 +
19 + /// <summary>Conext currently inside else statement.</summary>
20 + Else,
21 + }
22 +}
src/WixToolset.Core/Preprocessor.cs
+1 -1
@@ -13,7 +13,7 @@ namespace WixToolset.Core
13 using System.Xml.Linq;
14 using WixToolset.Data;
15 using WixToolset.Extensibility;
16 - using WixToolset.Preprocess;
16 + using WixToolset.Core.Preprocess;
17
18 /// <summary>
19 /// Preprocessor object
src/WixToolset.Data.WindowsInstaller/ColumnDefinition.cs
+2 -1
@@ -975,7 +975,8 @@ namespace WixToolset.Data
975 {
976 if (!(value is string))
977 {
978 - throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Cannot set string column '{0}' with a value of type '{1}'.", this.name, value.GetType().ToString()));
978 + //throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Cannot set string column '{0}' with a value of type '{1}'.", this.name, value.GetType().ToString()));
979 + return value.ToString();
980 }
981 }
982 }
src/test/WixToolsetTest.CoreIntegrationFixture/ProgramFixture.cs
+47
@@ -39,5 +39,52 @@ namespace WixToolsetTest.CoreIntegrationFixture
39 Assert.Equal(@"test.txt", wixFile[WixFileTupleFields.Source].PreviousValue.AsPath().Path);
40 }
41 }
42 +
43 + [Fact]
44 + public void CanBuildSimpleModule()
45 + {
46 + var folder = TestData.Get(@"TestData\SimpleModule");
47 +
48 + using (var fs = new DisposableFileSystem())
49 + using (var pushd = new Pushd(folder))
50 + {
51 + var intermediateFolder = fs.GetFolder();
52 +
53 + var program = new Program();
54 + var result = program.Run(new WixToolsetServiceProvider(), new[] { "build", "Module.wxs", "-loc", "Module.en-us.wxl", "-bindpath", "data", "-intermediateFolder", intermediateFolder, "-o", $@"{intermediateFolder}\bin\test.msm" });
55 +
56 + Assert.Equal(0, result);
57 +
58 + Assert.True(File.Exists(Path.Combine(intermediateFolder, @"bin\test.msm")));
59 + Assert.True(File.Exists(Path.Combine(intermediateFolder, @"bin\test.wixpdb")));
60 +
61 + var intermediate = Intermediate.Load(Path.Combine(intermediateFolder, @"bin\test.wir"));
62 + Assert.Single(intermediate.Sections);
63 +
64 + var wixFile = intermediate.Sections.SelectMany(s => s.Tuples).OfType<WixFileTuple>().Single();
65 + Assert.Equal(@"data\test.txt", wixFile[WixFileTupleFields.Source].AsPath().Path);
66 + Assert.Equal(@"test.txt", wixFile[WixFileTupleFields.Source].PreviousValue.AsPath().Path);
67 + }
68 + }
69 +
70 + [Fact(Skip = "Not implemented yet.")]
71 + public void CanBuildInstanceTransform()
72 + {
73 + var folder = TestData.Get(@"TestData\InstanceTransform");
74 +
75 + using (var fs = new DisposableFileSystem())
76 + using (var pushd = new Pushd(folder))
77 + {
78 + var intermediateFolder = fs.GetFolder();
79 +
80 + var program = new Program();
81 + var result = program.Run(new WixToolsetServiceProvider(), new[] { "build", "Package.wxs", "PackageComponents.wxs", "-loc", "Package.en-us.wxl", "-bindpath", "data", "-intermediateFolder", intermediateFolder, "-o", $@"{intermediateFolder}\bin\test.msi" });
82 +
83 + Assert.Equal(0, result);
84 +
85 + var pdb = Pdb.Load(Path.Combine(intermediateFolder, @"bin\test.wixpdb"), false);
86 + Assert.NotEmpty(pdb.Output.SubStorages);
87 + }
88 + }
89 }
90 }
src/test/WixToolsetTest.CoreIntegrationFixture/TestData/InstanceTransform/Package.en-us.wxl new
+11
@@ -0,0 +1,11 @@
1 +<?xml version="1.0" encoding="utf-8"?>
2 +
3 +<!--
4 +This file contains the declaration of all the localizable strings.
5 +-->
6 +<WixLocalization xmlns="http://wixtoolset.org/schemas/v4/wxl" Culture="en-US">
7 +
8 + <String Id="DowngradeError">A newer version of [ProductName] is already installed.</String>
9 + <String Id="FeatureTitle">MsiPackage</String>
10 +
11 +</WixLocalization>
src/test/WixToolsetTest.CoreIntegrationFixture/TestData/InstanceTransform/Package.wxs new
+27
@@ -0,0 +1,27 @@
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 + <Product Id="*" Name="MsiPackage" Language="1033" Version="1.0.0.0" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a">
4 + <Package InstallerVersion="200" Compressed="no" InstallScope="perMachine" />
5 +
6 + <MajorUpgrade DowngradeErrorMessage="!(loc.DowngradeError)" />
7 + <MediaTemplate />
8 +
9 + <Property Id="INSTANCEPROPERTY" Secure="yes" />
10 +
11 + <InstanceTransforms Property="INSTANCEPROPERTY">
12 + <Instance Id="I1" ProductCode="*" ProductName="MsiPackage (Instance 1)" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a" />
13 + </InstanceTransforms>
14 +
15 + <Feature Id="ProductFeature" Title="!(loc.FeatureTitle)">
16 + <ComponentGroupRef Id="ProductComponents" />
17 + </Feature>
18 + </Product>
19 +
20 + <Fragment>
21 + <Directory Id="TARGETDIR" Name="SourceDir">
22 + <Directory Id="ProgramFilesFolder">
23 + <Directory Id="INSTALLFOLDER" Name="MsiPackageInstance" />
24 + </Directory>
25 + </Directory>
26 + </Fragment>
27 +</Wix>
src/test/WixToolsetTest.CoreIntegrationFixture/TestData/InstanceTransform/PackageComponents.wxs new
+10
@@ -0,0 +1,10 @@
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 + <Fragment>
4 + <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
5 + <Component>
6 + <File Source="test.txt" />
7 + </Component>
8 + </ComponentGroup>
9 + </Fragment>
10 +</Wix>
src/test/WixToolsetTest.CoreIntegrationFixture/TestData/InstanceTransform/data/test.txt new
+1
@@ -0,0 +1 @@
1 +This is test.txt.
\ No newline at end of file
src/test/WixToolsetTest.CoreIntegrationFixture/TestData/SimpleModule/Module.en-us.wxl new
+10
@@ -0,0 +1,10 @@
1 +<?xml version="1.0" encoding="utf-8"?>
2 +
3 +<!--
4 +This file contains the declaration of all the localizable strings.
5 +-->
6 +<WixLocalization xmlns="http://wixtoolset.org/schemas/v4/wxl" Culture="en-US">
7 +
8 + <String Id="Manufacturer">Example Company</String>
9 +
10 +</WixLocalization>
src/test/WixToolsetTest.CoreIntegrationFixture/TestData/SimpleModule/Module.wixproj new
+48
@@ -0,0 +1,48 @@
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 + <PropertyGroup>
4 + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 + <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
6 + <ProductVersion>0.9</ProductVersion>
7 + <ProjectGuid>27df04c6-3cef-4b9a-bac6-4e78d188384f</ProjectGuid>
8 + <OutputName>MergeModule1</OutputName>
9 + <OutputType>Module</OutputType>
10 + <Name>MergeModule1</Name>
11 + <RootNamespace>MergeModule1</RootNamespace>
12 + </PropertyGroup>
13 + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
14 + <PlatformName>$(Platform)</PlatformName>
15 + <OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
16 + <DefineConstants>Debug</DefineConstants>
17 + </PropertyGroup>
18 + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
19 + <PlatformName>$(Platform)</PlatformName>
20 + <OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
21 + </PropertyGroup>
22 + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
23 + <PlatformName>$(Platform)</PlatformName>
24 + <OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
25 + <DefineConstants>Debug</DefineConstants>
26 + </PropertyGroup>
27 + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
28 + <PlatformName>$(Platform)</PlatformName>
29 + <OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
30 + </PropertyGroup>
31 + <ItemGroup>
32 + <Compile Include="MergeModule.wxs" />
33 + </ItemGroup>
34 + <ItemGroup>
35 + <EmbeddedResource Include="MergeModule.en-us.wxl" />
36 + </ItemGroup>
37 + <ItemGroup>
38 + <WixExtension Include="FgwepExtension.wixext">
39 + <Name>FgwepExtension.wixext</Name>
40 + <HintPath>$(WixExtDir)\FgwepExtension.wixext.dll</HintPath>
41 + </WixExtension>
42 + </ItemGroup>
43 + <Import Project="$(WixTargetsPath)" Condition=" '$(WixTargetsPath)' != '' " />
44 + <Import Project="$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\wix.targets" Condition=" '$(WixTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\wix.targets') " />
45 + <Target Name="EnsureWixToolsetInstalled" Condition=" '$(WixTargetsImported)' != 'true' ">
46 + <Error Text="FG-WiX or WiX Toolset build tools (v3.11 or later) must be installed to build this project. To download FG-WiX, go to https://www.firegiant.com/downloads/. To download the WiX Toolset, go to http://wixtoolset.org/releases/." />
47 + </Target>
48 +</Project>
\ No newline at end of file
src/test/WixToolsetTest.CoreIntegrationFixture/TestData/SimpleModule/Module.wxs new
+16
@@ -0,0 +1,16 @@
1 +<?xml version="1.0" encoding="utf-8"?>
2 +<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 + <Module Id="MergeModule1" Language="1033" Version="1.0.0.0">
4 + <Package Id="243FB739-4D05-472F-9CFB-EF6B1017B6DE" Manufacturer="!(loc.Manufacturer)" InstallerVersion="200" />
5 +
6 + <Directory Id="TARGETDIR" Name="SourceDir">
7 + <Directory Id="MergeRedirectFolder">
8 +
9 + <Component Id="ModuleComponent" Guid="A04E61B2-3ED4-4803-B2EB-4B773576FA45">
10 + <File Source="test.txt" />
11 + </Component>
12 +
13 + </Directory>
14 + </Directory>
15 + </Module>
16 +</Wix>
src/test/WixToolsetTest.CoreIntegrationFixture/TestData/SimpleModule/data/test.txt new
+1
@@ -0,0 +1 @@
1 +This is test.txt.
\ No newline at end of file
src/test/WixToolsetTest.CoreIntegrationFixture/WixToolsetTest.CoreIntegrationFixture.csproj
+7 -4
@@ -7,11 +7,14 @@
7 <IsPackable>false</IsPackable>
8 </PropertyGroup>
9
10 - <PropertyGroup>
11 - <NoWarn>NU1701</NoWarn>
12 - </PropertyGroup>
13 -
10 <ItemGroup>
11 + <Content Include="TestData\SimpleModule\data\test.txt" CopyToOutputDirectory="PreserveNewest" />
12 + <Content Include="TestData\SimpleModule\Module.en-us.wxl" CopyToOutputDirectory="PreserveNewest" />
13 + <Content Include="TestData\SimpleModule\Module.wxs" CopyToOutputDirectory="PreserveNewest" />
14 + <Content Include="TestData\InstanceTransform\data\test.txt" CopyToOutputDirectory="PreserveNewest" />
15 + <Content Include="TestData\InstanceTransform\Package.en-us.wxl" CopyToOutputDirectory="PreserveNewest" />
16 + <Content Include="TestData\InstanceTransform\Package.wxs" CopyToOutputDirectory="PreserveNewest" />
17 + <Content Include="TestData\InstanceTransform\PackageComponents.wxs" CopyToOutputDirectory="PreserveNewest" />
18 <Content Include="TestData\SingleFile\data\test.txt" CopyToOutputDirectory="PreserveNewest" />
19 <Content Include="TestData\SingleFile\Package.en-us.wxl" CopyToOutputDirectory="PreserveNewest" />
20 <Content Include="TestData\SingleFile\Package.wxs" CopyToOutputDirectory="PreserveNewest" />