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" />