From 9a18c230cfd88996b43c8ff7c59a195fb34ed3cf Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Tue, 4 Oct 2022 10:44:09 -0700 Subject: Use file system abstraction to handle retries automatically Fixes 4791 --- .../Services/IFileSystem.cs | 10 ++++++ src/wix/WixToolset.Core.Burn/Bundles/BurnReader.cs | 6 ++-- src/wix/WixToolset.Core.Burn/Bundles/BurnWriter.cs | 24 +++++++------- .../Bundles/CreateBundleExeCommand.cs | 2 +- .../Inscribe/InscribeBundleCommand.cs | 2 +- .../Inscribe/InscribeBundleEngineCommand.cs | 2 +- .../Bind/AssemblyNameReader.cs | 5 +-- .../Bind/BindDatabaseCommand.cs | 16 +++++---- .../Bind/BindTransformCommand.cs | 9 +++-- .../Bind/CreatePatchTransformsCommand.cs | 7 ++-- .../Bind/FileSystemManager.cs | 15 ++++++--- .../Bind/GenerateDatabaseCommand.cs | 7 ++-- .../Bind/UpdateFileFacadesCommand.cs | 7 ++-- .../CommandLine/TransformSubcommand.cs | 9 +++-- .../Inscribe/InscribeMsiPackageCommand.cs | 14 ++++---- .../WixToolset.Core.WindowsInstaller/MspBackend.cs | 4 ++- .../Unbind/ExtractCabinetsCommand.cs | 8 +++-- .../Unbind/UnbindDatabaseCommand.cs | 13 +++++--- .../Unbind/UnbindTransformCommand.cs | 13 +++++--- .../Validate/ValidateDatabaseCommand.cs | 8 +---- .../WindowsInstallerDecompiler.cs | 17 +++++----- src/wix/WixToolset.Core/Common.cs | 38 ---------------------- .../ExtensibilityServices/FileSystem.cs | 22 ++++++++++++- src/wix/WixToolset.Core/LayoutCreator.cs | 12 ++----- 24 files changed, 143 insertions(+), 127 deletions(-) diff --git a/src/api/wix/WixToolset.Extensibility/Services/IFileSystem.cs b/src/api/wix/WixToolset.Extensibility/Services/IFileSystem.cs index 26184462..cd987555 100644 --- a/src/api/wix/WixToolset.Extensibility/Services/IFileSystem.cs +++ b/src/api/wix/WixToolset.Extensibility/Services/IFileSystem.cs @@ -3,6 +3,7 @@ namespace WixToolset.Extensibility.Services { using System; + using System.IO; /// /// Abstracts basic file system operations. @@ -32,6 +33,15 @@ namespace WixToolset.Extensibility.Services /// The destination file. void MoveFile(string source, string destination); + /// + /// Opens a file. + /// + /// The file to open. + /// A System.IO.FileMode value that specifies whether a file is created if one does not exist, and determines whether the contents of existing files are retained or overwritten. + /// A System.IO.FileAccess value that specifies the operations that can be performed on the file. + /// A System.IO.FileShare value specifying the type of access other threads have to the file. + FileStream OpenFile(string path, FileMode mode, FileAccess access, FileShare share); + /// /// Executes an action and retries on any exception a few times with short pause /// between each attempt. Primarily intended for use with file system operations diff --git a/src/wix/WixToolset.Core.Burn/Bundles/BurnReader.cs b/src/wix/WixToolset.Core.Burn/Bundles/BurnReader.cs index e87e32c7..acc76a3b 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/BurnReader.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/BurnReader.cs @@ -56,7 +56,7 @@ namespace WixToolset.Core.Burn.Bundles /// Burn reader. public static BurnReader Open(IMessaging messaging, IFileSystem fileSystem, string fileExe) { - var binaryReader = new BinaryReader(File.Open(fileExe, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete)); + var binaryReader = new BinaryReader(fileSystem.OpenFile(fileExe, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete)); var reader = new BurnReader(messaging, fileSystem, fileExe) { binaryReader = binaryReader, @@ -92,7 +92,7 @@ namespace WixToolset.Core.Burn.Bundles var uxContainerSlot = this.AttachedContainers[0]; this.binaryReader.BaseStream.Seek(this.UXAddress, SeekOrigin.Begin); - using (Stream tempCab = File.Open(tempCabPath, FileMode.Create, FileAccess.Write)) + using (Stream tempCab = this.fileSystem.OpenFile(tempCabPath, FileMode.Create, FileAccess.Write, FileShare.Read)) { BurnCommon.CopyStream(this.binaryReader.BaseStream, tempCab, (int)uxContainerSlot.Size); } @@ -169,7 +169,7 @@ namespace WixToolset.Core.Burn.Bundles var tempCabPath = Path.Combine(tempDirectory, $"a{i}.cab"); this.binaryReader.BaseStream.Seek(nextAddress, SeekOrigin.Begin); - using (Stream tempCab = File.Open(tempCabPath, FileMode.Create, FileAccess.Write)) + using (Stream tempCab = this.fileSystem.OpenFile(tempCabPath, FileMode.Create, FileAccess.Write, FileShare.Read)) { BurnCommon.CopyStream(this.binaryReader.BaseStream, tempCab, (int)cntnr.Size); } diff --git a/src/wix/WixToolset.Core.Burn/Bundles/BurnWriter.cs b/src/wix/WixToolset.Core.Burn/Bundles/BurnWriter.cs index 1f0a032e..f6282443 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/BurnWriter.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/BurnWriter.cs @@ -24,35 +24,33 @@ namespace WixToolset.Core.Burn.Bundles { private bool disposed; private BinaryWriter binaryWriter; + private readonly IFileSystem fileSystem; - /// - /// Creates a BurnWriter for re-writing a PE file. - /// - /// - /// File to modify in-place. - private BurnWriter(IMessaging messaging, string fileExe) + private BurnWriter(IMessaging messaging, IFileSystem fileSystem, string fileExe) : base(messaging, fileExe) { + this.fileSystem = fileSystem; } /// /// Opens a Burn writer. /// - /// + /// Messaging system. + /// File system abstraction. /// Path to file. /// Burn writer. - public static BurnWriter Open(IMessaging messaging, string fileExe) + public static BurnWriter Open(IMessaging messaging, IFileSystem fileSystem, string fileExe) { - var writer = new BurnWriter(messaging, fileExe); + var writer = new BurnWriter(messaging, fileSystem, fileExe); - using (var binaryReader = new BinaryReader(File.Open(fileExe, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete))) + using (var binaryReader = new BinaryReader(fileSystem.OpenFile(fileExe, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete))) { writer.Initialize(binaryReader); } if (!writer.Invalid) { - writer.binaryWriter = new BinaryWriter(File.Open(fileExe, FileMode.Open, FileAccess.ReadWrite, FileShare.Read | FileShare.Delete)); + writer.binaryWriter = new BinaryWriter(fileSystem.OpenFile(fileExe, FileMode.Open, FileAccess.ReadWrite, FileShare.Read | FileShare.Delete)); } return writer; @@ -109,7 +107,7 @@ namespace WixToolset.Core.Burn.Bundles /// true if the container data is successfully appended; false otherwise public bool AppendContainer(string fileContainer, BurnCommon.Container container) { - using (var reader = File.OpenRead(fileContainer)) + using (var reader = this.fileSystem.OpenFile(fileContainer, FileMode.Open, FileAccess.Read, FileShare.Read)) { return this.AppendContainer(reader, reader.Length, container); } @@ -158,7 +156,7 @@ namespace WixToolset.Core.Burn.Bundles public bool AppendContainer(Stream containerStream, long containerSize, BurnCommon.Container container) { var containerCount = (uint)this.AttachedContainers.Count; - uint burnSectionOffsetSize = BURN_SECTION_OFFSET_UXSIZE + (containerCount * sizeof(uint)); + var burnSectionOffsetSize = BURN_SECTION_OFFSET_UXSIZE + (containerCount * sizeof(uint)); var containerSlot = new ContainerSlot((uint)containerSize); switch (container) diff --git a/src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs index fdc3dfe3..64e74bbe 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs @@ -82,7 +82,7 @@ namespace WixToolset.Core.Burn.Bundles // Update the .wixburn section to point to at the UX and attached container(s) then attach the containers // if they should be attached. - using (var writer = BurnWriter.Open(this.Messaging, bundleTempPath)) + using (var writer = BurnWriter.Open(this.Messaging, this.FileSystem, bundleTempPath)) { var burnStubFile = new FileInfo(bundleTempPath); writer.InitializeBundleSectionData(burnStubFile.Length, this.BundleSymbol.BundleId); diff --git a/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleCommand.cs b/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleCommand.cs index d68d372c..422ad329 100644 --- a/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleCommand.cs @@ -40,7 +40,7 @@ namespace WixToolset.Core.Burn.Inscribe { this.FileSystem.CopyFile(this.SignedEngineFile, tempFile, allowHardlink: false); - using (var writer = BurnWriter.Open(this.Messaging, tempFile)) + using (var writer = BurnWriter.Open(this.Messaging, this.FileSystem, tempFile)) { inscribed = writer.ReattachContainers(reader); } diff --git a/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleEngineCommand.cs b/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleEngineCommand.cs index c00788ca..3fde859a 100644 --- a/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleEngineCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleEngineCommand.cs @@ -33,7 +33,7 @@ namespace WixToolset.Core.Burn.Inscribe var tempFile = Path.Combine(this.IntermediateFolder, "bundle_engine_unsigned.exe"); using (var reader = BurnReader.Open(this.Messaging, this.FileSystem, this.InputFilePath)) - using (var writer = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.Read | FileShare.Delete)) + using (var writer = this.FileSystem.OpenFile(tempFile, FileMode.Create, FileAccess.Write, FileShare.Read | FileShare.Delete)) { reader.Stream.Seek(0, SeekOrigin.Begin); diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/AssemblyNameReader.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/AssemblyNameReader.cs index 5dcfa1e6..0bb9c389 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/AssemblyNameReader.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/AssemblyNameReader.cs @@ -11,14 +11,15 @@ namespace WixToolset.Core.WindowsInstaller.Bind using System.Xml; using System.Xml.XPath; using WixToolset.Data; + using WixToolset.Extensibility.Services; internal static class AssemblyNameReader { - public static AssemblyName ReadAssembly(SourceLineNumber sourceLineNumbers, string assemblyPath, string fileVersion) + public static AssemblyName ReadAssembly(IFileSystem fileSystem, SourceLineNumber sourceLineNumbers, string assemblyPath, string fileVersion) { try { - using (var stream = File.OpenRead(assemblyPath)) + using (var stream = fileSystem.OpenFile(assemblyPath, FileMode.Open, FileAccess.Read, FileShare.Read)) using (var peReader = new PEReader(stream)) { var reader = peReader.GetMetadataReader(); diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs index 41559f8b..e3d70b70 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs @@ -28,15 +28,15 @@ namespace WixToolset.Core.WindowsInstaller.Bind this.Messaging = context.ServiceProvider.GetService(); this.WindowsInstallerBackendHelper = context.ServiceProvider.GetService(); - - this.PathResolver = this.ServiceProvider.GetService(); + this.FileSystem = context.ServiceProvider.GetService(); + this.PathResolver = context.ServiceProvider.GetService(); this.CabbingThreadCount = context.CabbingThreadCount; this.CabCachePath = context.CabCachePath; this.DefaultCompressionLevel = context.DefaultCompressionLevel; this.DelayedFields = context.DelayedFields; this.ExpectedEmbeddedFiles = context.ExpectedEmbeddedFiles; - this.FileSystemManager = new FileSystemManager(context.FileSystemExtensions); + this.FileSystemManager = new FileSystemManager(this.FileSystem, context.FileSystemExtensions); this.Intermediate = context.IntermediateRepresentation; this.IntermediateFolder = context.IntermediateFolder; this.OutputPath = context.OutputPath; @@ -52,12 +52,14 @@ namespace WixToolset.Core.WindowsInstaller.Bind this.BackendExtensions = backendExtension; } - public IServiceProvider ServiceProvider { get; } + private IServiceProvider ServiceProvider { get; } private IMessaging Messaging { get; } private IWindowsInstallerBackendHelper WindowsInstallerBackendHelper { get; } + private IFileSystem FileSystem { get; } + private IPathResolver PathResolver { get; } private int CabbingThreadCount { get; } @@ -279,7 +281,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind // Gather information about files that do not come from merge modules. { - var command = new UpdateFileFacadesCommand(this.Messaging, section, allFileFacades, fileFacadesFromIntermediate, variableCache, overwriteHash: true); + var command = new UpdateFileFacadesCommand(this.Messaging, this.FileSystem, section, allFileFacades, fileFacadesFromIntermediate, variableCache, overwriteHash: true); command.Execute(); } @@ -323,7 +325,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind { var updatedFacades = reresolvedFiles.Select(f => allFileFacades.First(ff => ff.Id == f.Id?.Id)); - var command = new UpdateFileFacadesCommand(this.Messaging, section, allFileFacades, updatedFacades, variableCache, overwriteHash: false); + var command = new UpdateFileFacadesCommand(this.Messaging, this.FileSystem, section, allFileFacades, updatedFacades, variableCache, overwriteHash: false); command.Execute(); } } @@ -461,7 +463,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind var trackMsi = this.WindowsInstallerBackendHelper.TrackFile(this.OutputPath, TrackedFileType.BuiltTargetOutput); trackedFiles.Add(trackMsi); - var command = new GenerateDatabaseCommand(this.Messaging, this.WindowsInstallerBackendHelper, this.FileSystemManager, data, trackMsi.Path, tableDefinitions, this.IntermediateFolder, keepAddedColumns: false, this.SuppressAddingValidationRows, useSubdirectory: false); + var command = new GenerateDatabaseCommand(this.Messaging, this.WindowsInstallerBackendHelper, this.FileSystem, this.FileSystemManager, data, trackMsi.Path, tableDefinitions, this.IntermediateFolder, keepAddedColumns: false, this.SuppressAddingValidationRows, useSubdirectory: false); command.Execute(); trackedFiles.AddRange(command.GeneratedTemporaryFiles); diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindTransformCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindTransformCommand.cs index 3d8e7595..e6ab3a28 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindTransformCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindTransformCommand.cs @@ -13,10 +13,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind internal class BindTransformCommand { - public BindTransformCommand(IMessaging messaging, IBackendHelper backendHelper, FileSystemManager fileSystemManager, string intermediateFolder, WindowsInstallerData transform, string outputPath, TableDefinitionCollection tableDefinitions) + public BindTransformCommand(IMessaging messaging, IBackendHelper backendHelper, IFileSystem fileSystem, FileSystemManager fileSystemManager, string intermediateFolder, WindowsInstallerData transform, string outputPath, TableDefinitionCollection tableDefinitions) { this.Messaging = messaging; this.BackendHelper = backendHelper; + this.FileSystem = fileSystem; this.FileSystemManager = fileSystemManager; this.IntermediateFolder = intermediateFolder; this.Transform = transform; @@ -28,6 +29,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind private IBackendHelper BackendHelper { get; } + private IFileSystem FileSystem { get; } + private FileSystemManager FileSystemManager { get; } private TableDefinitionCollection TableDefinitions { get; } @@ -398,7 +401,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind { if (!String.IsNullOrEmpty(emptyFile)) { - using (var fileStream = File.Create(emptyFile)) + using (var fileStream = this.FileSystem.OpenFile(emptyFile, FileMode.Create, FileAccess.Write, FileShare.None)) { } } @@ -434,7 +437,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind private void GenerateDatabase(WindowsInstallerData output, string outputPath, bool keepAddedColumns) { - var command = new GenerateDatabaseCommand(this.Messaging, this.BackendHelper, this.FileSystemManager, output, outputPath, this.TableDefinitions, this.IntermediateFolder, keepAddedColumns, suppressAddingValidationRows: true, useSubdirectory: true); + var command = new GenerateDatabaseCommand(this.Messaging, this.BackendHelper, this.FileSystem, this.FileSystemManager, output, outputPath, this.TableDefinitions, this.IntermediateFolder, keepAddedColumns, suppressAddingValidationRows: true, useSubdirectory: true); command.Execute(); } } diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/CreatePatchTransformsCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/CreatePatchTransformsCommand.cs index 0d88cfd1..1f6b6558 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/CreatePatchTransformsCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/CreatePatchTransformsCommand.cs @@ -16,10 +16,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind internal class CreatePatchTransformsCommand { - public CreatePatchTransformsCommand(IMessaging messaging, IBackendHelper backendHelper, IPathResolver pathResolver, IFileResolver fileResolver, IReadOnlyCollection resolverExtensions, IReadOnlyCollection backendExtensions, Intermediate intermediate, string intermediateFolder, IReadOnlyCollection bindPaths) + public CreatePatchTransformsCommand(IMessaging messaging, IBackendHelper backendHelper, IFileSystem fileSystem, IPathResolver pathResolver, IFileResolver fileResolver, IReadOnlyCollection resolverExtensions, IReadOnlyCollection backendExtensions, Intermediate intermediate, string intermediateFolder, IReadOnlyCollection bindPaths) { this.Messaging = messaging; this.BackendHelper = backendHelper; + this.FileSystem = fileSystem; this.PathResolver = pathResolver; this.FileResolver = fileResolver; this.ResolverExtensions = resolverExtensions; @@ -33,6 +34,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind private IBackendHelper BackendHelper { get; } + private IFileSystem FileSystem { get; } + private IPathResolver PathResolver { get; } private IFileResolver FileResolver { get; } @@ -105,7 +108,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind var exportBasePath = Path.Combine(this.IntermediateFolder, stageFolder); var extractFilesFolder = Path.Combine(exportBasePath, "File"); - var command = new UnbindDatabaseCommand(this.Messaging, this.BackendHelper, this.PathResolver, path, null, OutputType.Product, exportBasePath, extractFilesFolder, this.IntermediateFolder, enableDemodularization: false, skipSummaryInfo: false); + var command = new UnbindDatabaseCommand(this.Messaging, this.BackendHelper, this.FileSystem, this.PathResolver, path, null, OutputType.Product, exportBasePath, extractFilesFolder, this.IntermediateFolder, enableDemodularization: false, skipSummaryInfo: false); data = command.Execute(); } diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/FileSystemManager.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/FileSystemManager.cs index fe65ccef..8707d5f1 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/FileSystemManager.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/FileSystemManager.cs @@ -5,15 +5,20 @@ namespace WixToolset.Core.WindowsInstaller.Bind using System; using System.Collections.Generic; using System.IO; + using System.Runtime.CompilerServices; using WixToolset.Extensibility; + using WixToolset.Extensibility.Services; internal class FileSystemManager { - public FileSystemManager(IEnumerable fileSystemExtensions) + public FileSystemManager(IFileSystem fileSystem, IEnumerable fileSystemExtensions) { + this.FileSystem = fileSystem; this.Extensions = fileSystemExtensions; } + private IFileSystem FileSystem { get; } + private IEnumerable Extensions { get; } public bool CompareFiles(string firstPath, string secondPath) @@ -27,18 +32,18 @@ namespace WixToolset.Core.WindowsInstaller.Bind } } - return BuiltinCompareFiles(firstPath, secondPath); + return this.BuiltinCompareFiles(firstPath, secondPath); } - private static bool BuiltinCompareFiles(string firstPath, string secondPath) + private bool BuiltinCompareFiles(string firstPath, string secondPath) { if (String.Equals(firstPath, secondPath, StringComparison.OrdinalIgnoreCase)) { return true; } - using (var firstStream = File.OpenRead(firstPath)) - using (var secondStream = File.OpenRead(secondPath)) + using (var firstStream = this.FileSystem.OpenFile(firstPath, FileMode.Open, FileAccess.Read, FileShare.Read)) + using (var secondStream = this.FileSystem.OpenFile(secondPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { if (firstStream.Length != secondStream.Length) { diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/GenerateDatabaseCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/GenerateDatabaseCommand.cs index b8cca752..361f797d 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/GenerateDatabaseCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/GenerateDatabaseCommand.cs @@ -18,10 +18,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind { private const string IdtsSubFolder = "_idts"; - public GenerateDatabaseCommand(IMessaging messaging, IBackendHelper backendHelper, FileSystemManager fileSystemManager, WindowsInstallerData data, string outputPath, TableDefinitionCollection tableDefinitions, string intermediateFolder, bool keepAddedColumns, bool suppressAddingValidationRows, bool useSubdirectory) + public GenerateDatabaseCommand(IMessaging messaging, IBackendHelper backendHelper, IFileSystem fileSystem, FileSystemManager fileSystemManager, WindowsInstallerData data, string outputPath, TableDefinitionCollection tableDefinitions, string intermediateFolder, bool keepAddedColumns, bool suppressAddingValidationRows, bool useSubdirectory) { this.Messaging = messaging; this.BackendHelper = backendHelper; + this.FileSystem = fileSystem; this.FileSystemManager = fileSystemManager; this.Data = data; this.OutputPath = outputPath; @@ -34,6 +35,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind private IBackendHelper BackendHelper { get; } + private IFileSystem FileSystem { get; } + private FileSystemManager FileSystemManager { get; } /// @@ -358,7 +361,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind var transformFile = Path.Combine(this.IntermediateFolder, String.Concat(subStorage.Name, ".mst")); // Bind the transform. - var command = new BindTransformCommand(this.Messaging, this.BackendHelper, this.FileSystemManager, this.IntermediateFolder, subStorage.Data, transformFile, this.TableDefinitions); + var command = new BindTransformCommand(this.Messaging, this.BackendHelper, this.FileSystem, this.FileSystemManager, this.IntermediateFolder, subStorage.Data, transformFile, this.TableDefinitions); command.Execute(); if (this.Messaging.EncounteredError) diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs index f2f8e126..7f764f49 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs @@ -19,9 +19,10 @@ namespace WixToolset.Core.WindowsInstaller.Bind /// internal class UpdateFileFacadesCommand { - public UpdateFileFacadesCommand(IMessaging messaging, IntermediateSection section, IEnumerable allFileFacades, IEnumerable updateFileFacades, IDictionary variableCache, bool overwriteHash) + public UpdateFileFacadesCommand(IMessaging messaging, IFileSystem fileSystem, IntermediateSection section, IEnumerable allFileFacades, IEnumerable updateFileFacades, IDictionary variableCache, bool overwriteHash) { this.Messaging = messaging; + this.FileSystem = fileSystem; this.Section = section; this.AllFileFacades = allFileFacades; this.UpdateFileFacades = updateFileFacades; @@ -31,6 +32,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind private IMessaging Messaging { get; } + private IFileSystem FileSystem { get; } + private IntermediateSection Section { get; } private IEnumerable AllFileFacades { get; } @@ -212,7 +215,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind { try { - var assemblyName = AssemblyNameReader.ReadAssembly(facade.SourceLineNumber, fileInfo.FullName, version); + var assemblyName = AssemblyNameReader.ReadAssembly(this.FileSystem, facade.SourceLineNumber, fileInfo.FullName, version); this.SetMsiAssemblyName(assemblyNameSymbols, facade, assemblySymbol, "name", assemblyName.Name); this.SetMsiAssemblyName(assemblyNameSymbols, facade, assemblySymbol, "culture", assemblyName.Culture); diff --git a/src/wix/WixToolset.Core.WindowsInstaller/CommandLine/TransformSubcommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/CommandLine/TransformSubcommand.cs index e37267bb..3b582e74 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/CommandLine/TransformSubcommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/CommandLine/TransformSubcommand.cs @@ -21,6 +21,7 @@ namespace WixToolset.Core.WindowsInstaller.CommandLine { this.Messaging = serviceProvider.GetService(); this.BackendHelper = serviceProvider.GetService(); + this.FileSystem = serviceProvider.GetService(); this.PathResolver = serviceProvider.GetService(); this.ExtensionManager = serviceProvider.GetService(); } @@ -29,6 +30,8 @@ namespace WixToolset.Core.WindowsInstaller.CommandLine private IBackendHelper BackendHelper { get; } + private IFileSystem FileSystem { get; } + private IPathResolver PathResolver { get; } private IExtensionManager ExtensionManager { get; } @@ -342,11 +345,11 @@ namespace WixToolset.Core.WindowsInstaller.CommandLine else { var fileSystemExtensions = this.ExtensionManager.GetServices(); - var fileSystemManager = new FileSystemManager(fileSystemExtensions); + var fileSystemManager = new FileSystemManager(this.FileSystem, fileSystemExtensions); var tableDefinitions = this.GetTableDefinitions(); - var bindCommand = new BindTransformCommand(this.Messaging, this.BackendHelper, fileSystemManager, this.IntermediateFolder, transform, this.OutputPath, tableDefinitions); + var bindCommand = new BindTransformCommand(this.Messaging, this.BackendHelper, this.FileSystem, fileSystemManager, this.IntermediateFolder, transform, this.OutputPath, tableDefinitions); bindCommand.Execute(); } } @@ -379,7 +382,7 @@ namespace WixToolset.Core.WindowsInstaller.CommandLine { if (!DataLoader.TryLoadWindowsInstallerData(path, out var data)) { - var unbindCommand = new UnbindDatabaseCommand(this.Messaging, this.BackendHelper, this.PathResolver, path, null, OutputType.Product, this.ExportBasePath, null, this.IntermediateFolder, enableDemodularization: false, skipSummaryInfo: false); + var unbindCommand = new UnbindDatabaseCommand(this.Messaging, this.BackendHelper, this.FileSystem, this.PathResolver, path, null, OutputType.Product, this.ExportBasePath, null, this.IntermediateFolder, enableDemodularization: false, skipSummaryInfo: false); data = unbindCommand.Execute(); } diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs index 80fcb8e1..3f0d0c51 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs @@ -19,6 +19,7 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe public InscribeMsiPackageCommand(IServiceProvider serviceProvider, string inputPath, string intermediateFolder, string outputPath) { this.Messaging = serviceProvider.GetService(); + this.FileSystem = serviceProvider.GetService(); this.WindowsInstallerBackendHelper = serviceProvider.GetService(); this.TableDefinitions = new TableDefinitionCollection(WindowsInstallerTableDefinitions.All); this.InputPath = inputPath; @@ -34,6 +35,8 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe private IMessaging Messaging { get; } + private IFileSystem FileSystem { get; } + private IWindowsInstallerBackendHelper WindowsInstallerBackendHelper { get; } private TableDefinitionCollection TableDefinitions { get; } @@ -48,8 +51,7 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe if (!String.Equals(this.InputPath, this.OutputPath, StringComparison.OrdinalIgnoreCase)) { - Directory.CreateDirectory(Path.GetDirectoryName(this.OutputPath)); - File.Copy(this.InputPath, this.OutputPath, true); + this.FileSystem.CopyFile(this.InputPath, this.OutputPath, allowHardlink: false); } var attributes = File.GetAttributes(databasePath); @@ -96,7 +98,7 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe Directory.CreateDirectory(hashPath); hashPath = Path.Combine(hashPath, hashFileName); - using (var fs = File.Create(hashPath)) + using (var fs = this.FileSystem.OpenFile(hashPath, FileMode.Create, FileAccess.Write, FileShare.None)) { int bytesRead; var buffer = new byte[1024 * 4]; @@ -127,7 +129,7 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe Directory.CreateDirectory(certPath); certPath = Path.Combine(certPath, String.Concat(certificateId, ".cer")); - using (var fs = File.Create(certPath)) + using (var fs = this.FileSystem.OpenFile(certPath, FileMode.Create, FileAccess.Write, FileShare.None)) { int bytesRead; var buffer = new byte[1024 * 4]; @@ -221,9 +223,9 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe var certPath = Path.Combine(this.IntermediateFolder, "MsiDigitalCertificate"); Directory.CreateDirectory(certPath); certPath = Path.Combine(certPath, String.Concat(cert2.Thumbprint, ".cer")); - File.Delete(certPath); + this.FileSystem.DeleteFile(certPath, true); - using (var writer = new BinaryWriter(File.Open(certPath, FileMode.Create))) + using (var writer = new BinaryWriter(this.FileSystem.OpenFile(certPath, FileMode.Create, FileAccess.Write, FileShare.Read))) { writer.Write(cert2.RawData); writer.Close(); diff --git a/src/wix/WixToolset.Core.WindowsInstaller/MspBackend.cs b/src/wix/WixToolset.Core.WindowsInstaller/MspBackend.cs index ace382de..8320bb0a 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/MspBackend.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/MspBackend.cs @@ -17,6 +17,8 @@ namespace WixToolset.Core.WindowsInstaller var backendHelper = context.ServiceProvider.GetService(); + var fileSystem = context.ServiceProvider.GetService(); + var pathResolver = context.ServiceProvider.GetService(); var fileResolver = context.ServiceProvider.GetService(); @@ -36,7 +38,7 @@ namespace WixToolset.Core.WindowsInstaller IEnumerable patchTransforms; PatchFilterMap patchFilterMap; { - var command = new CreatePatchTransformsCommand(messaging, backendHelper, pathResolver, fileResolver, resolveExtensions, backendExtensions, context.IntermediateRepresentation, context.IntermediateFolder, context.BindPaths); + var command = new CreatePatchTransformsCommand(messaging, backendHelper, fileSystem, pathResolver, fileResolver, resolveExtensions, backendExtensions, context.IntermediateRepresentation, context.IntermediateFolder, context.BindPaths); command.Execute(); patchTransforms = command.PatchTransforms; diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Unbind/ExtractCabinetsCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Unbind/ExtractCabinetsCommand.cs index 9aa6f3d4..c2981b08 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Unbind/ExtractCabinetsCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Unbind/ExtractCabinetsCommand.cs @@ -12,11 +12,13 @@ namespace WixToolset.Core.WindowsInstaller.Unbind using WixToolset.Data; using WixToolset.Data.WindowsInstaller; using WixToolset.Data.WindowsInstaller.Rows; + using WixToolset.Extensibility.Services; internal class ExtractCabinetsCommand { - public ExtractCabinetsCommand(WindowsInstallerData output, Database database, string inputFilePath, string exportBasePath, string intermediateFolder, bool treatOutputAsModule = false) + public ExtractCabinetsCommand(IFileSystem fileSystem, WindowsInstallerData output, Database database, string inputFilePath, string exportBasePath, string intermediateFolder, bool treatOutputAsModule = false) { + this.FileSystem = fileSystem; this.Output = output; this.Database = database; this.InputFilePath = inputFilePath; @@ -27,6 +29,8 @@ namespace WixToolset.Core.WindowsInstaller.Unbind public Dictionary ExtractedFileIdsWithMediaRow { get; private set; } + private IFileSystem FileSystem { get; } + private WindowsInstallerData Output { get; } private Database Database { get; } @@ -100,7 +104,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind // ensure the parent directory exists Directory.CreateDirectory(Path.GetDirectoryName(cabinetPath)); - using (var fs = File.Create(cabinetPath)) + using (var fs = this.FileSystem.OpenFile(cabinetPath, FileMode.Create, FileAccess.Write, FileShare.None)) { int bytesRead; var buffer = new byte[4096]; diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs index 7f6537e5..54534e50 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs @@ -21,10 +21,11 @@ namespace WixToolset.Core.WindowsInstaller.Unbind { private static readonly Regex Modularization = new Regex(@"\.[0-9A-Fa-f]{8}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{4}_[0-9A-Fa-f]{12}"); - public UnbindDatabaseCommand(IMessaging messaging, IBackendHelper backendHelper, IPathResolver pathResolver, string databasePath, Database database, OutputType outputType, string exportBasePath, string extractFilesFolder, string intermediateFolder, bool enableDemodularization, bool skipSummaryInfo) + public UnbindDatabaseCommand(IMessaging messaging, IBackendHelper backendHelper, IFileSystem fileSystem, IPathResolver pathResolver, string databasePath, Database database, OutputType outputType, string exportBasePath, string extractFilesFolder, string intermediateFolder, bool enableDemodularization, bool skipSummaryInfo) { this.Messaging = messaging; this.BackendHelper = backendHelper; + this.FileSystem = fileSystem; this.PathResolver = pathResolver; this.DatabasePath = databasePath; this.Database = database; @@ -38,9 +39,11 @@ namespace WixToolset.Core.WindowsInstaller.Unbind this.TableDefinitions = new TableDefinitionCollection(WindowsInstallerTableDefinitions.All); } - public IMessaging Messaging { get; } + private IMessaging Messaging { get; } - public IBackendHelper BackendHelper { get; } + private IBackendHelper BackendHelper { get; } + + private IFileSystem FileSystem { get; } private IPathResolver PathResolver { get; } @@ -203,7 +206,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind Directory.CreateDirectory(Path.Combine(this.ExportBasePath, tableName)); - using (var fs = File.Create(source)) + using (var fs = this.FileSystem.OpenFile(source, FileMode.Create, FileAccess.Write, FileShare.None)) { int bytesRead; var buffer = new byte[4096]; @@ -531,7 +534,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind if (!String.IsNullOrEmpty(this.ExtractFilesFolder)) { - var extractCommand = new ExtractCabinetsCommand(output, this.Database, this.DatabasePath, this.ExtractFilesFolder, this.IntermediateFolder); + var extractCommand = new ExtractCabinetsCommand(this.FileSystem, output, this.Database, this.DatabasePath, this.ExtractFilesFolder, this.IntermediateFolder); extractCommand.Execute(); extractedFileIds = new HashSet(extractCommand.ExtractedFileIdsWithMediaRow.Keys, StringComparer.OrdinalIgnoreCase); diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Unbind/UnbindTransformCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Unbind/UnbindTransformCommand.cs index f2567ebb..bb4da1ed 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Unbind/UnbindTransformCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Unbind/UnbindTransformCommand.cs @@ -16,10 +16,11 @@ namespace WixToolset.Core.WindowsInstaller.Unbind internal class UnbindTransformCommand { - public UnbindTransformCommand(IMessaging messaging, IBackendHelper backendHelper, IPathResolver pathResolver, FileSystemManager fileSystemManager, string transformFile, string exportBasePath, string intermediateFolder) + public UnbindTransformCommand(IMessaging messaging, IBackendHelper backendHelper, IFileSystem fileSystem, IPathResolver pathResolver, FileSystemManager fileSystemManager, string transformFile, string exportBasePath, string intermediateFolder) { this.Messaging = messaging; this.BackendHelper = backendHelper; + this.FileSystem = fileSystem; this.PathResolver = pathResolver; this.FileSystemManager = fileSystemManager; this.TransformFile = transformFile; @@ -33,6 +34,8 @@ namespace WixToolset.Core.WindowsInstaller.Unbind private IBackendHelper BackendHelper { get; } + private IFileSystem FileSystem { get; } + private IPathResolver PathResolver { get; } private FileSystemManager FileSystemManager { get; } @@ -116,7 +119,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind using (var msiDatabase = this.ApplyTransformToSchemaDatabase(schemaDatabasePath, TransformErrorConditions.All | TransformErrorConditions.ViewTransform)) { // unbind the database - var unbindCommand = new UnbindDatabaseCommand(this.Messaging, this.BackendHelper, this.PathResolver, schemaDatabasePath, msiDatabase, OutputType.Product, null, null, this.IntermediateFolder, enableDemodularization: false, skipSummaryInfo: true); + var unbindCommand = new UnbindDatabaseCommand(this.Messaging, this.BackendHelper, this.FileSystem, this.PathResolver, schemaDatabasePath, msiDatabase, OutputType.Product, null, null, this.IntermediateFolder, enableDemodularization: false, skipSummaryInfo: true); var transformViewOutput = unbindCommand.Execute(); return transformViewOutput.Tables["_TransformView"]; @@ -177,7 +180,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind { // unbind the database - var unbindCommand = new UnbindDatabaseCommand(this.Messaging, this.BackendHelper, this.PathResolver, schemaDatabasePath, database, OutputType.Product, this.ExportBasePath, null, this.IntermediateFolder, enableDemodularization: false, skipSummaryInfo: true); + var unbindCommand = new UnbindDatabaseCommand(this.Messaging, this.BackendHelper, this.FileSystem, this.PathResolver, schemaDatabasePath, database, OutputType.Product, this.ExportBasePath, null, this.IntermediateFolder, enableDemodularization: false, skipSummaryInfo: true); output = unbindCommand.Execute(); } @@ -324,7 +327,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind if (null == this.EmptyFile) { this.EmptyFile = Path.Combine(this.IntermediateFolder, ".empty"); - using (var fileStream = File.Create(this.EmptyFile)) + using (var fileStream = this.FileSystem.OpenFile(this.EmptyFile, FileMode.Create, FileAccess.Write, FileShare.None)) { } } @@ -343,7 +346,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind private void GenerateDatabase(WindowsInstallerData data) { - var command = new GenerateDatabaseCommand(this.Messaging, this.BackendHelper, this.FileSystemManager, data, data.SourceLineNumbers.FileName, this.TableDefinitions, this.IntermediateFolder, keepAddedColumns: true, suppressAddingValidationRows: true, useSubdirectory: false); + var command = new GenerateDatabaseCommand(this.Messaging, this.BackendHelper, this.FileSystem, this.FileSystemManager, data, data.SourceLineNumbers.FileName, this.TableDefinitions, this.IntermediateFolder, keepAddedColumns: true, suppressAddingValidationRows: true, useSubdirectory: false); command.Execute(); } diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Validate/ValidateDatabaseCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Validate/ValidateDatabaseCommand.cs index 06fa6817..24dd9927 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Validate/ValidateDatabaseCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Validate/ValidateDatabaseCommand.cs @@ -34,9 +34,6 @@ namespace WixToolset.Core.WindowsInstaller.Validate public IEnumerable TrackedFiles { get; private set; } - /// - /// Encountered error implementation for . - /// public bool EncounteredError => this.Messaging.EncounteredError; private IMessaging Messaging { get; } @@ -84,10 +81,7 @@ namespace WixToolset.Core.WindowsInstaller.Validate } finally { - if (File.Exists(workingDatabasePath)) - { - File.Delete(workingDatabasePath); - } + this.FileSystem.DeleteFile(workingDatabasePath); } stopwatch.Stop(); diff --git a/src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerDecompiler.cs b/src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerDecompiler.cs index f3d116f6..b41876b3 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerDecompiler.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/WindowsInstallerDecompiler.cs @@ -3,7 +3,6 @@ namespace WixToolset.Core.WindowsInstaller { using System; - using System.Collections.Generic; using System.IO; using System.Linq; using WixToolset.Core.WindowsInstaller.Bind; @@ -74,25 +73,27 @@ namespace WixToolset.Core.WindowsInstaller var backendHelper = context.ServiceProvider.GetService(); + var fileSystem = context.ServiceProvider.GetService(); + var pathResolver = context.ServiceProvider.GetService(); if (context.DecompileType == OutputType.Transform) { - return this.DecompileTransform(context, backendHelper, pathResolver); + return this.DecompileTransform(context, backendHelper, fileSystem, pathResolver); } else { - return this.DecompileDatabase(context, backendHelper, pathResolver); + return this.DecompileDatabase(context, backendHelper, fileSystem, pathResolver); } } - private IWindowsInstallerDecompileResult DecompileDatabase(IWindowsInstallerDecompileContext context, IWindowsInstallerBackendHelper backendHelper, IPathResolver pathResolver) + private IWindowsInstallerDecompileResult DecompileDatabase(IWindowsInstallerDecompileContext context, IWindowsInstallerBackendHelper backendHelper, IFileSystem fileSystem, IPathResolver pathResolver) { var extractFilesFolder = context.SuppressExtractCabinets || (String.IsNullOrEmpty(context.CabinetExtractFolder) && String.IsNullOrEmpty(context.ExtractFolder)) ? null : String.IsNullOrEmpty(context.CabinetExtractFolder) ? Path.Combine(context.ExtractFolder, "File") : context.CabinetExtractFolder; var outputType = context.TreatProductAsModule ? OutputType.Module : context.DecompileType; - var unbindCommand = new UnbindDatabaseCommand(this.Messaging, backendHelper, pathResolver, context.DecompilePath, null, outputType, context.ExtractFolder, extractFilesFolder, context.IntermediateFolder, enableDemodularization: true, skipSummaryInfo: false); + var unbindCommand = new UnbindDatabaseCommand(this.Messaging, backendHelper, fileSystem, pathResolver, context.DecompilePath, null, outputType, context.ExtractFolder, extractFilesFolder, context.IntermediateFolder, enableDemodularization: true, skipSummaryInfo: false); var output = unbindCommand.Execute(); var extractedFilePaths = unbindCommand.ExportedFiles; @@ -108,13 +109,13 @@ namespace WixToolset.Core.WindowsInstaller return result; } - private IWindowsInstallerDecompileResult DecompileTransform(IWindowsInstallerDecompileContext context, IWindowsInstallerBackendHelper backendHelper, IPathResolver pathResolver) + private IWindowsInstallerDecompileResult DecompileTransform(IWindowsInstallerDecompileContext context, IWindowsInstallerBackendHelper backendHelper, IFileSystem fileSystem, IPathResolver pathResolver) { var fileSystemExtensions = this.ExtensionManager.GetServices(); - var fileSystemManager = new FileSystemManager(fileSystemExtensions); + var fileSystemManager = new FileSystemManager(fileSystem, fileSystemExtensions); - var unbindCommand = new UnbindTransformCommand(this.Messaging, backendHelper, pathResolver, fileSystemManager, context.DecompilePath, context.ExtractFolder, context.IntermediateFolder); + var unbindCommand = new UnbindTransformCommand(this.Messaging, backendHelper, fileSystem, pathResolver, fileSystemManager, context.DecompilePath, context.ExtractFolder, context.IntermediateFolder); var output = unbindCommand.Execute(); var result = context.ServiceProvider.GetService(); diff --git a/src/wix/WixToolset.Core/Common.cs b/src/wix/WixToolset.Core/Common.cs index f581e1a4..f5a9709d 100644 --- a/src/wix/WixToolset.Core/Common.cs +++ b/src/wix/WixToolset.Core/Common.cs @@ -361,44 +361,6 @@ namespace WixToolset.Core return false; } - /// - /// Recursively loops through a directory, changing an attribute on all of the underlying files. - /// An example is to add/remove the ReadOnly flag from each file. - /// - /// The directory path to start deleting from. - /// The FileAttribute to change on each file. - /// The message handler. - /// If true, add the attribute to each file. If false, remove it. - private static void RecursiveFileAttributes(string path, FileAttributes fileAttribute, bool markAttribute, IMessaging messageHandler) - { - foreach (var subDirectory in Directory.GetDirectories(path)) - { - RecursiveFileAttributes(subDirectory, fileAttribute, markAttribute, messageHandler); - } - - foreach (var filePath in Directory.GetFiles(path)) - { - var attributes = File.GetAttributes(filePath); - if (markAttribute) - { - attributes = attributes | fileAttribute; // add to list of attributes - } - else if (fileAttribute == (attributes & fileAttribute)) // if attribute set - { - attributes = attributes ^ fileAttribute; // remove from list of attributes - } - - try - { - File.SetAttributes(filePath, attributes); - } - catch (UnauthorizedAccessException) - { - messageHandler.Write(WarningMessages.AccessDeniedForSettingAttributes(null, filePath)); - } - } - } - /// /// Takes an id, and demodularizes it (if possible). /// diff --git a/src/wix/WixToolset.Core/ExtensibilityServices/FileSystem.cs b/src/wix/WixToolset.Core/ExtensibilityServices/FileSystem.cs index 4269cabe..8cf7a872 100644 --- a/src/wix/WixToolset.Core/ExtensibilityServices/FileSystem.cs +++ b/src/wix/WixToolset.Core/ExtensibilityServices/FileSystem.cs @@ -3,6 +3,7 @@ namespace WixToolset.Core.ExtensibilityServices { using System; + using System.ComponentModel; using System.IO; using System.Runtime.InteropServices; using System.Threading; @@ -50,6 +51,25 @@ namespace WixToolset.Core.ExtensibilityServices this.ExecuteWithRetries(() => File.Move(source, destination)); } + public FileStream OpenFile(string path, FileMode mode, FileAccess access, FileShare share) + { + const int maxRetries = 4; + + for (var attempt = 1; attempt <= maxRetries; ++attempt) + { + try + { + return File.Open(path, mode, access, share); + } + catch (Exception e) when (attempt < maxRetries && (e is IOException || e is SystemException || e is Win32Exception)) + { + Thread.Sleep(250); + } + } + + throw new InvalidOperationException("Cannot reach this code"); + } + public void ExecuteWithRetries(Action action, int maxRetries = 4) { for (var attempt = 1; attempt <= maxRetries; ++attempt) @@ -59,7 +79,7 @@ namespace WixToolset.Core.ExtensibilityServices action(); break; } - catch when (attempt < maxRetries) + catch (Exception e) when (attempt < maxRetries && (e is IOException || e is SystemException || e is Win32Exception)) { Thread.Sleep(250); } diff --git a/src/wix/WixToolset.Core/LayoutCreator.cs b/src/wix/WixToolset.Core/LayoutCreator.cs index 3e7ecf3a..c361f78a 100644 --- a/src/wix/WixToolset.Core/LayoutCreator.cs +++ b/src/wix/WixToolset.Core/LayoutCreator.cs @@ -112,15 +112,9 @@ namespace WixToolset.Core // Clean up temp files. foreach (var tempPath in uniqueTempPaths) { - try - { - this.SplitUniqueFolders(intermediateFolder, tempPath, uniqueFolders); + this.SplitUniqueFolders(intermediateFolder, tempPath, uniqueFolders); - File.Delete(tempPath); - } - catch // delete is best effort. - { - } + this.FileSystem.DeleteFile(tempPath); } // Clean up empty temp folders. @@ -140,7 +134,7 @@ namespace WixToolset.Core { if (tempPath.StartsWith(intermediateFolder, StringComparison.OrdinalIgnoreCase)) { - var folder = Path.GetDirectoryName(tempPath).Substring(intermediateFolder.Length); + var folder = Path.GetDirectoryName(tempPath.Substring(intermediateFolder.Length)); var parts = folder.Split(new[] { '\\', '/' }, StringSplitOptions.RemoveEmptyEntries); -- cgit v1.2.3-55-g6feb