aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/api/wix/WixToolset.Extensibility/Services/IFileSystem.cs25
-rw-r--r--src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs5
-rw-r--r--src/wix/WixToolset.Core.Burn/Bundles/BurnReader.cs23
-rw-r--r--src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs8
-rw-r--r--src/wix/WixToolset.Core.Burn/Bundles/HarvestBundlePackageCommand.cs5
-rw-r--r--src/wix/WixToolset.Core.Burn/CommandLine/ExtractSubcommand.cs9
-rw-r--r--src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleCommand.cs12
-rw-r--r--src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleEngineCommand.cs10
-rw-r--r--src/wix/WixToolset.Core.Native/DateTimeInterop.cs4
-rw-r--r--src/wix/WixToolset.Core.Native/WixToolset.Core.Native.csproj1
-rw-r--r--src/wix/WixToolset.Core.TestPackage/BundleExtractor.cs17
-rw-r--r--src/wix/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs22
-rw-r--r--src/wix/WixToolset.Core.WindowsInstaller/CommandLine/ValidateSubcommand.cs5
-rw-r--r--src/wix/WixToolset.Core.WindowsInstaller/Validate/ValidateDatabaseCommand.cs7
-rw-r--r--src/wix/WixToolset.Core/Bind/TransferFilesCommand.cs25
-rw-r--r--src/wix/WixToolset.Core/ExtensibilityServices/FileSystem.cs (renamed from src/wix/WixToolset.Core.Native/FileSystem.cs)43
-rw-r--r--src/wix/WixToolset.Core/LayoutCreator.cs5
-rw-r--r--src/wix/WixToolset.Core/WixToolset.Core.csproj9
-rw-r--r--src/wix/WixToolset.Core/WixToolsetServiceProvider.cs1
19 files changed, 143 insertions, 93 deletions
diff --git a/src/api/wix/WixToolset.Extensibility/Services/IFileSystem.cs b/src/api/wix/WixToolset.Extensibility/Services/IFileSystem.cs
new file mode 100644
index 00000000..d633c823
--- /dev/null
+++ b/src/api/wix/WixToolset.Extensibility/Services/IFileSystem.cs
@@ -0,0 +1,25 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Extensibility.Services
4{
5 /// <summary>
6 /// Abstracts basic file system operations.
7 /// </summary>
8 public interface IFileSystem
9 {
10 /// <summary>
11 /// Copies a file.
12 /// </summary>
13 /// <param name="source">The file to copy.</param>
14 /// <param name="destination">The destination file.</param>
15 /// <param name="allowHardlink">Allow hardlinks.</param>
16 void CopyFile(string source, string destination, bool allowHardlink);
17
18 /// <summary>
19 /// Moves a file.
20 /// </summary>
21 /// <param name="source">The file to move.</param>
22 /// <param name="destination">The destination file.</param>
23 void MoveFile(string source, string destination);
24 }
25}
diff --git a/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs b/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
index 44fb84c7..db4fbf0e 100644
--- a/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
@@ -28,6 +28,7 @@ namespace WixToolset.Core.Burn
28 this.ServiceProvider = context.ServiceProvider; 28 this.ServiceProvider = context.ServiceProvider;
29 29
30 this.Messaging = context.ServiceProvider.GetService<IMessaging>(); 30 this.Messaging = context.ServiceProvider.GetService<IMessaging>();
31 this.FileSystem = context.ServiceProvider.GetService<IFileSystem>();
31 32
32 this.BackendHelper = context.ServiceProvider.GetService<IBackendHelper>(); 33 this.BackendHelper = context.ServiceProvider.GetService<IBackendHelper>();
33 this.InternalBurnBackendHelper = context.ServiceProvider.GetService<IInternalBurnBackendHelper>(); 34 this.InternalBurnBackendHelper = context.ServiceProvider.GetService<IInternalBurnBackendHelper>();
@@ -49,6 +50,8 @@ namespace WixToolset.Core.Burn
49 50
50 private IMessaging Messaging { get; } 51 private IMessaging Messaging { get; }
51 52
53 private IFileSystem FileSystem { get; }
54
52 private IBackendHelper BackendHelper { get; } 55 private IBackendHelper BackendHelper { get; }
53 56
54 private IInternalBurnBackendHelper InternalBurnBackendHelper { get; } 57 private IInternalBurnBackendHelper InternalBurnBackendHelper { get; }
@@ -507,7 +510,7 @@ namespace WixToolset.Core.Burn
507 } 510 }
508 511
509 { 512 {
510 var command = new CreateBundleExeCommand(this.Messaging, this.BackendHelper, this.IntermediateFolder, this.OutputPath, bundleApplicationDllSymbol, bundleSymbol, uxContainer, containers.Values); 513 var command = new CreateBundleExeCommand(this.Messaging, this.FileSystem, this.BackendHelper, this.IntermediateFolder, this.OutputPath, bundleApplicationDllSymbol, bundleSymbol, uxContainer, containers.Values);
511 command.Execute(); 514 command.Execute();
512 515
513 fileTransfers.Add(command.Transfer); 516 fileTransfers.Add(command.Transfer);
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/BurnReader.cs b/src/wix/WixToolset.Core.Burn/Bundles/BurnReader.cs
index e3d0f0af..e87e32c7 100644
--- a/src/wix/WixToolset.Core.Burn/Bundles/BurnReader.cs
+++ b/src/wix/WixToolset.Core.Burn/Bundles/BurnReader.cs
@@ -27,16 +27,19 @@ namespace WixToolset.Core.Burn.Bundles
27 27
28 private BinaryReader binaryReader; 28 private BinaryReader binaryReader;
29 private readonly List<DictionaryEntry> attachedContainerPayloadNames; 29 private readonly List<DictionaryEntry> attachedContainerPayloadNames;
30 private readonly IFileSystem fileSystem;
30 31
31 /// <summary> 32 /// <summary>
32 /// Creates a BurnReader for reading a PE file. 33 /// Creates a BurnReader for reading a PE file.
33 /// </summary> 34 /// </summary>
34 /// <param name="messaging"></param> 35 /// <param name="messaging">Messaging.</param>
36 /// <param name="fileSystem">File system.</param>
35 /// <param name="fileExe">File to read.</param> 37 /// <param name="fileExe">File to read.</param>
36 private BurnReader(IMessaging messaging, string fileExe) 38 private BurnReader(IMessaging messaging, IFileSystem fileSystem, string fileExe)
37 : base(messaging, fileExe) 39 : base(messaging, fileExe)
38 { 40 {
39 this.attachedContainerPayloadNames = new List<DictionaryEntry>(); 41 this.attachedContainerPayloadNames = new List<DictionaryEntry>();
42 this.fileSystem = fileSystem;
40 } 43 }
41 44
42 /// <summary> 45 /// <summary>
@@ -47,13 +50,14 @@ namespace WixToolset.Core.Burn.Bundles
47 /// <summary> 50 /// <summary>
48 /// Opens a Burn reader. 51 /// Opens a Burn reader.
49 /// </summary> 52 /// </summary>
50 /// <param name="messaging"></param> 53 /// <param name="messaging">Messaging.</param>
54 /// <param name="fileSystem">File system.</param>
51 /// <param name="fileExe">Path to file.</param> 55 /// <param name="fileExe">Path to file.</param>
52 /// <returns>Burn reader.</returns> 56 /// <returns>Burn reader.</returns>
53 public static BurnReader Open(IMessaging messaging, string fileExe) 57 public static BurnReader Open(IMessaging messaging, IFileSystem fileSystem, string fileExe)
54 { 58 {
55 var binaryReader = new BinaryReader(File.Open(fileExe, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete)); 59 var binaryReader = new BinaryReader(File.Open(fileExe, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete));
56 var reader = new BurnReader(messaging, fileExe) 60 var reader = new BurnReader(messaging, fileSystem, fileExe)
57 { 61 {
58 binaryReader = binaryReader, 62 binaryReader = binaryReader,
59 }; 63 };
@@ -96,8 +100,7 @@ namespace WixToolset.Core.Burn.Bundles
96 var cabinet = new Cabinet(tempCabPath); 100 var cabinet = new Cabinet(tempCabPath);
97 cabinet.Extract(outputDirectory); 101 cabinet.Extract(outputDirectory);
98 102
99 Directory.CreateDirectory(Path.GetDirectoryName(manifestPath)); 103 this.fileSystem.MoveFile(manifestOriginalPath, manifestPath);
100 FileSystem.MoveFile(manifestOriginalPath, manifestPath);
101 104
102 var document = new XmlDocument(); 105 var document = new XmlDocument();
103 document.Load(manifestPath); 106 document.Load(manifestPath);
@@ -114,8 +117,7 @@ namespace WixToolset.Core.Burn.Bundles
114 var sourcePath = Path.Combine(outputDirectory, sourcePathNode.Value); 117 var sourcePath = Path.Combine(outputDirectory, sourcePathNode.Value);
115 var destinationPath = Path.Combine(outputDirectory, filePathNode.Value); 118 var destinationPath = Path.Combine(outputDirectory, filePathNode.Value);
116 119
117 Directory.CreateDirectory(Path.GetDirectoryName(destinationPath)); 120 this.fileSystem.MoveFile(sourcePath, destinationPath);
118 FileSystem.MoveFile(sourcePath, destinationPath);
119 } 121 }
120 122
121 foreach (XmlNode payload in payloads) 123 foreach (XmlNode payload in payloads)
@@ -183,8 +185,7 @@ namespace WixToolset.Core.Burn.Bundles
183 var sourcePath = Path.Combine(outputDirectory, (string)entry.Key); 185 var sourcePath = Path.Combine(outputDirectory, (string)entry.Key);
184 var destinationPath = Path.Combine(outputDirectory, (string)entry.Value); 186 var destinationPath = Path.Combine(outputDirectory, (string)entry.Value);
185 187
186 Directory.CreateDirectory(Path.GetDirectoryName(destinationPath)); 188 this.fileSystem.MoveFile(sourcePath, destinationPath);
187 FileSystem.MoveFile(sourcePath, destinationPath);
188 } 189 }
189 190
190 return true; 191 return true;
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs
index 67a6cb4a..7fe3c4ec 100644
--- a/src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs
@@ -9,7 +9,6 @@ namespace WixToolset.Core.Burn.Bundles
9 using System.Runtime.InteropServices; 9 using System.Runtime.InteropServices;
10 using System.Text; 10 using System.Text;
11 using System.Xml; 11 using System.Xml;
12 using WixToolset.Core.Native;
13 using WixToolset.Data; 12 using WixToolset.Data;
14 using WixToolset.Data.Burn; 13 using WixToolset.Data.Burn;
15 using WixToolset.Data.Symbols; 14 using WixToolset.Data.Symbols;
@@ -19,9 +18,10 @@ namespace WixToolset.Core.Burn.Bundles
19 18
20 internal class CreateBundleExeCommand 19 internal class CreateBundleExeCommand
21 { 20 {
22 public CreateBundleExeCommand(IMessaging messaging, IBackendHelper backendHelper, string intermediateFolder, string outputPath, WixBootstrapperApplicationDllSymbol bootstrapperApplicationDllSymbol, WixBundleSymbol bundleSymbol, WixBundleContainerSymbol uxContainer, IEnumerable<WixBundleContainerSymbol> containers) 21 public CreateBundleExeCommand(IMessaging messaging, IFileSystem fileSystem, IBackendHelper backendHelper, string intermediateFolder, string outputPath, WixBootstrapperApplicationDllSymbol bootstrapperApplicationDllSymbol, WixBundleSymbol bundleSymbol, WixBundleContainerSymbol uxContainer, IEnumerable<WixBundleContainerSymbol> containers)
23 { 22 {
24 this.Messaging = messaging; 23 this.Messaging = messaging;
24 this.FileSystem = fileSystem;
25 this.BackendHelper = backendHelper; 25 this.BackendHelper = backendHelper;
26 this.IntermediateFolder = intermediateFolder; 26 this.IntermediateFolder = intermediateFolder;
27 this.OutputPath = outputPath; 27 this.OutputPath = outputPath;
@@ -35,6 +35,8 @@ namespace WixToolset.Core.Burn.Bundles
35 35
36 private IMessaging Messaging { get; } 36 private IMessaging Messaging { get; }
37 37
38 private IFileSystem FileSystem { get; }
39
38 private IBackendHelper BackendHelper { get; } 40 private IBackendHelper BackendHelper { get; }
39 41
40 private string IntermediateFolder { get; } 42 private string IntermediateFolder { get; }
@@ -68,7 +70,7 @@ namespace WixToolset.Core.Burn.Bundles
68 70
69 this.Transfer = this.BackendHelper.CreateFileTransfer(bundleTempPath, this.OutputPath, true, this.BundleSymbol.SourceLineNumbers); 71 this.Transfer = this.BackendHelper.CreateFileTransfer(bundleTempPath, this.OutputPath, true, this.BundleSymbol.SourceLineNumbers);
70 72
71 FileSystem.CopyFile(stubFile, bundleTempPath, allowHardlink: false); 73 this.FileSystem.CopyFile(stubFile, bundleTempPath, allowHardlink: false);
72 File.SetAttributes(bundleTempPath, FileAttributes.Normal); 74 File.SetAttributes(bundleTempPath, FileAttributes.Normal);
73 75
74 var fourPartVersion = this.GetFourPartVersion(this.BundleSymbol); 76 var fourPartVersion = this.GetFourPartVersion(this.BundleSymbol);
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/HarvestBundlePackageCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/HarvestBundlePackageCommand.cs
index 89e0da98..bc065f2f 100644
--- a/src/wix/WixToolset.Core.Burn/Bundles/HarvestBundlePackageCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bundles/HarvestBundlePackageCommand.cs
@@ -18,6 +18,7 @@ namespace WixToolset.Core.Burn.Bundles
18 public HarvestBundlePackageCommand(IServiceProvider serviceProvider, IEnumerable<IBurnBackendBinderExtension> backendExtensions, string intermediateFolder, WixBundlePayloadSymbol payloadSymbol, WixBundleBundlePackagePayloadSymbol packagePayloadSymbol, Dictionary<string, WixBundlePayloadSymbol> packagePayloadsById) 18 public HarvestBundlePackageCommand(IServiceProvider serviceProvider, IEnumerable<IBurnBackendBinderExtension> backendExtensions, string intermediateFolder, WixBundlePayloadSymbol payloadSymbol, WixBundleBundlePackagePayloadSymbol packagePayloadSymbol, Dictionary<string, WixBundlePayloadSymbol> packagePayloadsById)
19 { 19 {
20 this.Messaging = serviceProvider.GetService<IMessaging>(); 20 this.Messaging = serviceProvider.GetService<IMessaging>();
21 this.FileSystem = serviceProvider.GetService<IFileSystem>();
21 this.BackendHelper = serviceProvider.GetService<IBackendHelper>(); 22 this.BackendHelper = serviceProvider.GetService<IBackendHelper>();
22 this.BackendExtensions = backendExtensions; 23 this.BackendExtensions = backendExtensions;
23 this.IntermediateFolder = intermediateFolder; 24 this.IntermediateFolder = intermediateFolder;
@@ -29,6 +30,8 @@ namespace WixToolset.Core.Burn.Bundles
29 30
30 private IMessaging Messaging { get; } 31 private IMessaging Messaging { get; }
31 32
33 private IFileSystem FileSystem { get; }
34
32 private IBackendHelper BackendHelper { get; } 35 private IBackendHelper BackendHelper { get; }
33 36
34 private IEnumerable<IBurnBackendBinderExtension> BackendExtensions { get; } 37 private IEnumerable<IBurnBackendBinderExtension> BackendExtensions { get; }
@@ -66,7 +69,7 @@ namespace WixToolset.Core.Burn.Bundles
66 var sourcePath = this.PackagePayload.SourceFile.Path; 69 var sourcePath = this.PackagePayload.SourceFile.Path;
67 var sourceLineNumbers = this.PackagePayload.SourceLineNumbers; 70 var sourceLineNumbers = this.PackagePayload.SourceLineNumbers;
68 71
69 using (var burnReader = BurnReader.Open(this.Messaging, sourcePath)) 72 using (var burnReader = BurnReader.Open(this.Messaging, this.FileSystem, sourcePath))
70 { 73 {
71 if (burnReader.Invalid) 74 if (burnReader.Invalid)
72 { 75 {
diff --git a/src/wix/WixToolset.Core.Burn/CommandLine/ExtractSubcommand.cs b/src/wix/WixToolset.Core.Burn/CommandLine/ExtractSubcommand.cs
index 605ee045..5d6edc33 100644
--- a/src/wix/WixToolset.Core.Burn/CommandLine/ExtractSubcommand.cs
+++ b/src/wix/WixToolset.Core.Burn/CommandLine/ExtractSubcommand.cs
@@ -7,21 +7,20 @@ namespace WixToolset.Core.Burn.CommandLine
7 using System.Threading; 7 using System.Threading;
8 using System.Threading.Tasks; 8 using System.Threading.Tasks;
9 using WixToolset.Core.Burn.Bundles; 9 using WixToolset.Core.Burn.Bundles;
10 using WixToolset.Core.Burn.Inscribe;
11 using WixToolset.Extensibility.Services; 10 using WixToolset.Extensibility.Services;
12 11
13 internal class ExtractSubcommand : BurnSubcommandBase 12 internal class ExtractSubcommand : BurnSubcommandBase
14 { 13 {
15 public ExtractSubcommand(IServiceProvider serviceProvider) 14 public ExtractSubcommand(IServiceProvider serviceProvider)
16 { 15 {
17 this.ServiceProvider = serviceProvider;
18 this.Messaging = serviceProvider.GetService<IMessaging>(); 16 this.Messaging = serviceProvider.GetService<IMessaging>();
17 this.FileSystem = serviceProvider.GetService<IFileSystem>();
19 } 18 }
20 19
21 private IServiceProvider ServiceProvider { get; }
22
23 private IMessaging Messaging { get; } 20 private IMessaging Messaging { get; }
24 21
22 private IFileSystem FileSystem { get; }
23
25 private string InputPath { get; set; } 24 private string InputPath { get; set; }
26 25
27 private string IntermediateFolder { get; set; } 26 private string IntermediateFolder { get; set; }
@@ -49,7 +48,7 @@ namespace WixToolset.Core.Burn.CommandLine
49 48
50 var uxExtractPath = Path.Combine(this.ExtractPath, "BA"); 49 var uxExtractPath = Path.Combine(this.ExtractPath, "BA");
51 50
52 using (var reader = BurnReader.Open(this.Messaging, this.InputPath)) 51 using (var reader = BurnReader.Open(this.Messaging, this.FileSystem, this.InputPath))
53 { 52 {
54 reader.ExtractUXContainer(uxExtractPath, this.IntermediateFolder); 53 reader.ExtractUXContainer(uxExtractPath, this.IntermediateFolder);
55 54
diff --git a/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleCommand.cs b/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleCommand.cs
index 6e071fe7..d68d372c 100644
--- a/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleCommand.cs
@@ -5,7 +5,6 @@ namespace WixToolset.Core.Burn.Inscribe
5 using System; 5 using System;
6 using System.IO; 6 using System.IO;
7 using WixToolset.Core.Burn.Bundles; 7 using WixToolset.Core.Burn.Bundles;
8 using WixToolset.Core.Native;
9 using WixToolset.Extensibility.Services; 8 using WixToolset.Extensibility.Services;
10 9
11 internal class InscribeBundleCommand 10 internal class InscribeBundleCommand
@@ -13,6 +12,7 @@ namespace WixToolset.Core.Burn.Inscribe
13 public InscribeBundleCommand(IServiceProvider serviceProvider, string inputPath, string signedEngineFile, string outputPath, string intermediateFolder) 12 public InscribeBundleCommand(IServiceProvider serviceProvider, string inputPath, string signedEngineFile, string outputPath, string intermediateFolder)
14 { 13 {
15 this.Messaging = serviceProvider.GetService<IMessaging>(); 14 this.Messaging = serviceProvider.GetService<IMessaging>();
15 this.FileSystem = serviceProvider.GetService<IFileSystem>();
16 this.IntermediateFolder = intermediateFolder; 16 this.IntermediateFolder = intermediateFolder;
17 this.InputFilePath = inputPath; 17 this.InputFilePath = inputPath;
18 this.SignedEngineFile = signedEngineFile; 18 this.SignedEngineFile = signedEngineFile;
@@ -21,6 +21,8 @@ namespace WixToolset.Core.Burn.Inscribe
21 21
22 private IMessaging Messaging { get; } 22 private IMessaging Messaging { get; }
23 23
24 private IFileSystem FileSystem { get; }
25
24 private string IntermediateFolder { get; } 26 private string IntermediateFolder { get; }
25 27
26 private string InputFilePath { get; } 28 private string InputFilePath { get; }
@@ -34,9 +36,9 @@ namespace WixToolset.Core.Burn.Inscribe
34 var inscribed = false; 36 var inscribed = false;
35 var tempFile = Path.Combine(this.IntermediateFolder, "~bundle_engine_signed.exe"); 37 var tempFile = Path.Combine(this.IntermediateFolder, "~bundle_engine_signed.exe");
36 38
37 using (var reader = BurnReader.Open(this.Messaging, this.InputFilePath)) 39 using (var reader = BurnReader.Open(this.Messaging, this.FileSystem, this.InputFilePath))
38 { 40 {
39 FileSystem.CopyFile(this.SignedEngineFile, tempFile, allowHardlink: false); 41 this.FileSystem.CopyFile(this.SignedEngineFile, tempFile, allowHardlink: false);
40 42
41 using (var writer = BurnWriter.Open(this.Messaging, tempFile)) 43 using (var writer = BurnWriter.Open(this.Messaging, tempFile))
42 { 44 {
@@ -44,9 +46,7 @@ namespace WixToolset.Core.Burn.Inscribe
44 } 46 }
45 } 47 }
46 48
47 Directory.CreateDirectory(Path.GetDirectoryName(this.OutputFile)); 49 this.FileSystem.MoveFile(tempFile, this.OutputFile);
48
49 FileSystem.MoveFile(tempFile, this.OutputFile);
50 50
51 return inscribed; 51 return inscribed;
52 } 52 }
diff --git a/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleEngineCommand.cs b/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleEngineCommand.cs
index e607a28f..c00788ca 100644
--- a/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleEngineCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleEngineCommand.cs
@@ -5,7 +5,6 @@ namespace WixToolset.Core.Burn.Inscribe
5 using System; 5 using System;
6 using System.IO; 6 using System.IO;
7 using WixToolset.Core.Burn.Bundles; 7 using WixToolset.Core.Burn.Bundles;
8 using WixToolset.Core.Native;
9 using WixToolset.Extensibility.Services; 8 using WixToolset.Extensibility.Services;
10 9
11 internal class InscribeBundleEngineCommand 10 internal class InscribeBundleEngineCommand
@@ -13,6 +12,7 @@ namespace WixToolset.Core.Burn.Inscribe
13 public InscribeBundleEngineCommand(IServiceProvider serviceProvider, string inputPath, string outputPath, string intermediateFolder) 12 public InscribeBundleEngineCommand(IServiceProvider serviceProvider, string inputPath, string outputPath, string intermediateFolder)
14 { 13 {
15 this.Messaging = serviceProvider.GetService<IMessaging>(); 14 this.Messaging = serviceProvider.GetService<IMessaging>();
15 this.FileSystem = serviceProvider.GetService<IFileSystem>();
16 this.IntermediateFolder = intermediateFolder; 16 this.IntermediateFolder = intermediateFolder;
17 this.InputFilePath = inputPath; 17 this.InputFilePath = inputPath;
18 this.OutputFile = outputPath; 18 this.OutputFile = outputPath;
@@ -20,6 +20,8 @@ namespace WixToolset.Core.Burn.Inscribe
20 20
21 private IMessaging Messaging { get; } 21 private IMessaging Messaging { get; }
22 22
23 private IFileSystem FileSystem { get; }
24
23 private string IntermediateFolder { get; } 25 private string IntermediateFolder { get; }
24 26
25 private string InputFilePath { get; } 27 private string InputFilePath { get; }
@@ -30,7 +32,7 @@ namespace WixToolset.Core.Burn.Inscribe
30 { 32 {
31 var tempFile = Path.Combine(this.IntermediateFolder, "bundle_engine_unsigned.exe"); 33 var tempFile = Path.Combine(this.IntermediateFolder, "bundle_engine_unsigned.exe");
32 34
33 using (var reader = BurnReader.Open(this.Messaging, this.InputFilePath)) 35 using (var reader = BurnReader.Open(this.Messaging, this.FileSystem, this.InputFilePath))
34 using (var writer = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.Read | FileShare.Delete)) 36 using (var writer = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.Read | FileShare.Delete))
35 { 37 {
36 reader.Stream.Seek(0, SeekOrigin.Begin); 38 reader.Stream.Seek(0, SeekOrigin.Begin);
@@ -56,9 +58,7 @@ namespace WixToolset.Core.Burn.Inscribe
56 // TODO: update writer with detached container signatures. 58 // TODO: update writer with detached container signatures.
57 } 59 }
58 60
59 Directory.CreateDirectory(Path.GetDirectoryName(this.OutputFile)); 61 this.FileSystem.MoveFile(tempFile, this.OutputFile);
60
61 FileSystem.MoveFile(tempFile, this.OutputFile);
62 } 62 }
63 } 63 }
64} 64}
diff --git a/src/wix/WixToolset.Core.Native/DateTimeInterop.cs b/src/wix/WixToolset.Core.Native/DateTimeInterop.cs
index d2a0ba2b..9ab4f813 100644
--- a/src/wix/WixToolset.Core.Native/DateTimeInterop.cs
+++ b/src/wix/WixToolset.Core.Native/DateTimeInterop.cs
@@ -20,8 +20,8 @@ namespace WixToolset.Core.Native
20 { 20 {
21 // dateTime.ToLocalTime() does not match FileTimeToLocalFileTime() for some reason. 21 // dateTime.ToLocalTime() does not match FileTimeToLocalFileTime() for some reason.
22 // so we need to call FileTimeToLocalFileTime() from kernel32.dll. 22 // so we need to call FileTimeToLocalFileTime() from kernel32.dll.
23 long filetime = dateTime.ToFileTime(); 23 var filetime = dateTime.ToFileTime();
24 long localTime = 0; 24 var localTime = 0L;
25 FileTimeToLocalFileTime(ref filetime, ref localTime); 25 FileTimeToLocalFileTime(ref filetime, ref localTime);
26 FileTimeToDosDateTime(ref localTime, out cabDate, out cabTime); 26 FileTimeToDosDateTime(ref localTime, out cabDate, out cabTime);
27 } 27 }
diff --git a/src/wix/WixToolset.Core.Native/WixToolset.Core.Native.csproj b/src/wix/WixToolset.Core.Native/WixToolset.Core.Native.csproj
index 6553a276..b5c83fba 100644
--- a/src/wix/WixToolset.Core.Native/WixToolset.Core.Native.csproj
+++ b/src/wix/WixToolset.Core.Native/WixToolset.Core.Native.csproj
@@ -24,6 +24,5 @@
24 24
25 <ItemGroup> 25 <ItemGroup>
26 <PackageReference Include="WixToolset.Data" /> 26 <PackageReference Include="WixToolset.Data" />
27 <PackageReference Include="System.IO.FileSystem.AccessControl" />
28 </ItemGroup> 27 </ItemGroup>
29</Project> 28</Project>
diff --git a/src/wix/WixToolset.Core.TestPackage/BundleExtractor.cs b/src/wix/WixToolset.Core.TestPackage/BundleExtractor.cs
index 3cc98e3a..f8cf49df 100644
--- a/src/wix/WixToolset.Core.TestPackage/BundleExtractor.cs
+++ b/src/wix/WixToolset.Core.TestPackage/BundleExtractor.cs
@@ -39,7 +39,7 @@ namespace WixToolset.Core.TestPackage
39 { 39 {
40 var result = new ExtractBAContainerResult(); 40 var result = new ExtractBAContainerResult();
41 Directory.CreateDirectory(tempFolderPath); 41 Directory.CreateDirectory(tempFolderPath);
42 using (var burnReader = BurnReader.Open(messaging, bundleFilePath)) 42 using (var burnReader = BurnReader.Open(messaging, new TestFileSystem(), bundleFilePath))
43 { 43 {
44 result.Success = burnReader.ExtractUXContainer(baFolderPath, tempFolderPath); 44 result.Success = burnReader.ExtractUXContainer(baFolderPath, tempFolderPath);
45 45
@@ -138,5 +138,20 @@ namespace WixToolset.Core.TestPackage
138 document.Load(Path.Combine(baFolderPath, "manifest.xml")); 138 document.Load(Path.Combine(baFolderPath, "manifest.xml"));
139 return document; 139 return document;
140 } 140 }
141
142 private class TestFileSystem : IFileSystem
143 {
144 public void CopyFile(string source, string destination, bool allowHardlink)
145 {
146 Directory.CreateDirectory(Path.GetDirectoryName(destination));
147 File.Copy(source, destination);
148 }
149
150 public void MoveFile(string source, string destination)
151 {
152 Directory.CreateDirectory(Path.GetDirectoryName(destination));
153 File.Move(source, destination);
154 }
155 }
141 } 156 }
142} 157}
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs
index 7af0ca19..7e6a7de0 100644
--- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs
+++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/MergeModulesCommand.cs
@@ -71,10 +71,10 @@ namespace WixToolset.Core.WindowsInstaller.Bind
71 { 71 {
72 merge = MsmInterop.GetMsmMerge(); 72 merge = MsmInterop.GetMsmMerge();
73 73
74 FileSystem.ActionWithRetries(() => merge.OpenLog(logPath)); 74 ActionWithRetries(() => merge.OpenLog(logPath));
75 logOpen = true; 75 logOpen = true;
76 76
77 FileSystem.ActionWithRetries(() => merge.OpenDatabase(this.OutputPath)); 77 ActionWithRetries(() => merge.OpenDatabase(this.OutputPath));
78 databaseOpen = true; 78 databaseOpen = true;
79 79
80 var featureModulesByMergeId = this.Section.Symbols.OfType<WixFeatureModulesSymbol>().GroupBy(t => t.WixMergeRef).ToDictionary(g => g.Key); 80 var featureModulesByMergeId = this.Section.Symbols.OfType<WixFeatureModulesSymbol>().GroupBy(t => t.WixMergeRef).ToDictionary(g => g.Key);
@@ -99,7 +99,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
99 } 99 }
100 100
101 this.Messaging.Write(VerboseMessages.OpeningMergeModule(wixMergeRow.SourceFile, mergeLanguage)); 101 this.Messaging.Write(VerboseMessages.OpeningMergeModule(wixMergeRow.SourceFile, mergeLanguage));
102 FileSystem.ActionWithRetries(() => merge.OpenModule(wixMergeRow.SourceFile, mergeLanguage)); 102 ActionWithRetries(() => merge.OpenModule(wixMergeRow.SourceFile, mergeLanguage));
103 moduleOpen = true; 103 moduleOpen = true;
104 104
105 trackedFiles.Add(this.BackendHelper.TrackFile(wixMergeRow.SourceFile, TrackedFileType.Input, wixMergeRow.SourceLineNumbers)); 105 trackedFiles.Add(this.BackendHelper.TrackFile(wixMergeRow.SourceFile, TrackedFileType.Input, wixMergeRow.SourceLineNumbers));
@@ -340,5 +340,21 @@ namespace WixToolset.Core.WindowsInstaller.Bind
340 340
341 this.TrackedFiles = trackedFiles; 341 this.TrackedFiles = trackedFiles;
342 } 342 }
343
344 internal static void ActionWithRetries(Action action, int maxRetries = 3)
345 {
346 for (var attempt = 1; attempt <= maxRetries; ++attempt)
347 {
348 try
349 {
350 action();
351 break;
352 }
353 catch when (attempt < maxRetries)
354 {
355 Thread.Sleep(250);
356 }
357 }
358 }
343 } 359 }
344} 360}
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/CommandLine/ValidateSubcommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/CommandLine/ValidateSubcommand.cs
index 7d77aa30..eb014086 100644
--- a/src/wix/WixToolset.Core.WindowsInstaller/CommandLine/ValidateSubcommand.cs
+++ b/src/wix/WixToolset.Core.WindowsInstaller/CommandLine/ValidateSubcommand.cs
@@ -16,10 +16,13 @@ namespace WixToolset.Core.WindowsInstaller.CommandLine
16 public ValidateSubcommand(IServiceProvider serviceProvider) 16 public ValidateSubcommand(IServiceProvider serviceProvider)
17 { 17 {
18 this.Messaging = serviceProvider.GetService<IMessaging>(); 18 this.Messaging = serviceProvider.GetService<IMessaging>();
19 this.FileSystem = serviceProvider.GetService<IFileSystem>();
19 } 20 }
20 21
21 private IMessaging Messaging { get; } 22 private IMessaging Messaging { get; }
22 23
24 private IFileSystem FileSystem { get; }
25
23 private string DatabasePath { get; set; } 26 private string DatabasePath { get; set; }
24 27
25 private string WixpdbPath { get; set; } 28 private string WixpdbPath { get; set; }
@@ -76,7 +79,7 @@ namespace WixToolset.Core.WindowsInstaller.CommandLine
76 data = WindowsInstallerData.Load(this.WixpdbPath); 79 data = WindowsInstallerData.Load(this.WixpdbPath);
77 } 80 }
78 81
79 var command = new ValidateDatabaseCommand(this.Messaging, this.IntermediateFolder, this.DatabasePath, data, this.CubeFiles, this.Ices, this.SuppressIces); 82 var command = new ValidateDatabaseCommand(this.Messaging, this.FileSystem, this.IntermediateFolder, this.DatabasePath, data, this.CubeFiles, this.Ices, this.SuppressIces);
80 command.Execute(); 83 command.Execute();
81 84
82 return Task.FromResult(this.Messaging.EncounteredError ? 1 : 0); 85 return Task.FromResult(this.Messaging.EncounteredError ? 1 : 0);
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Validate/ValidateDatabaseCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Validate/ValidateDatabaseCommand.cs
index fa01a119..06fa6817 100644
--- a/src/wix/WixToolset.Core.WindowsInstaller/Validate/ValidateDatabaseCommand.cs
+++ b/src/wix/WixToolset.Core.WindowsInstaller/Validate/ValidateDatabaseCommand.cs
@@ -18,9 +18,10 @@ namespace WixToolset.Core.WindowsInstaller.Validate
18 // Set of ICEs that have equivalent-or-better checks in WiX. 18 // Set of ICEs that have equivalent-or-better checks in WiX.
19 private static readonly string[] WellKnownSuppressedIces = new[] { "ICE08", "ICE33", "ICE47", "ICE66" }; 19 private static readonly string[] WellKnownSuppressedIces = new[] { "ICE08", "ICE33", "ICE47", "ICE66" };
20 20
21 public ValidateDatabaseCommand(IMessaging messaging, string intermediateFolder, string databasePath, WindowsInstallerData data, IEnumerable<string> cubeFiles, IEnumerable<string> ices, IEnumerable<string> suppressedIces) 21 public ValidateDatabaseCommand(IMessaging messaging, IFileSystem fileSystem, string intermediateFolder, string databasePath, WindowsInstallerData data, IEnumerable<string> cubeFiles, IEnumerable<string> ices, IEnumerable<string> suppressedIces)
22 { 22 {
23 this.Messaging = messaging; 23 this.Messaging = messaging;
24 this.FileSystem = fileSystem;
24 this.Data = data; 25 this.Data = data;
25 this.DatabasePath = databasePath; 26 this.DatabasePath = databasePath;
26 this.CubeFiles = cubeFiles; 27 this.CubeFiles = cubeFiles;
@@ -40,6 +41,8 @@ namespace WixToolset.Core.WindowsInstaller.Validate
40 41
41 private IMessaging Messaging { get; } 42 private IMessaging Messaging { get; }
42 43
44 private IFileSystem FileSystem { get; }
45
43 private WindowsInstallerData Data { get; } 46 private WindowsInstallerData Data { get; }
44 47
45 private string DatabasePath { get; } 48 private string DatabasePath { get; }
@@ -71,7 +74,7 @@ namespace WixToolset.Core.WindowsInstaller.Validate
71 var workingDatabasePath = Path.Combine(this.IntermediateFolder, workingDatabaseFilename); 74 var workingDatabasePath = Path.Combine(this.IntermediateFolder, workingDatabaseFilename);
72 try 75 try
73 { 76 {
74 FileSystem.CopyFile(this.DatabasePath, workingDatabasePath, allowHardlink: false); 77 this.FileSystem.CopyFile(this.DatabasePath, workingDatabasePath, allowHardlink: false);
75 78
76 var attributes = File.GetAttributes(workingDatabasePath); 79 var attributes = File.GetAttributes(workingDatabasePath);
77 File.SetAttributes(workingDatabasePath, attributes & ~FileAttributes.ReadOnly); 80 File.SetAttributes(workingDatabasePath, attributes & ~FileAttributes.ReadOnly);
diff --git a/src/wix/WixToolset.Core/Bind/TransferFilesCommand.cs b/src/wix/WixToolset.Core/Bind/TransferFilesCommand.cs
index b3b74fbc..87c2590f 100644
--- a/src/wix/WixToolset.Core/Bind/TransferFilesCommand.cs
+++ b/src/wix/WixToolset.Core/Bind/TransferFilesCommand.cs
@@ -5,7 +5,7 @@ namespace WixToolset.Core.Bind
5 using System; 5 using System;
6 using System.Collections.Generic; 6 using System.Collections.Generic;
7 using System.IO; 7 using System.IO;
8 using WixToolset.Core.Native; 8 using System.Security.AccessControl;
9 using WixToolset.Data; 9 using WixToolset.Data;
10 using WixToolset.Extensibility; 10 using WixToolset.Extensibility;
11 using WixToolset.Extensibility.Data; 11 using WixToolset.Extensibility.Data;
@@ -13,16 +13,19 @@ namespace WixToolset.Core.Bind
13 13
14 internal class TransferFilesCommand 14 internal class TransferFilesCommand
15 { 15 {
16 public TransferFilesCommand(IMessaging messaging, IEnumerable<ILayoutExtension> extensions, IEnumerable<IFileTransfer> fileTransfers, bool resetAcls) 16 public TransferFilesCommand(IMessaging messaging, IFileSystem fileSystem, IEnumerable<ILayoutExtension> extensions, IEnumerable<IFileTransfer> fileTransfers, bool resetAcls)
17 { 17 {
18 this.Extensions = extensions; 18 this.Extensions = extensions;
19 this.Messaging = messaging; 19 this.Messaging = messaging;
20 this.FileSystem = fileSystem;
20 this.FileTransfers = fileTransfers; 21 this.FileTransfers = fileTransfers;
21 this.ResetAcls = resetAcls; 22 this.ResetAcls = resetAcls;
22 } 23 }
23 24
24 private IMessaging Messaging { get; } 25 private IMessaging Messaging { get; }
25 26
27 private IFileSystem FileSystem { get; }
28
26 private IEnumerable<ILayoutExtension> Extensions { get; } 29 private IEnumerable<ILayoutExtension> Extensions { get; }
27 30
28 private IEnumerable<IFileTransfer> FileTransfers { get; } 31 private IEnumerable<IFileTransfer> FileTransfers { get; }
@@ -158,7 +161,7 @@ namespace WixToolset.Core.Bind
158 { 161 {
159 try 162 try
160 { 163 {
161 FileSystem.ResetAcls(destinationFiles); 164 this.AclReset(destinationFiles);
162 } 165 }
163 catch (Exception e) 166 catch (Exception e)
164 { 167 {
@@ -177,7 +180,7 @@ namespace WixToolset.Core.Bind
177 } 180 }
178 } 181 }
179 182
180 FileSystem.CopyFile(source, destination, allowHardlink: true); 183 this.FileSystem.CopyFile(source, destination, allowHardlink: true);
181 } 184 }
182 185
183 private void MoveFile(string source, string destination) 186 private void MoveFile(string source, string destination)
@@ -190,7 +193,19 @@ namespace WixToolset.Core.Bind
190 } 193 }
191 } 194 }
192 195
193 FileSystem.MoveFile(source, destination); 196 this.FileSystem.MoveFile(source, destination);
197 }
198
199 private void AclReset(IEnumerable<string> files)
200 {
201 var aclReset = new FileSecurity();
202 aclReset.SetAccessRuleProtection(false, false);
203
204 foreach (var file in files)
205 {
206 var fileInfo = new FileInfo(file);
207 ExtensibilityServices.FileSystem.ActionWithRetries(() => fileInfo.SetAccessControl(aclReset));
208 }
194 } 209 }
195 } 210 }
196} 211}
diff --git a/src/wix/WixToolset.Core.Native/FileSystem.cs b/src/wix/WixToolset.Core/ExtensibilityServices/FileSystem.cs
index 3c59c90c..8bda4966 100644
--- a/src/wix/WixToolset.Core.Native/FileSystem.cs
+++ b/src/wix/WixToolset.Core/ExtensibilityServices/FileSystem.cs
@@ -1,26 +1,16 @@
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. 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 2
3namespace WixToolset.Core.Native 3namespace WixToolset.Core.ExtensibilityServices
4{ 4{
5 using System; 5 using System;
6 using System.Collections.Generic;
7 using System.IO; 6 using System.IO;
8 using System.Runtime.InteropServices; 7 using System.Runtime.InteropServices;
9 using System.Security.AccessControl;
10 using System.Threading; 8 using System.Threading;
9 using WixToolset.Extensibility.Services;
11 10
12 /// <summary> 11 internal class FileSystem : IFileSystem
13 /// File system helpers.
14 /// </summary>
15 public static class FileSystem
16 { 12 {
17 /// <summary> 13 public void CopyFile(string source, string destination, bool allowHardlink)
18 /// Copies a file.
19 /// </summary>
20 /// <param name="source">The file to copy.</param>
21 /// <param name="destination">The destination file.</param>
22 /// <param name="allowHardlink">Allow hardlinks.</param>
23 public static void CopyFile(string source, string destination, bool allowHardlink)
24 { 14 {
25 EnsureDirectoryWithoutFile(destination); 15 EnsureDirectoryWithoutFile(destination);
26 16
@@ -41,12 +31,7 @@ namespace WixToolset.Core.Native
41 } 31 }
42 } 32 }
43 33
44 /// <summary> 34 public void MoveFile(string source, string destination)
45 /// Moves a file.
46 /// </summary>
47 /// <param name="source">The file to move.</param>
48 /// <param name="destination">The destination file.</param>
49 public static void MoveFile(string source, string destination)
50 { 35 {
51 EnsureDirectoryWithoutFile(destination); 36 EnsureDirectoryWithoutFile(destination);
52 37
@@ -54,29 +39,13 @@ namespace WixToolset.Core.Native
54 } 39 }
55 40
56 /// <summary> 41 /// <summary>
57 /// Reset the ACLs on a set of files.
58 /// </summary>
59 /// <param name="files">The list of file paths to set ACLs.</param>
60 public static void ResetAcls(IEnumerable<string> files)
61 {
62 var aclReset = new FileSecurity();
63 aclReset.SetAccessRuleProtection(false, false);
64
65 foreach (var file in files)
66 {
67 var fileInfo = new FileInfo(file);
68 ActionWithRetries(() => fileInfo.SetAccessControl(aclReset));
69 }
70 }
71
72 /// <summary>
73 /// Executes an action and retries on any exception up to a few times. Primarily 42 /// Executes an action and retries on any exception up to a few times. Primarily
74 /// intended for use with file system operations that might get interrupted by 43 /// intended for use with file system operations that might get interrupted by
75 /// external systems (usually anti-virus). 44 /// external systems (usually anti-virus).
76 /// </summary> 45 /// </summary>
77 /// <param name="action">Action to execute.</param> 46 /// <param name="action">Action to execute.</param>
78 /// <param name="maxRetries">Maximum retry attempts.</param> 47 /// <param name="maxRetries">Maximum retry attempts.</param>
79 public static void ActionWithRetries(Action action, int maxRetries = 3) 48 internal static void ActionWithRetries(Action action, int maxRetries = 3)
80 { 49 {
81 for (var attempt = 1; attempt <= maxRetries; ++attempt) 50 for (var attempt = 1; attempt <= maxRetries; ++attempt)
82 { 51 {
diff --git a/src/wix/WixToolset.Core/LayoutCreator.cs b/src/wix/WixToolset.Core/LayoutCreator.cs
index 7a143680..3e7ecf3a 100644
--- a/src/wix/WixToolset.Core/LayoutCreator.cs
+++ b/src/wix/WixToolset.Core/LayoutCreator.cs
@@ -21,10 +21,13 @@ namespace WixToolset.Core
21 internal LayoutCreator(IServiceProvider serviceProvider) 21 internal LayoutCreator(IServiceProvider serviceProvider)
22 { 22 {
23 this.Messaging = serviceProvider.GetService<IMessaging>(); 23 this.Messaging = serviceProvider.GetService<IMessaging>();
24 this.FileSystem = serviceProvider.GetService<IFileSystem>();
24 } 25 }
25 26
26 private IMessaging Messaging { get; } 27 private IMessaging Messaging { get; }
27 28
29 private IFileSystem FileSystem { get; }
30
28 public void Layout(ILayoutContext context) 31 public void Layout(ILayoutContext context)
29 { 32 {
30 // Pre-layout. 33 // Pre-layout.
@@ -42,7 +45,7 @@ namespace WixToolset.Core
42 { 45 {
43 this.Messaging.Write(VerboseMessages.LayingOutMedia()); 46 this.Messaging.Write(VerboseMessages.LayingOutMedia());
44 47
45 var command = new TransferFilesCommand(this.Messaging, context.Extensions, context.FileTransfers, context.ResetAcls); 48 var command = new TransferFilesCommand(this.Messaging, this.FileSystem, context.Extensions, context.FileTransfers, context.ResetAcls);
46 command.Execute(); 49 command.Execute();
47 } 50 }
48 51
diff --git a/src/wix/WixToolset.Core/WixToolset.Core.csproj b/src/wix/WixToolset.Core/WixToolset.Core.csproj
index c2551b21..f2ee3a2c 100644
--- a/src/wix/WixToolset.Core/WixToolset.Core.csproj
+++ b/src/wix/WixToolset.Core/WixToolset.Core.csproj
@@ -15,19 +15,12 @@
15 </PropertyGroup> 15 </PropertyGroup>
16 16
17 <ItemGroup> 17 <ItemGroup>
18 <ProjectReference Include="..\WixToolset.Core.Native\WixToolset.Core.Native.csproj" />
19 </ItemGroup>
20
21 <ItemGroup>
22 <PackageReference Include="WixToolset.Data" /> 18 <PackageReference Include="WixToolset.Data" />
23 <PackageReference Include="WixToolset.Extensibility" /> 19 <PackageReference Include="WixToolset.Extensibility" />
24 </ItemGroup> 20 </ItemGroup>
25 21
26 <!--
27 These package references are duplicated in WixToolset.Core.TestPackage.csproj. If
28 you update these here, be sure to update them there.
29 -->
30 <ItemGroup> 22 <ItemGroup>
23 <PackageReference Include="System.IO.FileSystem.AccessControl" />
31 <PackageReference Include="System.Text.Encoding.CodePages" /> 24 <PackageReference Include="System.Text.Encoding.CodePages" />
32 <PackageReference Include="NuGet.Versioning" /> 25 <PackageReference Include="NuGet.Versioning" />
33 </ItemGroup> 26 </ItemGroup>
diff --git a/src/wix/WixToolset.Core/WixToolsetServiceProvider.cs b/src/wix/WixToolset.Core/WixToolsetServiceProvider.cs
index 525b9dd9..fa6b369d 100644
--- a/src/wix/WixToolset.Core/WixToolsetServiceProvider.cs
+++ b/src/wix/WixToolset.Core/WixToolsetServiceProvider.cs
@@ -27,6 +27,7 @@ namespace WixToolset.Core
27 this.AddService((provider, singletons) => AddSingleton<ILayoutServices>(singletons, new LayoutServices(provider))); 27 this.AddService((provider, singletons) => AddSingleton<ILayoutServices>(singletons, new LayoutServices(provider)));
28 this.AddService((provider, singletons) => AddSingleton<IBackendHelper>(singletons, new BackendHelper(provider))); 28 this.AddService((provider, singletons) => AddSingleton<IBackendHelper>(singletons, new BackendHelper(provider)));
29 this.AddService((provider, singletons) => AddSingleton<IPathResolver>(singletons, new PathResolver())); 29 this.AddService((provider, singletons) => AddSingleton<IPathResolver>(singletons, new PathResolver()));
30 this.AddService((provider, singletons) => AddSingleton<IFileSystem>(singletons, new FileSystem()));
30 this.AddService((provider, singletons) => AddSingleton<IWixBranding>(singletons, new WixBranding())); 31 this.AddService((provider, singletons) => AddSingleton<IWixBranding>(singletons, new WixBranding()));
31 32
32 // Transients. 33 // Transients.