diff options
author | Rob Mensching <rob@firegiant.com> | 2022-11-04 01:05:28 -0700 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2022-11-04 14:11:42 -0700 |
commit | f8749f8e438b150884449ad3e2e13aed750de679 (patch) | |
tree | 7cc2f8c403d0f1bbea04153ed618897f14d688a1 /src | |
parent | 8f67ce3ce8a248b7421e14ec3dd6f65e9b53ea08 (diff) | |
download | wix-f8749f8e438b150884449ad3e2e13aed750de679.tar.gz wix-f8749f8e438b150884449ad3e2e13aed750de679.tar.bz2 wix-f8749f8e438b150884449ad3e2e13aed750de679.zip |
Provide useful error message when file system operations fail
Fixes 5417
Diffstat (limited to 'src')
21 files changed, 152 insertions, 61 deletions
diff --git a/src/api/wix/WixToolset.Extensibility/Services/IFileSystem.cs b/src/api/wix/WixToolset.Extensibility/Services/IFileSystem.cs index cd987555..83a44400 100644 --- a/src/api/wix/WixToolset.Extensibility/Services/IFileSystem.cs +++ b/src/api/wix/WixToolset.Extensibility/Services/IFileSystem.cs | |||
@@ -4,6 +4,7 @@ namespace WixToolset.Extensibility.Services | |||
4 | { | 4 | { |
5 | using System; | 5 | using System; |
6 | using System.IO; | 6 | using System.IO; |
7 | using WixToolset.Data; | ||
7 | 8 | ||
8 | /// <summary> | 9 | /// <summary> |
9 | /// Abstracts basic file system operations. | 10 | /// Abstracts basic file system operations. |
@@ -13,34 +14,38 @@ namespace WixToolset.Extensibility.Services | |||
13 | /// <summary> | 14 | /// <summary> |
14 | /// Copies a file. | 15 | /// Copies a file. |
15 | /// </summary> | 16 | /// </summary> |
17 | /// <param name="sourceLineNumbers">Optional source line number requiring the copy.</param> | ||
16 | /// <param name="source">The file to copy.</param> | 18 | /// <param name="source">The file to copy.</param> |
17 | /// <param name="destination">The destination file.</param> | 19 | /// <param name="destination">The destination file.</param> |
18 | /// <param name="allowHardlink">Allow hardlinks.</param> | 20 | /// <param name="allowHardlink">Allow hardlinks.</param> |
19 | void CopyFile(string source, string destination, bool allowHardlink); | 21 | void CopyFile(SourceLineNumber sourceLineNumbers, string source, string destination, bool allowHardlink); |
20 | 22 | ||
21 | /// <summary> | 23 | /// <summary> |
22 | /// Deletes a file. | 24 | /// Deletes a file. |
23 | /// </summary> | 25 | /// </summary> |
26 | /// <param name="sourceLineNumbers">Optional source line number requiring the delete.</param> | ||
24 | /// <param name="source">The file to delete.</param> | 27 | /// <param name="source">The file to delete.</param> |
25 | /// <param name="throwOnError">Indicates the file must be deleted. Default is a best effort delete.</param> | 28 | /// <param name="throwOnError">Indicates the file must be deleted. Default is a best effort delete.</param> |
26 | /// <param name="maxRetries">Maximum retry attempts. Default is 4.</param> | 29 | /// <param name="maxRetries">Maximum retry attempts. Default is 4.</param> |
27 | void DeleteFile(string source, bool throwOnError = false, int maxRetries = 4); | 30 | void DeleteFile(SourceLineNumber sourceLineNumbers, string source, bool throwOnError = false, int maxRetries = 4); |
28 | 31 | ||
29 | /// <summary> | 32 | /// <summary> |
30 | /// Moves a file. | 33 | /// Moves a file. |
31 | /// </summary> | 34 | /// </summary> |
35 | /// <param name="sourceLineNumbers">Optional source line number requiring the move.</param> | ||
32 | /// <param name="source">The file to move.</param> | 36 | /// <param name="source">The file to move.</param> |
33 | /// <param name="destination">The destination file.</param> | 37 | /// <param name="destination">The destination file.</param> |
34 | void MoveFile(string source, string destination); | 38 | void MoveFile(SourceLineNumber sourceLineNumbers, string source, string destination); |
35 | 39 | ||
36 | /// <summary> | 40 | /// <summary> |
37 | /// Opens a file. | 41 | /// Opens a file. |
38 | /// </summary> | 42 | /// </summary> |
43 | /// <param name="sourceLineNumbers">Optional source line number requiring the file.</param> | ||
39 | /// <param name="path">The file to open.</param> | 44 | /// <param name="path">The file to open.</param> |
40 | /// <param name="mode">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.</param> | 45 | /// <param name="mode">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.</param> |
41 | /// <param name="access">A System.IO.FileAccess value that specifies the operations that can be performed on the file.</param> | 46 | /// <param name="access">A System.IO.FileAccess value that specifies the operations that can be performed on the file.</param> |
42 | /// <param name="share">A System.IO.FileShare value specifying the type of access other threads have to the file.</param> | 47 | /// <param name="share">A System.IO.FileShare value specifying the type of access other threads have to the file.</param> |
43 | FileStream OpenFile(string path, FileMode mode, FileAccess access, FileShare share); | 48 | FileStream OpenFile(SourceLineNumber sourceLineNumbers, string path, FileMode mode, FileAccess access, FileShare share); |
44 | 49 | ||
45 | /// <summary> | 50 | /// <summary> |
46 | /// Executes an action and retries on any exception a few times with short pause | 51 | /// Executes an action and retries on any exception a few times with short pause |
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/BurnReader.cs b/src/wix/WixToolset.Core.Burn/Bundles/BurnReader.cs index acc76a3b..d8e49397 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 | |||
56 | /// <returns>Burn reader.</returns> | 56 | /// <returns>Burn reader.</returns> |
57 | public static BurnReader Open(IMessaging messaging, IFileSystem fileSystem, string fileExe) | 57 | public static BurnReader Open(IMessaging messaging, IFileSystem fileSystem, string fileExe) |
58 | { | 58 | { |
59 | var binaryReader = new BinaryReader(fileSystem.OpenFile(fileExe, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete)); | 59 | var binaryReader = new BinaryReader(fileSystem.OpenFile(null, fileExe, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete)); |
60 | var reader = new BurnReader(messaging, fileSystem, fileExe) | 60 | var reader = new BurnReader(messaging, fileSystem, fileExe) |
61 | { | 61 | { |
62 | binaryReader = binaryReader, | 62 | binaryReader = binaryReader, |
@@ -92,7 +92,7 @@ namespace WixToolset.Core.Burn.Bundles | |||
92 | var uxContainerSlot = this.AttachedContainers[0]; | 92 | var uxContainerSlot = this.AttachedContainers[0]; |
93 | 93 | ||
94 | this.binaryReader.BaseStream.Seek(this.UXAddress, SeekOrigin.Begin); | 94 | this.binaryReader.BaseStream.Seek(this.UXAddress, SeekOrigin.Begin); |
95 | using (Stream tempCab = this.fileSystem.OpenFile(tempCabPath, FileMode.Create, FileAccess.Write, FileShare.Read)) | 95 | using (Stream tempCab = this.fileSystem.OpenFile(null, tempCabPath, FileMode.Create, FileAccess.Write, FileShare.Read)) |
96 | { | 96 | { |
97 | BurnCommon.CopyStream(this.binaryReader.BaseStream, tempCab, (int)uxContainerSlot.Size); | 97 | BurnCommon.CopyStream(this.binaryReader.BaseStream, tempCab, (int)uxContainerSlot.Size); |
98 | } | 98 | } |
@@ -100,7 +100,7 @@ namespace WixToolset.Core.Burn.Bundles | |||
100 | var cabinet = new Cabinet(tempCabPath); | 100 | var cabinet = new Cabinet(tempCabPath); |
101 | cabinet.Extract(outputDirectory); | 101 | cabinet.Extract(outputDirectory); |
102 | 102 | ||
103 | this.fileSystem.MoveFile(manifestOriginalPath, manifestPath); | 103 | this.fileSystem.MoveFile(null, manifestOriginalPath, manifestPath); |
104 | 104 | ||
105 | var document = new XmlDocument(); | 105 | var document = new XmlDocument(); |
106 | document.Load(manifestPath); | 106 | document.Load(manifestPath); |
@@ -117,7 +117,7 @@ namespace WixToolset.Core.Burn.Bundles | |||
117 | var sourcePath = Path.Combine(outputDirectory, sourcePathNode.Value); | 117 | var sourcePath = Path.Combine(outputDirectory, sourcePathNode.Value); |
118 | var destinationPath = Path.Combine(outputDirectory, filePathNode.Value); | 118 | var destinationPath = Path.Combine(outputDirectory, filePathNode.Value); |
119 | 119 | ||
120 | this.fileSystem.MoveFile(sourcePath, destinationPath); | 120 | this.fileSystem.MoveFile(null, sourcePath, destinationPath); |
121 | } | 121 | } |
122 | 122 | ||
123 | foreach (XmlNode payload in payloads) | 123 | foreach (XmlNode payload in payloads) |
@@ -169,7 +169,7 @@ namespace WixToolset.Core.Burn.Bundles | |||
169 | var tempCabPath = Path.Combine(tempDirectory, $"a{i}.cab"); | 169 | var tempCabPath = Path.Combine(tempDirectory, $"a{i}.cab"); |
170 | 170 | ||
171 | this.binaryReader.BaseStream.Seek(nextAddress, SeekOrigin.Begin); | 171 | this.binaryReader.BaseStream.Seek(nextAddress, SeekOrigin.Begin); |
172 | using (Stream tempCab = this.fileSystem.OpenFile(tempCabPath, FileMode.Create, FileAccess.Write, FileShare.Read)) | 172 | using (Stream tempCab = this.fileSystem.OpenFile(null, tempCabPath, FileMode.Create, FileAccess.Write, FileShare.Read)) |
173 | { | 173 | { |
174 | BurnCommon.CopyStream(this.binaryReader.BaseStream, tempCab, (int)cntnr.Size); | 174 | BurnCommon.CopyStream(this.binaryReader.BaseStream, tempCab, (int)cntnr.Size); |
175 | } | 175 | } |
@@ -185,7 +185,7 @@ namespace WixToolset.Core.Burn.Bundles | |||
185 | var sourcePath = Path.Combine(outputDirectory, (string)entry.Key); | 185 | var sourcePath = Path.Combine(outputDirectory, (string)entry.Key); |
186 | var destinationPath = Path.Combine(outputDirectory, (string)entry.Value); | 186 | var destinationPath = Path.Combine(outputDirectory, (string)entry.Value); |
187 | 187 | ||
188 | this.fileSystem.MoveFile(sourcePath, destinationPath); | 188 | this.fileSystem.MoveFile(null, sourcePath, destinationPath); |
189 | } | 189 | } |
190 | 190 | ||
191 | return true; | 191 | return true; |
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/BurnWriter.cs b/src/wix/WixToolset.Core.Burn/Bundles/BurnWriter.cs index f6282443..a61713f1 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/BurnWriter.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/BurnWriter.cs | |||
@@ -43,14 +43,14 @@ namespace WixToolset.Core.Burn.Bundles | |||
43 | { | 43 | { |
44 | var writer = new BurnWriter(messaging, fileSystem, fileExe); | 44 | var writer = new BurnWriter(messaging, fileSystem, fileExe); |
45 | 45 | ||
46 | using (var binaryReader = new BinaryReader(fileSystem.OpenFile(fileExe, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete))) | 46 | using (var binaryReader = new BinaryReader(fileSystem.OpenFile(null, fileExe, FileMode.Open, FileAccess.Read, FileShare.Read | FileShare.Delete))) |
47 | { | 47 | { |
48 | writer.Initialize(binaryReader); | 48 | writer.Initialize(binaryReader); |
49 | } | 49 | } |
50 | 50 | ||
51 | if (!writer.Invalid) | 51 | if (!writer.Invalid) |
52 | { | 52 | { |
53 | writer.binaryWriter = new BinaryWriter(fileSystem.OpenFile(fileExe, FileMode.Open, FileAccess.ReadWrite, FileShare.Read | FileShare.Delete)); | 53 | writer.binaryWriter = new BinaryWriter(fileSystem.OpenFile(null, fileExe, FileMode.Open, FileAccess.ReadWrite, FileShare.Read | FileShare.Delete)); |
54 | } | 54 | } |
55 | 55 | ||
56 | return writer; | 56 | return writer; |
@@ -102,12 +102,13 @@ namespace WixToolset.Core.Burn.Bundles | |||
102 | /// <summary> | 102 | /// <summary> |
103 | /// Appends a UX or Attached container to the exe and updates the ".wixburn" section data to point to it. | 103 | /// Appends a UX or Attached container to the exe and updates the ".wixburn" section data to point to it. |
104 | /// </summary> | 104 | /// </summary> |
105 | /// <param name="sourceLineNumbers">Source line numbers for the container.</param> | ||
105 | /// <param name="fileContainer">File path to append to the current exe.</param> | 106 | /// <param name="fileContainer">File path to append to the current exe.</param> |
106 | /// <param name="container">Container section represented by the fileContainer.</param> | 107 | /// <param name="container">Container section represented by the fileContainer.</param> |
107 | /// <returns>true if the container data is successfully appended; false otherwise</returns> | 108 | /// <returns>true if the container data is successfully appended; false otherwise</returns> |
108 | public bool AppendContainer(string fileContainer, BurnCommon.Container container) | 109 | public bool AppendContainer(SourceLineNumber sourceLineNumbers, string fileContainer, BurnCommon.Container container) |
109 | { | 110 | { |
110 | using (var reader = this.fileSystem.OpenFile(fileContainer, FileMode.Open, FileAccess.Read, FileShare.Read)) | 111 | using (var reader = this.fileSystem.OpenFile(sourceLineNumbers, fileContainer, FileMode.Open, FileAccess.Read, FileShare.Read)) |
111 | { | 112 | { |
112 | return this.AppendContainer(reader, reader.Length, container); | 113 | return this.AppendContainer(reader, reader.Length, container); |
113 | } | 114 | } |
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs index 64e74bbe..f4b36ac2 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/CreateBundleExeCommand.cs | |||
@@ -71,7 +71,7 @@ namespace WixToolset.Core.Burn.Bundles | |||
71 | 71 | ||
72 | this.Transfer = this.BackendHelper.CreateFileTransfer(bundleTempPath, this.OutputPath, true, this.BundleSymbol.SourceLineNumbers); | 72 | this.Transfer = this.BackendHelper.CreateFileTransfer(bundleTempPath, this.OutputPath, true, this.BundleSymbol.SourceLineNumbers); |
73 | 73 | ||
74 | this.FileSystem.CopyFile(stubFile, bundleTempPath, allowHardlink: false); | 74 | this.FileSystem.CopyFile(this.BundleSymbol.SourceLineNumbers, stubFile, bundleTempPath, allowHardlink: false); |
75 | File.SetAttributes(bundleTempPath, FileAttributes.Normal); | 75 | File.SetAttributes(bundleTempPath, FileAttributes.Normal); |
76 | 76 | ||
77 | var fourPartVersion = this.GetFourPartVersion(this.BundleSymbol); | 77 | var fourPartVersion = this.GetFourPartVersion(this.BundleSymbol); |
@@ -88,7 +88,7 @@ namespace WixToolset.Core.Burn.Bundles | |||
88 | writer.InitializeBundleSectionData(burnStubFile.Length, this.BundleSymbol.BundleId); | 88 | writer.InitializeBundleSectionData(burnStubFile.Length, this.BundleSymbol.BundleId); |
89 | 89 | ||
90 | // Always attach the UX container first | 90 | // Always attach the UX container first |
91 | writer.AppendContainer(this.UXContainer.WorkingPath, BurnWriter.Container.UX); | 91 | writer.AppendContainer(this.UXContainer.SourceLineNumbers, this.UXContainer.WorkingPath, BurnWriter.Container.UX); |
92 | 92 | ||
93 | // Now append all other attached containers | 93 | // Now append all other attached containers |
94 | foreach (var container in this.Containers) | 94 | foreach (var container in this.Containers) |
@@ -98,7 +98,7 @@ namespace WixToolset.Core.Burn.Bundles | |||
98 | // The container was only created if it had payloads. | 98 | // The container was only created if it had payloads. |
99 | if (!String.IsNullOrEmpty(container.WorkingPath) && BurnConstants.BurnUXContainerName != container.Id.Id) | 99 | if (!String.IsNullOrEmpty(container.WorkingPath) && BurnConstants.BurnUXContainerName != container.Id.Id) |
100 | { | 100 | { |
101 | writer.AppendContainer(container.WorkingPath, BurnWriter.Container.Attached); | 101 | writer.AppendContainer(container.SourceLineNumbers, container.WorkingPath, BurnWriter.Container.Attached); |
102 | } | 102 | } |
103 | } | 103 | } |
104 | } | 104 | } |
diff --git a/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleCommand.cs b/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleCommand.cs index 422ad329..2ebc9c47 100644 --- a/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleCommand.cs | |||
@@ -38,7 +38,7 @@ namespace WixToolset.Core.Burn.Inscribe | |||
38 | 38 | ||
39 | using (var reader = BurnReader.Open(this.Messaging, this.FileSystem, this.InputFilePath)) | 39 | using (var reader = BurnReader.Open(this.Messaging, this.FileSystem, this.InputFilePath)) |
40 | { | 40 | { |
41 | this.FileSystem.CopyFile(this.SignedEngineFile, tempFile, allowHardlink: false); | 41 | this.FileSystem.CopyFile(null, this.SignedEngineFile, tempFile, allowHardlink: false); |
42 | 42 | ||
43 | using (var writer = BurnWriter.Open(this.Messaging, this.FileSystem, tempFile)) | 43 | using (var writer = BurnWriter.Open(this.Messaging, this.FileSystem, tempFile)) |
44 | { | 44 | { |
@@ -46,7 +46,7 @@ namespace WixToolset.Core.Burn.Inscribe | |||
46 | } | 46 | } |
47 | } | 47 | } |
48 | 48 | ||
49 | this.FileSystem.MoveFile(tempFile, this.OutputFile); | 49 | this.FileSystem.MoveFile(null, 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 3fde859a..5eeb7061 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 | |||
33 | var tempFile = Path.Combine(this.IntermediateFolder, "bundle_engine_unsigned.exe"); | 33 | var tempFile = Path.Combine(this.IntermediateFolder, "bundle_engine_unsigned.exe"); |
34 | 34 | ||
35 | using (var reader = BurnReader.Open(this.Messaging, this.FileSystem, this.InputFilePath)) | 35 | using (var reader = BurnReader.Open(this.Messaging, this.FileSystem, this.InputFilePath)) |
36 | using (var writer = this.FileSystem.OpenFile(tempFile, FileMode.Create, FileAccess.Write, FileShare.Read | FileShare.Delete)) | 36 | using (var writer = this.FileSystem.OpenFile(null, tempFile, FileMode.Create, FileAccess.Write, FileShare.Read | FileShare.Delete)) |
37 | { | 37 | { |
38 | reader.Stream.Seek(0, SeekOrigin.Begin); | 38 | reader.Stream.Seek(0, SeekOrigin.Begin); |
39 | 39 | ||
@@ -58,7 +58,7 @@ namespace WixToolset.Core.Burn.Inscribe | |||
58 | // TODO: update writer with detached container signatures. | 58 | // TODO: update writer with detached container signatures. |
59 | } | 59 | } |
60 | 60 | ||
61 | this.FileSystem.MoveFile(tempFile, this.OutputFile); | 61 | this.FileSystem.MoveFile(null, tempFile, this.OutputFile); |
62 | } | 62 | } |
63 | } | 63 | } |
64 | } | 64 | } |
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/AssemblyNameReader.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/AssemblyNameReader.cs index 0bb9c389..838a6fe1 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/AssemblyNameReader.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/AssemblyNameReader.cs | |||
@@ -19,7 +19,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
19 | { | 19 | { |
20 | try | 20 | try |
21 | { | 21 | { |
22 | using (var stream = fileSystem.OpenFile(assemblyPath, FileMode.Open, FileAccess.Read, FileShare.Read)) | 22 | using (var stream = fileSystem.OpenFile(sourceLineNumbers, assemblyPath, FileMode.Open, FileAccess.Read, FileShare.Read)) |
23 | using (var peReader = new PEReader(stream)) | 23 | using (var peReader = new PEReader(stream)) |
24 | { | 24 | { |
25 | var reader = peReader.GetMetadataReader(); | 25 | 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 e3d70b70..b3008d6e 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs | |||
@@ -212,7 +212,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
212 | 212 | ||
213 | if (softwareTags.Any()) | 213 | if (softwareTags.Any()) |
214 | { | 214 | { |
215 | var command = new ProcessPackageSoftwareTagsCommand(section, this.WindowsInstallerBackendHelper, softwareTags, this.IntermediateFolder); | 215 | var command = new ProcessPackageSoftwareTagsCommand(section, this.WindowsInstallerBackendHelper, this.FileSystem, softwareTags, this.IntermediateFolder); |
216 | command.Execute(); | 216 | command.Execute(); |
217 | 217 | ||
218 | trackedFiles.AddRange(command.TrackedFiles); | 218 | trackedFiles.AddRange(command.TrackedFiles); |
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindTransformCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindTransformCommand.cs index e6ab3a28..b61247a5 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindTransformCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/BindTransformCommand.cs | |||
@@ -401,7 +401,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
401 | { | 401 | { |
402 | if (!String.IsNullOrEmpty(emptyFile)) | 402 | if (!String.IsNullOrEmpty(emptyFile)) |
403 | { | 403 | { |
404 | using (var fileStream = this.FileSystem.OpenFile(emptyFile, FileMode.Create, FileAccess.Write, FileShare.None)) | 404 | using (var fileStream = this.FileSystem.OpenFile(null, emptyFile, FileMode.Create, FileAccess.Write, FileShare.None)) |
405 | { | 405 | { |
406 | } | 406 | } |
407 | } | 407 | } |
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/FileSystemManager.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/FileSystemManager.cs index 8707d5f1..e4fa279c 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/FileSystemManager.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/FileSystemManager.cs | |||
@@ -5,7 +5,6 @@ namespace WixToolset.Core.WindowsInstaller.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 System.Runtime.CompilerServices; | ||
9 | using WixToolset.Extensibility; | 8 | using WixToolset.Extensibility; |
10 | using WixToolset.Extensibility.Services; | 9 | using WixToolset.Extensibility.Services; |
11 | 10 | ||
@@ -42,8 +41,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
42 | return true; | 41 | return true; |
43 | } | 42 | } |
44 | 43 | ||
45 | using (var firstStream = this.FileSystem.OpenFile(firstPath, FileMode.Open, FileAccess.Read, FileShare.Read)) | 44 | using (var firstStream = this.FileSystem.OpenFile(null, firstPath, FileMode.Open, FileAccess.Read, FileShare.Read)) |
46 | using (var secondStream = this.FileSystem.OpenFile(secondPath, FileMode.Open, FileAccess.Read, FileShare.Read)) | 45 | using (var secondStream = this.FileSystem.OpenFile(null, secondPath, FileMode.Open, FileAccess.Read, FileShare.Read)) |
47 | { | 46 | { |
48 | if (firstStream.Length != secondStream.Length) | 47 | if (firstStream.Length != secondStream.Length) |
49 | { | 48 | { |
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/ProcessPackageSoftwareTagsCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/ProcessPackageSoftwareTagsCommand.cs index 1348f163..9fb42fbc 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/ProcessPackageSoftwareTagsCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/ProcessPackageSoftwareTagsCommand.cs | |||
@@ -15,10 +15,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
15 | 15 | ||
16 | internal class ProcessPackageSoftwareTagsCommand | 16 | internal class ProcessPackageSoftwareTagsCommand |
17 | { | 17 | { |
18 | public ProcessPackageSoftwareTagsCommand(IntermediateSection section, IBackendHelper backendHelper, IEnumerable<WixPackageTagSymbol> softwareTags, string intermediateFolder) | 18 | public ProcessPackageSoftwareTagsCommand(IntermediateSection section, IBackendHelper backendHelper, IFileSystem fileSystem, IEnumerable<WixPackageTagSymbol> softwareTags, string intermediateFolder) |
19 | { | 19 | { |
20 | this.Section = section; | 20 | this.Section = section; |
21 | this.BackendHelper = backendHelper; | 21 | this.BackendHelper = backendHelper; |
22 | this.FileSystem = fileSystem; | ||
22 | this.SoftwareTags = softwareTags; | 23 | this.SoftwareTags = softwareTags; |
23 | this.IntermediateFolder = intermediateFolder; | 24 | this.IntermediateFolder = intermediateFolder; |
24 | } | 25 | } |
@@ -29,6 +30,8 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
29 | 30 | ||
30 | private IBackendHelper BackendHelper { get; } | 31 | private IBackendHelper BackendHelper { get; } |
31 | 32 | ||
33 | private IFileSystem FileSystem { get; } | ||
34 | |||
32 | private IEnumerable<WixPackageTagSymbol> SoftwareTags { get; } | 35 | private IEnumerable<WixPackageTagSymbol> SoftwareTags { get; } |
33 | 36 | ||
34 | public IReadOnlyCollection<ITrackedFile> TrackedFiles { get; private set; } | 37 | public IReadOnlyCollection<ITrackedFile> TrackedFiles { get; private set; } |
@@ -61,7 +64,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
61 | 64 | ||
62 | trackedFiles.Add(this.BackendHelper.TrackFile(fileSymbol.Source.Path, TrackedFileType.Intermediate, tagRow.SourceLineNumbers)); | 65 | trackedFiles.Add(this.BackendHelper.TrackFile(fileSymbol.Source.Path, TrackedFileType.Intermediate, tagRow.SourceLineNumbers)); |
63 | 66 | ||
64 | using (var fs = new FileStream(fileSymbol.Source.Path, FileMode.Create)) | 67 | using (var fs = this.FileSystem.OpenFile(fileSymbol.SourceLineNumbers, fileSymbol.Source.Path, FileMode.Create, FileAccess.ReadWrite, FileShare.Read)) |
65 | { | 68 | { |
66 | CreateTagFile(fs, uniqueId, packageSymbol.Name, packageSymbol.Version, tagRow.Regid, packageSymbol.Manufacturer, persistentId); | 69 | CreateTagFile(fs, uniqueId, packageSymbol.Name, packageSymbol.Version, tagRow.Regid, packageSymbol.Manufacturer, persistentId); |
67 | } | 70 | } |
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs index 7f764f49..b51e3a0f 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Bind/UpdateFileFacadesCommand.cs | |||
@@ -84,7 +84,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind | |||
84 | return; | 84 | return; |
85 | } | 85 | } |
86 | 86 | ||
87 | using (var fileStream = new FileStream(fileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)) | 87 | using (var fileStream = this.FileSystem.OpenFile(facade.SourceLineNumber, fileInfo.FullName, FileMode.Open, FileAccess.Read, FileShare.Read)) |
88 | { | 88 | { |
89 | if (Int32.MaxValue < fileStream.Length) | 89 | if (Int32.MaxValue < fileStream.Length) |
90 | { | 90 | { |
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs index 3f0d0c51..455057f6 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Inscribe/InscribeMsiPackageCommand.cs | |||
@@ -51,7 +51,7 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe | |||
51 | 51 | ||
52 | if (!String.Equals(this.InputPath, this.OutputPath, StringComparison.OrdinalIgnoreCase)) | 52 | if (!String.Equals(this.InputPath, this.OutputPath, StringComparison.OrdinalIgnoreCase)) |
53 | { | 53 | { |
54 | this.FileSystem.CopyFile(this.InputPath, this.OutputPath, allowHardlink: false); | 54 | this.FileSystem.CopyFile(null, this.InputPath, this.OutputPath, allowHardlink: false); |
55 | } | 55 | } |
56 | 56 | ||
57 | var attributes = File.GetAttributes(databasePath); | 57 | var attributes = File.GetAttributes(databasePath); |
@@ -98,7 +98,7 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe | |||
98 | Directory.CreateDirectory(hashPath); | 98 | Directory.CreateDirectory(hashPath); |
99 | hashPath = Path.Combine(hashPath, hashFileName); | 99 | hashPath = Path.Combine(hashPath, hashFileName); |
100 | 100 | ||
101 | using (var fs = this.FileSystem.OpenFile(hashPath, FileMode.Create, FileAccess.Write, FileShare.None)) | 101 | using (var fs = this.FileSystem.OpenFile(null, hashPath, FileMode.Create, FileAccess.Write, FileShare.None)) |
102 | { | 102 | { |
103 | int bytesRead; | 103 | int bytesRead; |
104 | var buffer = new byte[1024 * 4]; | 104 | var buffer = new byte[1024 * 4]; |
@@ -129,7 +129,7 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe | |||
129 | Directory.CreateDirectory(certPath); | 129 | Directory.CreateDirectory(certPath); |
130 | certPath = Path.Combine(certPath, String.Concat(certificateId, ".cer")); | 130 | certPath = Path.Combine(certPath, String.Concat(certificateId, ".cer")); |
131 | 131 | ||
132 | using (var fs = this.FileSystem.OpenFile(certPath, FileMode.Create, FileAccess.Write, FileShare.None)) | 132 | using (var fs = this.FileSystem.OpenFile(null, certPath, FileMode.Create, FileAccess.Write, FileShare.None)) |
133 | { | 133 | { |
134 | int bytesRead; | 134 | int bytesRead; |
135 | var buffer = new byte[1024 * 4]; | 135 | var buffer = new byte[1024 * 4]; |
@@ -223,9 +223,9 @@ namespace WixToolset.Core.WindowsInstaller.Inscribe | |||
223 | var certPath = Path.Combine(this.IntermediateFolder, "MsiDigitalCertificate"); | 223 | var certPath = Path.Combine(this.IntermediateFolder, "MsiDigitalCertificate"); |
224 | Directory.CreateDirectory(certPath); | 224 | Directory.CreateDirectory(certPath); |
225 | certPath = Path.Combine(certPath, String.Concat(cert2.Thumbprint, ".cer")); | 225 | certPath = Path.Combine(certPath, String.Concat(cert2.Thumbprint, ".cer")); |
226 | this.FileSystem.DeleteFile(certPath, true); | 226 | this.FileSystem.DeleteFile(null, certPath, true); |
227 | 227 | ||
228 | using (var writer = new BinaryWriter(this.FileSystem.OpenFile(certPath, FileMode.Create, FileAccess.Write, FileShare.Read))) | 228 | using (var writer = new BinaryWriter(this.FileSystem.OpenFile(null, certPath, FileMode.Create, FileAccess.Write, FileShare.Read))) |
229 | { | 229 | { |
230 | writer.Write(cert2.RawData); | 230 | writer.Write(cert2.RawData); |
231 | writer.Close(); | 231 | writer.Close(); |
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Unbind/ExtractCabinetsCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Unbind/ExtractCabinetsCommand.cs index c2981b08..bfbe0339 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Unbind/ExtractCabinetsCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Unbind/ExtractCabinetsCommand.cs | |||
@@ -97,6 +97,8 @@ namespace WixToolset.Core.WindowsInstaller.Unbind | |||
97 | { | 97 | { |
98 | if (null != record) | 98 | if (null != record) |
99 | { | 99 | { |
100 | embeddedCabinetRowsByDiskId.TryGetValue(diskId, out var cabinetMediaRow); | ||
101 | |||
100 | // since the cabinets are stored in case-sensitive streams inside the msi, but the file system is not (typically) case-sensitive, | 102 | // since the cabinets are stored in case-sensitive streams inside the msi, but the file system is not (typically) case-sensitive, |
101 | // embedded cabinets must be extracted to a canonical file name (like their diskid) to ensure extraction will always work | 103 | // embedded cabinets must be extracted to a canonical file name (like their diskid) to ensure extraction will always work |
102 | var cabinetPath = Path.Combine(this.IntermediateFolder, "Media", diskId.ToString(CultureInfo.InvariantCulture), ".cab"); | 104 | var cabinetPath = Path.Combine(this.IntermediateFolder, "Media", diskId.ToString(CultureInfo.InvariantCulture), ".cab"); |
@@ -104,7 +106,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind | |||
104 | // ensure the parent directory exists | 106 | // ensure the parent directory exists |
105 | Directory.CreateDirectory(Path.GetDirectoryName(cabinetPath)); | 107 | Directory.CreateDirectory(Path.GetDirectoryName(cabinetPath)); |
106 | 108 | ||
107 | using (var fs = this.FileSystem.OpenFile(cabinetPath, FileMode.Create, FileAccess.Write, FileShare.None)) | 109 | using (var fs = this.FileSystem.OpenFile(cabinetMediaRow.SourceLineNumbers, cabinetPath, FileMode.Create, FileAccess.Write, FileShare.None)) |
108 | { | 110 | { |
109 | int bytesRead; | 111 | int bytesRead; |
110 | var buffer = new byte[4096]; | 112 | var buffer = new byte[4096]; |
@@ -115,7 +117,6 @@ namespace WixToolset.Core.WindowsInstaller.Unbind | |||
115 | } | 117 | } |
116 | } | 118 | } |
117 | 119 | ||
118 | embeddedCabinetRowsByDiskId.TryGetValue(diskId, out var cabinetMediaRow); | ||
119 | cabinetPathsWithMediaRow.Add(cabinetPath, cabinetMediaRow); | 120 | cabinetPathsWithMediaRow.Add(cabinetPath, cabinetMediaRow); |
120 | } | 121 | } |
121 | else | 122 | else |
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs index 54534e50..9ad936e4 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Unbind/UnbindDatabaseCommand.cs | |||
@@ -206,7 +206,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind | |||
206 | 206 | ||
207 | Directory.CreateDirectory(Path.Combine(this.ExportBasePath, tableName)); | 207 | Directory.CreateDirectory(Path.Combine(this.ExportBasePath, tableName)); |
208 | 208 | ||
209 | using (var fs = this.FileSystem.OpenFile(source, FileMode.Create, FileAccess.Write, FileShare.None)) | 209 | using (var fs = this.FileSystem.OpenFile(null, source, FileMode.Create, FileAccess.Write, FileShare.None)) |
210 | { | 210 | { |
211 | int bytesRead; | 211 | int bytesRead; |
212 | var buffer = new byte[4096]; | 212 | var buffer = new byte[4096]; |
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Unbind/UnbindTransformCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Unbind/UnbindTransformCommand.cs index bb4da1ed..49759d2c 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Unbind/UnbindTransformCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Unbind/UnbindTransformCommand.cs | |||
@@ -327,7 +327,7 @@ namespace WixToolset.Core.WindowsInstaller.Unbind | |||
327 | if (null == this.EmptyFile) | 327 | if (null == this.EmptyFile) |
328 | { | 328 | { |
329 | this.EmptyFile = Path.Combine(this.IntermediateFolder, ".empty"); | 329 | this.EmptyFile = Path.Combine(this.IntermediateFolder, ".empty"); |
330 | using (var fileStream = this.FileSystem.OpenFile(this.EmptyFile, FileMode.Create, FileAccess.Write, FileShare.None)) | 330 | using (var fileStream = this.FileSystem.OpenFile(null, this.EmptyFile, FileMode.Create, FileAccess.Write, FileShare.None)) |
331 | { | 331 | { |
332 | } | 332 | } |
333 | } | 333 | } |
diff --git a/src/wix/WixToolset.Core.WindowsInstaller/Validate/ValidateDatabaseCommand.cs b/src/wix/WixToolset.Core.WindowsInstaller/Validate/ValidateDatabaseCommand.cs index 24dd9927..6996dc44 100644 --- a/src/wix/WixToolset.Core.WindowsInstaller/Validate/ValidateDatabaseCommand.cs +++ b/src/wix/WixToolset.Core.WindowsInstaller/Validate/ValidateDatabaseCommand.cs | |||
@@ -71,7 +71,7 @@ namespace WixToolset.Core.WindowsInstaller.Validate | |||
71 | var workingDatabasePath = Path.Combine(this.IntermediateFolder, workingDatabaseFilename); | 71 | var workingDatabasePath = Path.Combine(this.IntermediateFolder, workingDatabaseFilename); |
72 | try | 72 | try |
73 | { | 73 | { |
74 | this.FileSystem.CopyFile(this.DatabasePath, workingDatabasePath, allowHardlink: false); | 74 | this.FileSystem.CopyFile(null, this.DatabasePath, workingDatabasePath, allowHardlink: false); |
75 | 75 | ||
76 | var attributes = File.GetAttributes(workingDatabasePath); | 76 | var attributes = File.GetAttributes(workingDatabasePath); |
77 | File.SetAttributes(workingDatabasePath, attributes & ~FileAttributes.ReadOnly); | 77 | File.SetAttributes(workingDatabasePath, attributes & ~FileAttributes.ReadOnly); |
@@ -81,7 +81,7 @@ namespace WixToolset.Core.WindowsInstaller.Validate | |||
81 | } | 81 | } |
82 | finally | 82 | finally |
83 | { | 83 | { |
84 | this.FileSystem.DeleteFile(workingDatabasePath); | 84 | this.FileSystem.DeleteFile(null, workingDatabasePath); |
85 | } | 85 | } |
86 | 86 | ||
87 | stopwatch.Stop(); | 87 | stopwatch.Stop(); |
diff --git a/src/wix/WixToolset.Core/Bind/TransferFilesCommand.cs b/src/wix/WixToolset.Core/Bind/TransferFilesCommand.cs index 4a0329bc..28ca6b49 100644 --- a/src/wix/WixToolset.Core/Bind/TransferFilesCommand.cs +++ b/src/wix/WixToolset.Core/Bind/TransferFilesCommand.cs | |||
@@ -53,12 +53,12 @@ namespace WixToolset.Core.Bind | |||
53 | if (fileTransfer.Move) | 53 | if (fileTransfer.Move) |
54 | { | 54 | { |
55 | this.Messaging.Write(VerboseMessages.MoveFile(fileTransfer.Source, fileTransfer.Destination)); | 55 | this.Messaging.Write(VerboseMessages.MoveFile(fileTransfer.Source, fileTransfer.Destination)); |
56 | this.MoveFile(fileTransfer.Source, fileTransfer.Destination); | 56 | this.MoveFile(fileTransfer.SourceLineNumbers, fileTransfer.Source, fileTransfer.Destination); |
57 | } | 57 | } |
58 | else | 58 | else |
59 | { | 59 | { |
60 | this.Messaging.Write(VerboseMessages.CopyFile(fileTransfer.Source, fileTransfer.Destination)); | 60 | this.Messaging.Write(VerboseMessages.CopyFile(fileTransfer.Source, fileTransfer.Destination)); |
61 | this.CopyFile(fileTransfer.Source, fileTransfer.Destination); | 61 | this.CopyFile(fileTransfer.SourceLineNumbers, fileTransfer.Source, fileTransfer.Destination); |
62 | } | 62 | } |
63 | 63 | ||
64 | retry = false; | 64 | retry = false; |
@@ -170,7 +170,7 @@ namespace WixToolset.Core.Bind | |||
170 | } | 170 | } |
171 | } | 171 | } |
172 | 172 | ||
173 | private void CopyFile(string source, string destination) | 173 | private void CopyFile(SourceLineNumber sourceLineNumbers, string source, string destination) |
174 | { | 174 | { |
175 | foreach (var extension in this.Extensions) | 175 | foreach (var extension in this.Extensions) |
176 | { | 176 | { |
@@ -180,10 +180,10 @@ namespace WixToolset.Core.Bind | |||
180 | } | 180 | } |
181 | } | 181 | } |
182 | 182 | ||
183 | this.FileSystem.CopyFile(source, destination, allowHardlink: true); | 183 | this.FileSystem.CopyFile(sourceLineNumbers, source, destination, allowHardlink: true); |
184 | } | 184 | } |
185 | 185 | ||
186 | private void MoveFile(string source, string destination) | 186 | private void MoveFile(SourceLineNumber sourceLineNumbers, string source, string destination) |
187 | { | 187 | { |
188 | foreach (var extension in this.Extensions) | 188 | foreach (var extension in this.Extensions) |
189 | { | 189 | { |
@@ -193,7 +193,7 @@ namespace WixToolset.Core.Bind | |||
193 | } | 193 | } |
194 | } | 194 | } |
195 | 195 | ||
196 | this.FileSystem.MoveFile(source, destination); | 196 | this.FileSystem.MoveFile(sourceLineNumbers, source, destination); |
197 | } | 197 | } |
198 | 198 | ||
199 | private void AclReset(IEnumerable<string> files) | 199 | private void AclReset(IEnumerable<string> files) |
diff --git a/src/wix/WixToolset.Core/CoreErrors.cs b/src/wix/WixToolset.Core/CoreErrors.cs new file mode 100644 index 00000000..6dbd6c88 --- /dev/null +++ b/src/wix/WixToolset.Core/CoreErrors.cs | |||
@@ -0,0 +1,42 @@ | |||
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 | ||
4 | { | ||
5 | using WixToolset.Data; | ||
6 | |||
7 | internal static class CoreErrors | ||
8 | { | ||
9 | public static Message UnableToCopyFile(SourceLineNumber sourceLineNumbers, string source, string destination, string detail) | ||
10 | { | ||
11 | return Message(sourceLineNumbers, Ids.UnableToCopyFile, "Unable to copy file from: {0}, to: {1}. Error detail: {2}", source, destination, detail); | ||
12 | } | ||
13 | |||
14 | public static Message UnableToDeleteFile(SourceLineNumber sourceLineNumbers, string path, string detail) | ||
15 | { | ||
16 | return Message(sourceLineNumbers, Ids.UnableToDeleteFile, "Unable to delete file: {0}. Error detail: {1}", path, detail); | ||
17 | } | ||
18 | |||
19 | public static Message UnableToMoveFile(SourceLineNumber sourceLineNumbers, string source, string destination, string detail) | ||
20 | { | ||
21 | return Message(sourceLineNumbers, Ids.UnableToMoveFile, "Unable to move file from: {0}, to: {1}. Error detail: {2}", source, destination, detail); | ||
22 | } | ||
23 | |||
24 | public static Message UnableToOpenFile(SourceLineNumber sourceLineNumbers, string path, string detail) | ||
25 | { | ||
26 | return Message(sourceLineNumbers, Ids.UnableToOpenFile, "Unable to open file: {0}. Error detail: {1}", path, detail); | ||
27 | } | ||
28 | |||
29 | private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args) | ||
30 | { | ||
31 | return new Message(sourceLineNumber, MessageLevel.Error, (int)id, format, args); | ||
32 | } | ||
33 | |||
34 | public enum Ids | ||
35 | { | ||
36 | UnableToCopyFile = 7010, | ||
37 | UnableToDeleteFile = 7011, | ||
38 | UnableToMoveFile = 7012, | ||
39 | UnableToOpenFile = 7013, | ||
40 | } // last available is 7099. 7100 is WindowsInstallerBackendWarnings. | ||
41 | } | ||
42 | } | ||
diff --git a/src/wix/WixToolset.Core/ExtensibilityServices/FileSystem.cs b/src/wix/WixToolset.Core/ExtensibilityServices/FileSystem.cs index 8cf7a872..8baee3d8 100644 --- a/src/wix/WixToolset.Core/ExtensibilityServices/FileSystem.cs +++ b/src/wix/WixToolset.Core/ExtensibilityServices/FileSystem.cs | |||
@@ -7,19 +7,34 @@ namespace WixToolset.Core.ExtensibilityServices | |||
7 | using System.IO; | 7 | using System.IO; |
8 | using System.Runtime.InteropServices; | 8 | using System.Runtime.InteropServices; |
9 | using System.Threading; | 9 | using System.Threading; |
10 | using WixToolset.Data; | ||
10 | using WixToolset.Extensibility.Services; | 11 | using WixToolset.Extensibility.Services; |
11 | 12 | ||
12 | internal class FileSystem : IFileSystem | 13 | internal class FileSystem : IFileSystem |
13 | { | 14 | { |
14 | public void CopyFile(string source, string destination, bool allowHardlink) | 15 | public void CopyFile(SourceLineNumber sourceLineNumbers, string source, string destination, bool allowHardlink) |
15 | { | 16 | { |
16 | this.EnsureDirectoryWithoutFile(destination); | 17 | try |
18 | { | ||
19 | this.EnsureDirectoryWithoutFile(destination); | ||
20 | } | ||
21 | catch (Exception e) | ||
22 | { | ||
23 | throw new WixException(CoreErrors.UnableToCopyFile(sourceLineNumbers, source, destination, e.Message), e); | ||
24 | } | ||
17 | 25 | ||
18 | var hardlinked = false; | 26 | var hardlinked = false; |
19 | 27 | ||
20 | if (allowHardlink) | 28 | if (allowHardlink) |
21 | { | 29 | { |
22 | this.ExecuteWithRetries(() => hardlinked = CreateHardLink(destination, source, IntPtr.Zero)); | 30 | try |
31 | { | ||
32 | this.ExecuteWithRetries(() => hardlinked = CreateHardLink(destination, source, IntPtr.Zero)); | ||
33 | } | ||
34 | catch | ||
35 | { | ||
36 | // Catch hard-link failures and fall back to copy file. | ||
37 | } | ||
23 | } | 38 | } |
24 | 39 | ||
25 | if (!hardlinked) | 40 | if (!hardlinked) |
@@ -28,30 +43,48 @@ namespace WixToolset.Core.ExtensibilityServices | |||
28 | var er = Marshal.GetLastWin32Error(); | 43 | var er = Marshal.GetLastWin32Error(); |
29 | #endif | 44 | #endif |
30 | 45 | ||
31 | this.ExecuteWithRetries(() => File.Copy(source, destination, overwrite: true)); | 46 | try |
47 | { | ||
48 | this.ExecuteWithRetries(() => File.Copy(source, destination, overwrite: true)); | ||
49 | } | ||
50 | catch (Exception e) | ||
51 | { | ||
52 | throw new WixException(CoreErrors.UnableToCopyFile(sourceLineNumbers, source, destination, e.Message), e); | ||
53 | } | ||
32 | } | 54 | } |
33 | } | 55 | } |
34 | 56 | ||
35 | public void DeleteFile(string source, bool throwOnError = false, int maxRetries = 4) | 57 | public void DeleteFile(SourceLineNumber sourceLineNumbers, string source, bool throwOnError = false, int maxRetries = 4) |
36 | { | 58 | { |
37 | try | 59 | try |
38 | { | 60 | { |
39 | this.ExecuteWithRetries(() => File.Delete(source), maxRetries); | 61 | this.ExecuteWithRetries(() => File.Delete(source), maxRetries); |
40 | } | 62 | } |
41 | catch when (!throwOnError) | 63 | catch (Exception e) |
42 | { | 64 | { |
43 | // Do nothing on best-effort deletes. | 65 | if (throwOnError) |
66 | { | ||
67 | throw new WixException(CoreErrors.UnableToDeleteFile(sourceLineNumbers, source, e.Message), e); | ||
68 | } | ||
69 | // else do nothing on best-effort deletes. | ||
44 | } | 70 | } |
45 | } | 71 | } |
46 | 72 | ||
47 | public void MoveFile(string source, string destination) | 73 | public void MoveFile(SourceLineNumber sourceLineNumbers, string source, string destination) |
48 | { | 74 | { |
49 | this.EnsureDirectoryWithoutFile(destination); | 75 | try |
76 | { | ||
77 | this.EnsureDirectoryWithoutFile(destination); | ||
50 | 78 | ||
51 | this.ExecuteWithRetries(() => File.Move(source, destination)); | 79 | this.ExecuteWithRetries(() => File.Move(source, destination)); |
80 | } | ||
81 | catch (Exception e) | ||
82 | { | ||
83 | throw new WixException(CoreErrors.UnableToMoveFile(sourceLineNumbers, source, destination, e.Message), e); | ||
84 | } | ||
52 | } | 85 | } |
53 | 86 | ||
54 | public FileStream OpenFile(string path, FileMode mode, FileAccess access, FileShare share) | 87 | public FileStream OpenFile(SourceLineNumber sourceLineNumbers, string path, FileMode mode, FileAccess access, FileShare share) |
55 | { | 88 | { |
56 | const int maxRetries = 4; | 89 | const int maxRetries = 4; |
57 | 90 | ||
@@ -61,9 +94,16 @@ namespace WixToolset.Core.ExtensibilityServices | |||
61 | { | 94 | { |
62 | return File.Open(path, mode, access, share); | 95 | return File.Open(path, mode, access, share); |
63 | } | 96 | } |
64 | catch (Exception e) when (attempt < maxRetries && (e is IOException || e is SystemException || e is Win32Exception)) | 97 | catch (Exception e) when (e is IOException || e is SystemException || e is Win32Exception) |
65 | { | 98 | { |
66 | Thread.Sleep(250); | 99 | if (attempt < maxRetries) |
100 | { | ||
101 | Thread.Sleep(250); | ||
102 | } | ||
103 | else | ||
104 | { | ||
105 | throw new WixException(CoreErrors.UnableToOpenFile(sourceLineNumbers, path, e.Message), e); | ||
106 | } | ||
67 | } | 107 | } |
68 | } | 108 | } |
69 | 109 | ||
diff --git a/src/wix/WixToolset.Core/LayoutCreator.cs b/src/wix/WixToolset.Core/LayoutCreator.cs index c361f78a..f26b1127 100644 --- a/src/wix/WixToolset.Core/LayoutCreator.cs +++ b/src/wix/WixToolset.Core/LayoutCreator.cs | |||
@@ -114,7 +114,7 @@ namespace WixToolset.Core | |||
114 | { | 114 | { |
115 | this.SplitUniqueFolders(intermediateFolder, tempPath, uniqueFolders); | 115 | this.SplitUniqueFolders(intermediateFolder, tempPath, uniqueFolders); |
116 | 116 | ||
117 | this.FileSystem.DeleteFile(tempPath); | 117 | this.FileSystem.DeleteFile(null, tempPath); |
118 | } | 118 | } |
119 | 119 | ||
120 | // Clean up empty temp folders. | 120 | // Clean up empty temp folders. |