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