@joebigelow / wix-1 / commits / add52542

Make BindResult disposable to manage WixOutput disposability.

Bob Arnson committed Feb 13, 2020 at 14:28 UTC add525424e44a050d3f98f64e56a85ab5d79955d
6 files changed +120 -99
src/WixToolset.Core.WindowsInstaller/Bind/BindDatabaseCommand.cs
+15 -40
@@ -17,13 +17,11 @@ namespace WixToolset.Core.WindowsInstaller.Bind
17 /// <summary>
18 /// Binds a databse.
19 /// </summary>
20 - internal class BindDatabaseCommand : IDisposable
20 + internal class BindDatabaseCommand
21 {
22 // As outlined in RFC 4122, this is our namespace for generating name-based (version 3) UUIDs.
23 internal static readonly Guid WixComponentGuidNamespace = new Guid("{3064E5C6-FB63-4FE9-AC49-E446A792EFA5}");
24
25 - private bool disposed;
26 -
25 public BindDatabaseCommand(IBindContext context, IEnumerable<IWindowsInstallerBackendBinderExtension> backendExtension, Validator validator):this(context, backendExtension, null, validator)
26 {
27 }
@@ -97,13 +95,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
95
96 private Validator Validator { get; }
97
100 - public IEnumerable<IFileTransfer> FileTransfers { get; private set; }
101 -
102 - public IEnumerable<ITrackedFile> TrackedFiles { get; private set; }
103 -
104 - public WixOutput Wixout { get; private set; }
105 -
106 - public void Execute()
98 + public IBindResult Execute()
99 {
100 var section = this.Intermediate.Sections.Single();
101
@@ -218,7 +210,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
210
211 if (this.Messaging.EncounteredError)
212 {
221 - return;
213 + return null;
214 }
215
216 // Call extension
@@ -290,7 +282,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
282 // stop processing if an error previously occurred
283 if (this.Messaging.EncounteredError)
284 {
293 - return;
285 + return null;
286 }
287
288 // Gather information about files that do not come from merge modules.
@@ -322,7 +314,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
314 // stop processing if an error previously occurred
315 if (this.Messaging.EncounteredError)
316 {
325 - return;
317 + return null;
318 }
319
320 // Now that the variable cache is populated, resolve any delayed fields.
@@ -347,7 +339,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
339 // stop processing if an error previously occurred
340 if (this.Messaging.EncounteredError)
341 {
350 - return;
342 + return null;
343 }
344
345 // Time to create the output object. Try to put as much above here as possible, updating the IR is better.
@@ -425,7 +417,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
417 // Stop processing if an error previously occurred.
418 if (this.Messaging.EncounteredError)
419 {
428 - return;
420 + return null;
421 }
422
423 // Ensure the intermediate folder is created since delta patches will be
@@ -479,7 +471,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
471 // stop processing if an error previously occurred
472 if (this.Messaging.EncounteredError)
473 {
482 - return;
474 + return null;
475 }
476
477 // Generate database file.
@@ -496,7 +488,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
488 // Stop processing if an error previously occurred.
489 if (this.Messaging.EncounteredError)
490 {
499 - return;
491 + return null;
492 }
493
494 // Merge modules.
@@ -533,7 +525,7 @@ namespace WixToolset.Core.WindowsInstaller.Bind
525
526 if (this.Messaging.EncounteredError)
527 {
536 - return;
528 + return null;
529 }
530
531 #if TODO_FINISH_VALIDATION
@@ -580,10 +572,12 @@ namespace WixToolset.Core.WindowsInstaller.Bind
572 trackedFiles.AddRange(fileFacades.Select(f => this.BackendHelper.TrackFile(f.SourcePath, TrackedFileType.Input, f.SourceLineNumber)));
573 }
574
583 - this.Wixout = this.CreateWixout(trackedFiles, this.Intermediate, output);
575 + var result = this.ServiceProvider.GetService<IBindResult>();
576 + result.FileTransfers = fileTransfers;
577 + result.TrackedFiles = trackedFiles;
578 + result.Wixout = this.CreateWixout(trackedFiles, this.Intermediate, output);
579
585 - this.FileTransfers = fileTransfers;
586 - this.TrackedFiles = trackedFiles;
580 + return result;
581 }
582
583 private WixOutput CreateWixout(List<ITrackedFile> trackedFiles, Intermediate intermediate, WindowsInstallerData output)
@@ -984,24 +978,5 @@ namespace WixToolset.Core.WindowsInstaller.Bind
978
979 return command.GeneratedTemporaryFiles;
980 }
987 -
988 -#region IDisposable Support
989 -
990 - public void Dispose() => this.Dispose(true);
991 -
992 - protected virtual void Dispose(bool disposing)
993 - {
994 - if (!this.disposed)
995 - {
996 - if (disposing)
997 - {
998 - this.Wixout?.Dispose();
999 - }
1000 -
1001 - this.disposed = true;
1002 - }
1003 - }
1004 -
1005 -#endregion
981 }
982 }
src/WixToolset.Core.WindowsInstaller/MsiBackend.cs
+10 -8
@@ -25,22 +25,24 @@ namespace WixToolset.Core.WindowsInstaller
25
26 var validator = Validator.CreateFromContext(context, "darice.cub");
27
28 - using (var command = new BindDatabaseCommand(context, backendExtensions, validator))
28 + IBindResult result = null;
29 + try
30 {
30 - command.Execute();
31 -
32 - var result = context.ServiceProvider.GetService<IBindResult>();
33 - result.FileTransfers = command.FileTransfers;
34 - result.TrackedFiles = command.TrackedFiles;
35 - result.Wixout = command.Wixout;
31 + var command = new BindDatabaseCommand(context, backendExtensions, validator);
32 + result = command.Execute();
33
34 foreach (var extension in backendExtensions)
35 {
39 - extension.PostBackendBind(result, command.Wixout);
36 + extension.PostBackendBind(result);
37 }
38
39 return result;
40 }
41 + catch
42 + {
43 + result?.Dispose();
44 + throw;
45 + }
46 }
47
48 public IDecompileResult Decompile(IDecompileContext context)
src/WixToolset.Core.WindowsInstaller/MsmBackend.cs
+10 -7
@@ -24,21 +24,24 @@ namespace WixToolset.Core.WindowsInstaller
24
25 var validator = Validator.CreateFromContext(context, "mergemod.cub");
26
27 - using (var command = new BindDatabaseCommand(context, backendExtensions, validator))
27 + IBindResult result = null;
28 + try
29 {
29 - command.Execute();
30 -
31 - var result = context.ServiceProvider.GetService<IBindResult>();
32 - result.FileTransfers = command.FileTransfers;
33 - result.TrackedFiles = command.TrackedFiles;
30 + var command = new BindDatabaseCommand(context, backendExtensions, validator);
31 + result = command.Execute();
32
33 foreach (var extension in backendExtensions)
34 {
37 - extension.PostBackendBind(result, command.Wixout);
35 + extension.PostBackendBind(result);
36 }
37
38 return result;
39 }
40 + catch
41 + {
42 + result?.Dispose();
43 + throw;
44 + }
45 }
46
47 public IDecompileResult Decompile(IDecompileContext context)
src/WixToolset.Core.WindowsInstaller/MspBackend.cs
+10 -7
@@ -47,21 +47,24 @@ namespace WixToolset.Core.WindowsInstaller
47
48 // Create WindowsInstallerData with patch metdata and transforms as sub-storages
49 // Create MSP from WindowsInstallerData
50 - using (var command = new BindDatabaseCommand(context, backendExtensions, subStorages, null))
50 + IBindResult result = null;
51 + try
52 {
52 - command.Execute();
53 -
54 - var result = context.ServiceProvider.GetService<IBindResult>();
55 - result.FileTransfers = command.FileTransfers;
56 - result.TrackedFiles = command.TrackedFiles;
53 + var command = new BindDatabaseCommand(context, backendExtensions, subStorages, null);
54 + result = command.Execute();
55
56 foreach (var extension in backendExtensions)
57 {
60 - extension.PostBackendBind(result, command.Wixout);
58 + extension.PostBackendBind(result);
59 }
60
61 return result;
62 }
63 + catch
64 + {
65 + result?.Dispose();
66 + throw;
67 + }
68 }
69
70 public IDecompileResult Decompile(IDecompileContext context) => throw new NotImplementedException();
src/WixToolset.Core/BindResult.cs
+31
@@ -2,16 +2,47 @@
2
3 namespace WixToolset.Core
4 {
5 + using System;
6 using System.Collections.Generic;
7 using WixToolset.Data;
8 using WixToolset.Extensibility.Data;
9
10 internal class BindResult : IBindResult
11 {
12 + private bool disposed;
13 +
14 public IEnumerable<IFileTransfer> FileTransfers { get; set; }
15
16 public IEnumerable<ITrackedFile> TrackedFiles { get; set; }
17
18 public WixOutput Wixout { get; set; }
19 +
20 + #region IDisposable Support
21 + /// <summary>
22 + /// Disposes of the internal state of the file structure.
23 + /// </summary>
24 + public void Dispose()
25 + {
26 + this.Dispose(true);
27 + GC.SuppressFinalize(this);
28 + }
29 +
30 + /// <summary>
31 + /// Disposes of the internsl state of the file structure.
32 + /// </summary>
33 + /// <param name="disposing">True if disposing.</param>
34 + protected virtual void Dispose(bool disposing)
35 + {
36 + if (!this.disposed)
37 + {
38 + if (disposing)
39 + {
40 + this.Wixout?.Dispose();
41 + }
42 + }
43 +
44 + this.disposed = true;
45 + }
46 + #endregion
47 }
48 }
src/WixToolset.Core/CommandLine/BuildCommand.cs
+44 -37
@@ -294,47 +294,54 @@ namespace WixToolset.Core.CommandLine
294 return;
295 }
296
297 - IBindResult bindResult;
297 + IBindResult bindResult = null;
298 + try
299 {
299 - var context = this.ServiceProvider.GetService<IBindContext>();
300 - //context.CabbingThreadCount = this.CabbingThreadCount;
301 - context.BurnStubPath = burnStubPath;
302 - context.CabCachePath = cabCachePath;
303 - context.Codepage = resolveResult.Codepage;
304 - //context.DefaultCompressionLevel = this.DefaultCompressionLevel;
305 - context.DelayedFields = resolveResult.DelayedFields;
306 - context.ExpectedEmbeddedFiles = resolveResult.ExpectedEmbeddedFiles;
307 - context.Extensions = this.ExtensionManager.GetServices<IBinderExtension>();
308 - context.Ices = Array.Empty<string>(); // TODO: set this correctly
309 - context.IntermediateFolder = intermediateFolder;
310 - context.IntermediateRepresentation = resolveResult.IntermediateRepresentation;
311 - context.OutputPath = this.OutputFile;
312 - context.OutputPdbPath = Path.ChangeExtension(this.OutputFile, ".wixpdb");
313 - context.SuppressIces = Array.Empty<string>(); // TODO: set this correctly
314 - context.SuppressValidation = true; // TODO: set this correctly
315 -
316 - var binder = this.ServiceProvider.GetService<IBinder>();
317 - bindResult = binder.Bind(context);
318 - }
300 + {
301 + var context = this.ServiceProvider.GetService<IBindContext>();
302 + //context.CabbingThreadCount = this.CabbingThreadCount;
303 + context.BurnStubPath = burnStubPath;
304 + context.CabCachePath = cabCachePath;
305 + context.Codepage = resolveResult.Codepage;
306 + //context.DefaultCompressionLevel = this.DefaultCompressionLevel;
307 + context.DelayedFields = resolveResult.DelayedFields;
308 + context.ExpectedEmbeddedFiles = resolveResult.ExpectedEmbeddedFiles;
309 + context.Extensions = this.ExtensionManager.GetServices<IBinderExtension>();
310 + context.Ices = Array.Empty<string>(); // TODO: set this correctly
311 + context.IntermediateFolder = intermediateFolder;
312 + context.IntermediateRepresentation = resolveResult.IntermediateRepresentation;
313 + context.OutputPath = this.OutputFile;
314 + context.OutputPdbPath = Path.ChangeExtension(this.OutputFile, ".wixpdb");
315 + context.SuppressIces = Array.Empty<string>(); // TODO: set this correctly
316 + context.SuppressValidation = true; // TODO: set this correctly
317 +
318 + var binder = this.ServiceProvider.GetService<IBinder>();
319 + bindResult = binder.Bind(context);
320 + }
321
320 - if (this.Messaging.EncounteredError)
321 - {
322 - return;
323 - }
322 + if (this.Messaging.EncounteredError)
323 + {
324 + return;
325 + }
326
327 + {
328 + var context = this.ServiceProvider.GetService<ILayoutContext>();
329 + context.Extensions = this.ExtensionManager.GetServices<ILayoutExtension>();
330 + context.TrackedFiles = bindResult.TrackedFiles;
331 + context.FileTransfers = bindResult.FileTransfers;
332 + context.IntermediateFolder = intermediateFolder;
333 + context.ContentsFile = this.ContentsFile;
334 + context.OutputsFile = this.OutputsFile;
335 + context.BuiltOutputsFile = this.BuiltOutputsFile;
336 + context.SuppressAclReset = false; // TODO: correctly set SuppressAclReset
337 +
338 + var layout = this.ServiceProvider.GetService<ILayoutCreator>();
339 + layout.Layout(context);
340 + }
341 + }
342 + finally
343 {
326 - var context = this.ServiceProvider.GetService<ILayoutContext>();
327 - context.Extensions = this.ExtensionManager.GetServices<ILayoutExtension>();
328 - context.TrackedFiles = bindResult.TrackedFiles;
329 - context.FileTransfers = bindResult.FileTransfers;
330 - context.IntermediateFolder = intermediateFolder;
331 - context.ContentsFile = this.ContentsFile;
332 - context.OutputsFile = this.OutputsFile;
333 - context.BuiltOutputsFile = this.BuiltOutputsFile;
334 - context.SuppressAclReset = false; // TODO: correctly set SuppressAclReset
335 -
336 - var layout = this.ServiceProvider.GetService<ILayoutCreator>();
337 - layout.Layout(context);
344 + bindResult?.Dispose();
345 }
346 }
347