diff options
author | Rob Mensching <rob@firegiant.com> | 2022-01-10 14:19:16 -0800 |
---|---|---|
committer | Rob Mensching <rob@firegiant.com> | 2022-01-10 17:08:43 -0800 |
commit | 933d4fc340f989239b77bfef4212f80d0a4a65f2 (patch) | |
tree | dd296a9c3f009558526ead34e5cabc0f4c359c86 | |
parent | ee2bb35228e8d3c12ae0e31748075777e10f9d62 (diff) | |
download | wix-933d4fc340f989239b77bfef4212f80d0a4a65f2.tar.gz wix-933d4fc340f989239b77bfef4212f80d0a4a65f2.tar.bz2 wix-933d4fc340f989239b77bfef4212f80d0a4a65f2.zip |
Support "inscribing" Burn bundles
17 files changed, 639 insertions, 54 deletions
diff --git a/src/api/wix/WixToolset.Data/WarningMessages.cs b/src/api/wix/WixToolset.Data/WarningMessages.cs index a592fe48..b749bcf4 100644 --- a/src/api/wix/WixToolset.Data/WarningMessages.cs +++ b/src/api/wix/WixToolset.Data/WarningMessages.cs | |||
@@ -279,7 +279,7 @@ namespace WixToolset.Data | |||
279 | 279 | ||
280 | public static Message ExternalCabsAreNotSigned(string databaseFile) | 280 | public static Message ExternalCabsAreNotSigned(string databaseFile) |
281 | { | 281 | { |
282 | return Message(null, Ids.ExternalCabsAreNotSigned, "The installer database '{0}' has external cabs, but at least one of them is not signed. Please ensure that all external cabs are signed, if you mean to sign them. If you don't mean to sign them, there is no need to run the insignia tool as part of your build.", databaseFile); | 282 | return Message(null, Ids.ExternalCabsAreNotSigned, "The installer database '{0}' has external cabs, but at least one of them is not signed. Please ensure that all external cabs are signed, if you mean to sign them. If you don't mean to sign them, there is no need to inscribe the MSI as part of your build.", databaseFile); |
283 | } | 283 | } |
284 | 284 | ||
285 | public static Message FailedToDeleteTempDir(string directory) | 285 | public static Message FailedToDeleteTempDir(string directory) |
diff --git a/src/wix/WixToolset.BuildTasks/DetachBundleEngineForSigning.cs b/src/wix/WixToolset.BuildTasks/DetachBundleEngineForSigning.cs new file mode 100644 index 00000000..5fcd1def --- /dev/null +++ b/src/wix/WixToolset.BuildTasks/DetachBundleEngineForSigning.cs | |||
@@ -0,0 +1,64 @@ | |||
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.BuildTasks | ||
4 | { | ||
5 | using Microsoft.Build.Framework; | ||
6 | |||
7 | /// <summary> | ||
8 | /// An MSBuild task to run WiX to detach bundle engine to be signed. | ||
9 | /// </summary> | ||
10 | public sealed partial class DetachBundleEngineForSigning : WixExeBaseTask | ||
11 | { | ||
12 | /// <summary> | ||
13 | /// The bundle from which to detach the bundle engine. | ||
14 | /// </summary> | ||
15 | [Required] | ||
16 | public ITaskItem BundleFile { get; set; } | ||
17 | |||
18 | /// <summary> | ||
19 | /// Gets or sets the intermedidate folder to use. | ||
20 | /// </summary> | ||
21 | public ITaskItem IntermediateDirectory { get; set; } | ||
22 | |||
23 | /// <summary> | ||
24 | /// Gets or sets the path to the output detached bundle. | ||
25 | /// </summary> | ||
26 | [Required] | ||
27 | public ITaskItem OutputFile { get; set; } | ||
28 | |||
29 | /// <summary> | ||
30 | /// Gets or sets the output. Only set if the task does work. | ||
31 | /// </summary> | ||
32 | [Output] | ||
33 | public ITaskItem Output { get; set; } | ||
34 | |||
35 | protected override void BuildCommandLine(WixCommandLineBuilder commandLineBuilder) | ||
36 | { | ||
37 | commandLineBuilder.AppendTextUnquoted("burn detach"); | ||
38 | |||
39 | commandLineBuilder.AppendFileNameIfNotNull(this.BundleFile); | ||
40 | commandLineBuilder.AppendSwitchIfNotNull("-engine ", this.OutputFile); | ||
41 | commandLineBuilder.AppendSwitchIfNotNull("-intermediatefolder ", this.IntermediateDirectory); | ||
42 | |||
43 | base.BuildCommandLine(commandLineBuilder); | ||
44 | |||
45 | commandLineBuilder.AppendTextIfNotWhitespace(this.AdditionalOptions); | ||
46 | } | ||
47 | |||
48 | protected override int ExecuteTool(string pathToTool, string responseFileCommands, string commandLineCommands) | ||
49 | { | ||
50 | var exitCode = base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands); | ||
51 | |||
52 | if (exitCode == 0) // successfully did work. | ||
53 | { | ||
54 | this.Output = this.OutputFile; | ||
55 | } | ||
56 | else if (exitCode == -1000) // no work done. | ||
57 | { | ||
58 | exitCode = 0; | ||
59 | } | ||
60 | |||
61 | return exitCode; | ||
62 | } | ||
63 | } | ||
64 | } | ||
diff --git a/src/wix/WixToolset.BuildTasks/ReattachSignedBundleEngine.cs b/src/wix/WixToolset.BuildTasks/ReattachSignedBundleEngine.cs new file mode 100644 index 00000000..c07c12b9 --- /dev/null +++ b/src/wix/WixToolset.BuildTasks/ReattachSignedBundleEngine.cs | |||
@@ -0,0 +1,71 @@ | |||
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.BuildTasks | ||
4 | { | ||
5 | using Microsoft.Build.Framework; | ||
6 | |||
7 | /// <summary> | ||
8 | /// An MSBuild task to run WiX to reattach a (signed) bundle engine to its bundle. | ||
9 | /// </summary> | ||
10 | public sealed partial class ReattachSignedBundleEngine : WixExeBaseTask | ||
11 | { | ||
12 | /// <summary> | ||
13 | /// The bundle to which to attach the bundle engine. | ||
14 | /// </summary> | ||
15 | [Required] | ||
16 | public ITaskItem BundleFile { get; set; } | ||
17 | |||
18 | /// <summary> | ||
19 | /// The bundle engine file to reattach to the bundle. | ||
20 | /// </summary> | ||
21 | [Required] | ||
22 | public ITaskItem BundleEngineFile { get; set; } | ||
23 | |||
24 | /// <summary> | ||
25 | /// Gets or sets the intermedidate folder to use. | ||
26 | /// </summary> | ||
27 | public ITaskItem IntermediateDirectory { get; set; } | ||
28 | |||
29 | /// <summary> | ||
30 | /// Gets or sets the path to the output detached bundle. | ||
31 | /// </summary> | ||
32 | [Required] | ||
33 | public ITaskItem OutputFile { get; set; } | ||
34 | |||
35 | /// <summary> | ||
36 | /// Gets or sets the output. Only set if the task does work. | ||
37 | /// </summary> | ||
38 | [Output] | ||
39 | public ITaskItem Output { get; set; } | ||
40 | |||
41 | protected override void BuildCommandLine(WixCommandLineBuilder commandLineBuilder) | ||
42 | { | ||
43 | commandLineBuilder.AppendTextUnquoted("burn reattach"); | ||
44 | |||
45 | commandLineBuilder.AppendFileNameIfNotNull(this.BundleFile); | ||
46 | commandLineBuilder.AppendSwitchIfNotNull("-engine ", this.BundleEngineFile); | ||
47 | commandLineBuilder.AppendSwitchIfNotNull("-out ", this.OutputFile); | ||
48 | commandLineBuilder.AppendSwitchIfNotNull("-intermediatefolder ", this.IntermediateDirectory); | ||
49 | |||
50 | base.BuildCommandLine(commandLineBuilder); | ||
51 | |||
52 | commandLineBuilder.AppendTextIfNotWhitespace(this.AdditionalOptions); | ||
53 | } | ||
54 | |||
55 | protected override int ExecuteTool(string pathToTool, string responseFileCommands, string commandLineCommands) | ||
56 | { | ||
57 | var exitCode = base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands); | ||
58 | |||
59 | if (exitCode == 0) // successfully did work. | ||
60 | { | ||
61 | this.Output = this.OutputFile; | ||
62 | } | ||
63 | else if (exitCode == -1000) // no work done. | ||
64 | { | ||
65 | exitCode = 0; | ||
66 | } | ||
67 | |||
68 | return exitCode; | ||
69 | } | ||
70 | } | ||
71 | } | ||
diff --git a/src/wix/WixToolset.BuildTasks/ToolsetTask_InProc.cs b/src/wix/WixToolset.BuildTasks/ToolsetTask_InProc.cs index fcf4aea9..eff117da 100644 --- a/src/wix/WixToolset.BuildTasks/ToolsetTask_InProc.cs +++ b/src/wix/WixToolset.BuildTasks/ToolsetTask_InProc.cs | |||
@@ -15,7 +15,7 @@ namespace WixToolset.BuildTasks | |||
15 | 15 | ||
16 | public partial class ToolsetTask | 16 | public partial class ToolsetTask |
17 | { | 17 | { |
18 | protected sealed override int ExecuteTool(string pathToTool, string responseFileCommands, string commandLineCommands) | 18 | protected override int ExecuteTool(string pathToTool, string responseFileCommands, string commandLineCommands) |
19 | { | 19 | { |
20 | if (this.RunAsSeparateProcess) | 20 | if (this.RunAsSeparateProcess) |
21 | { | 21 | { |
diff --git a/src/wix/WixToolset.Core.Burn/BundleBackend.cs b/src/wix/WixToolset.Core.Burn/BundleBackend.cs index 518b77c8..b179ea50 100644 --- a/src/wix/WixToolset.Core.Burn/BundleBackend.cs +++ b/src/wix/WixToolset.Core.Burn/BundleBackend.cs | |||
@@ -47,16 +47,7 @@ namespace WixToolset.Core.Burn | |||
47 | 47 | ||
48 | public bool Inscribe(IInscribeContext context) | 48 | public bool Inscribe(IInscribeContext context) |
49 | { | 49 | { |
50 | if (String.IsNullOrEmpty(context.SignedEngineFile)) | 50 | return false; |
51 | { | ||
52 | var command = new InscribeBundleCommand(context); | ||
53 | return command.Execute(); | ||
54 | } | ||
55 | else | ||
56 | { | ||
57 | var command = new InscribeBundleEngineCommand(context); | ||
58 | return command.Execute(); | ||
59 | } | ||
60 | } | 51 | } |
61 | 52 | ||
62 | public Intermediate Unbind(IUnbindContext context) | 53 | public Intermediate Unbind(IUnbindContext context) |
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/BurnReader.cs b/src/wix/WixToolset.Core.Burn/Bundles/BurnReader.cs index 575252b0..933afc77 100644 --- a/src/wix/WixToolset.Core.Burn/Bundles/BurnReader.cs +++ b/src/wix/WixToolset.Core.Burn/Bundles/BurnReader.cs | |||
@@ -45,11 +45,6 @@ namespace WixToolset.Core.Burn.Bundles | |||
45 | /// </summary> | 45 | /// </summary> |
46 | public Stream Stream => this.binaryReader?.BaseStream; | 46 | public Stream Stream => this.binaryReader?.BaseStream; |
47 | 47 | ||
48 | internal static BurnReader Open(object inputFilePath) | ||
49 | { | ||
50 | throw new NotImplementedException(); | ||
51 | } | ||
52 | |||
53 | /// <summary> | 48 | /// <summary> |
54 | /// Opens a Burn reader. | 49 | /// Opens a Burn reader. |
55 | /// </summary> | 50 | /// </summary> |
diff --git a/src/wix/WixToolset.Core.Burn/BurnCommand.cs b/src/wix/WixToolset.Core.Burn/BurnCommand.cs new file mode 100644 index 00000000..3835bf2e --- /dev/null +++ b/src/wix/WixToolset.Core.Burn/BurnCommand.cs | |||
@@ -0,0 +1,78 @@ | |||
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.Burn | ||
4 | { | ||
5 | using System; | ||
6 | using System.Threading; | ||
7 | using System.Threading.Tasks; | ||
8 | using WixToolset.Extensibility.Data; | ||
9 | using WixToolset.Extensibility.Services; | ||
10 | |||
11 | /// <summary> | ||
12 | /// Burn specialized command. | ||
13 | /// </summary> | ||
14 | internal class BurnCommand : ICommandLineCommand | ||
15 | { | ||
16 | public BurnCommand(IServiceProvider serviceProvider) | ||
17 | { | ||
18 | this.ServiceProvider = serviceProvider; | ||
19 | } | ||
20 | |||
21 | public bool ShowHelp { get; set; } | ||
22 | |||
23 | public bool ShowLogo { get; set; } | ||
24 | |||
25 | public bool StopParsing { get; set; } | ||
26 | |||
27 | private IServiceProvider ServiceProvider { get; } | ||
28 | |||
29 | private BurnSubcommandBase Subcommand { get; set; } | ||
30 | |||
31 | public Task<int> ExecuteAsync(CancellationToken cancellationToken) | ||
32 | { | ||
33 | if (this.ShowHelp || this.Subcommand is null) | ||
34 | { | ||
35 | DisplayHelp(); | ||
36 | return Task.FromResult(1); | ||
37 | } | ||
38 | |||
39 | return this.Subcommand.ExecuteAsync(cancellationToken); | ||
40 | } | ||
41 | |||
42 | public bool TryParseArgument(ICommandLineParser parser, string argument) | ||
43 | { | ||
44 | if (this.Subcommand is null) | ||
45 | { | ||
46 | switch (argument.ToLowerInvariant()) | ||
47 | { | ||
48 | case "detach": | ||
49 | this.Subcommand = new DetachSubcommand(this.ServiceProvider); | ||
50 | return true; | ||
51 | |||
52 | case "reattach": | ||
53 | this.Subcommand = new ReattachSubcommand(this.ServiceProvider); | ||
54 | return true; | ||
55 | } | ||
56 | |||
57 | return false; | ||
58 | } | ||
59 | |||
60 | return this.Subcommand.TryParseArgument(parser, argument); | ||
61 | } | ||
62 | |||
63 | private static void DisplayHelp() | ||
64 | { | ||
65 | Console.WriteLine(); | ||
66 | Console.WriteLine("Usage: wix burn detach|reattach bundle.exe -out engine.exe"); | ||
67 | Console.WriteLine(); | ||
68 | Console.WriteLine("Options:"); | ||
69 | Console.WriteLine(" -h|--help Show command line help."); | ||
70 | Console.WriteLine(" --nologo Suppress displaying the logo information."); | ||
71 | Console.WriteLine(); | ||
72 | Console.WriteLine("Commands:"); | ||
73 | Console.WriteLine(); | ||
74 | Console.WriteLine(" detach Detaches the burn engine from a bundle so it can be signed."); | ||
75 | Console.WriteLine(" reattach Reattaches a signed burn engine to a bundle."); | ||
76 | } | ||
77 | } | ||
78 | } | ||
diff --git a/src/wix/WixToolset.Core.Burn/BurnExtensionCommandLine.cs b/src/wix/WixToolset.Core.Burn/BurnExtensionCommandLine.cs new file mode 100644 index 00000000..66e77888 --- /dev/null +++ b/src/wix/WixToolset.Core.Burn/BurnExtensionCommandLine.cs | |||
@@ -0,0 +1,41 @@ | |||
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.Burn | ||
4 | { | ||
5 | using System; | ||
6 | using System.Collections.Generic; | ||
7 | using WixToolset.Extensibility; | ||
8 | using WixToolset.Extensibility.Data; | ||
9 | using WixToolset.Extensibility.Services; | ||
10 | |||
11 | /// <summary> | ||
12 | /// Parses the "msi" command-line command. See <c>WindowsInstallerCommand</c> | ||
13 | /// for the bulk of the command-line processing. | ||
14 | /// </summary> | ||
15 | internal class BurnExtensionCommandLine : BaseExtensionCommandLine | ||
16 | { | ||
17 | public BurnExtensionCommandLine(IServiceProvider serviceProvider) | ||
18 | { | ||
19 | this.ServiceProvider = serviceProvider; | ||
20 | } | ||
21 | |||
22 | private IServiceProvider ServiceProvider { get; } | ||
23 | |||
24 | public override IReadOnlyCollection<ExtensionCommandLineSwitch> CommandLineSwitches => new ExtensionCommandLineSwitch[] | ||
25 | { | ||
26 | new ExtensionCommandLineSwitch { Switch = "burn", Description = "Burn specialized operations." }, | ||
27 | }; | ||
28 | |||
29 | public override bool TryParseCommand(ICommandLineParser parser, string argument, out ICommandLineCommand command) | ||
30 | { | ||
31 | command = null; | ||
32 | |||
33 | if ("burn".Equals(argument, StringComparison.OrdinalIgnoreCase)) | ||
34 | { | ||
35 | command = new BurnCommand(this.ServiceProvider); | ||
36 | } | ||
37 | |||
38 | return command != null; | ||
39 | } | ||
40 | } | ||
41 | } | ||
diff --git a/src/wix/WixToolset.Core.Burn/BurnExtensionFactory.cs b/src/wix/WixToolset.Core.Burn/BurnExtensionFactory.cs index b34d12c1..eca94f77 100644 --- a/src/wix/WixToolset.Core.Burn/BurnExtensionFactory.cs +++ b/src/wix/WixToolset.Core.Burn/BurnExtensionFactory.cs | |||
@@ -1,4 +1,4 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | 1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. |
2 | 2 | ||
3 | namespace WixToolset.Core.Burn | 3 | namespace WixToolset.Core.Burn |
4 | { | 4 | { |
@@ -7,10 +7,21 @@ namespace WixToolset.Core.Burn | |||
7 | 7 | ||
8 | internal class BurnExtensionFactory : IExtensionFactory | 8 | internal class BurnExtensionFactory : IExtensionFactory |
9 | { | 9 | { |
10 | public BurnExtensionFactory(IServiceProvider serviceProvider) | ||
11 | { | ||
12 | this.ServiceProvider = serviceProvider; | ||
13 | } | ||
14 | |||
15 | private IServiceProvider ServiceProvider { get; } | ||
16 | |||
10 | public bool TryCreateExtension(Type extensionType, out object extension) | 17 | public bool TryCreateExtension(Type extensionType, out object extension) |
11 | { | 18 | { |
12 | extension = null; | 19 | extension = null; |
13 | 20 | ||
21 | if (extensionType == typeof(IExtensionCommandLine)) | ||
22 | { | ||
23 | extension = new BurnExtensionCommandLine(this.ServiceProvider); | ||
24 | } | ||
14 | if (extensionType == typeof(IBackendFactory)) | 25 | if (extensionType == typeof(IBackendFactory)) |
15 | { | 26 | { |
16 | extension = new BurnBackendFactory(); | 27 | extension = new BurnBackendFactory(); |
diff --git a/src/wix/WixToolset.Core.Burn/BurnSubcommandBase.cs b/src/wix/WixToolset.Core.Burn/BurnSubcommandBase.cs new file mode 100644 index 00000000..62d69d4a --- /dev/null +++ b/src/wix/WixToolset.Core.Burn/BurnSubcommandBase.cs | |||
@@ -0,0 +1,15 @@ | |||
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.Burn | ||
4 | { | ||
5 | using System.Threading; | ||
6 | using System.Threading.Tasks; | ||
7 | using WixToolset.Extensibility.Services; | ||
8 | |||
9 | internal abstract class BurnSubcommandBase | ||
10 | { | ||
11 | public abstract bool TryParseArgument(ICommandLineParser parser, string argument); | ||
12 | |||
13 | public abstract Task<int> ExecuteAsync(CancellationToken cancellationToken); | ||
14 | } | ||
15 | } | ||
diff --git a/src/wix/WixToolset.Core.Burn/DetachSubcommand.cs b/src/wix/WixToolset.Core.Burn/DetachSubcommand.cs new file mode 100644 index 00000000..a1614a85 --- /dev/null +++ b/src/wix/WixToolset.Core.Burn/DetachSubcommand.cs | |||
@@ -0,0 +1,80 @@ | |||
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.Burn | ||
4 | { | ||
5 | using System; | ||
6 | using System.IO; | ||
7 | using System.Threading; | ||
8 | using System.Threading.Tasks; | ||
9 | using WixToolset.Core.Burn.Inscribe; | ||
10 | using WixToolset.Extensibility.Services; | ||
11 | |||
12 | internal class DetachSubcommand : BurnSubcommandBase | ||
13 | { | ||
14 | public DetachSubcommand(IServiceProvider serviceProvider) | ||
15 | { | ||
16 | this.ServiceProvider = serviceProvider; | ||
17 | this.Messaging = serviceProvider.GetService<IMessaging>(); | ||
18 | } | ||
19 | |||
20 | private IServiceProvider ServiceProvider { get; } | ||
21 | |||
22 | private IMessaging Messaging { get; } | ||
23 | |||
24 | private string InputPath { get; set; } | ||
25 | |||
26 | private string IntermediateFolder { get; set; } | ||
27 | |||
28 | private string EngineOutputPath { get; set; } | ||
29 | |||
30 | public override Task<int> ExecuteAsync(CancellationToken cancellationToken) | ||
31 | { | ||
32 | if (String.IsNullOrEmpty(this.InputPath)) | ||
33 | { | ||
34 | Console.Error.WriteLine("Path to input bundle is required"); | ||
35 | return Task.FromResult(-1); | ||
36 | } | ||
37 | |||
38 | if (String.IsNullOrEmpty(this.EngineOutputPath)) | ||
39 | { | ||
40 | Console.Error.WriteLine("Path to output the bundle engine is required"); | ||
41 | return Task.FromResult(-1); | ||
42 | } | ||
43 | |||
44 | if (String.IsNullOrEmpty(this.IntermediateFolder)) | ||
45 | { | ||
46 | this.IntermediateFolder = Path.GetTempPath(); | ||
47 | } | ||
48 | |||
49 | var command = new InscribeBundleEngineCommand(this.ServiceProvider, this.InputPath, this.EngineOutputPath, this.IntermediateFolder); | ||
50 | command.Execute(); | ||
51 | |||
52 | return Task.FromResult(this.Messaging.LastErrorNumber); | ||
53 | } | ||
54 | |||
55 | public override bool TryParseArgument(ICommandLineParser parser, string argument) | ||
56 | { | ||
57 | if (parser.IsSwitch(argument)) | ||
58 | { | ||
59 | var parameter = argument.Substring(1); | ||
60 | switch (parameter.ToLowerInvariant()) | ||
61 | { | ||
62 | case "intermediatefolder": | ||
63 | this.IntermediateFolder = parser.GetNextArgumentAsDirectoryOrError(argument); | ||
64 | return true; | ||
65 | |||
66 | case "engine": | ||
67 | this.EngineOutputPath = parser.GetNextArgumentAsFilePathOrError(argument); | ||
68 | return true; | ||
69 | } | ||
70 | } | ||
71 | else if (String.IsNullOrEmpty(this.InputPath)) | ||
72 | { | ||
73 | this.InputPath = argument; | ||
74 | return true; | ||
75 | } | ||
76 | |||
77 | return false; | ||
78 | } | ||
79 | } | ||
80 | } | ||
diff --git a/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleCommand.cs b/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleCommand.cs index f835fd3a..6e071fe7 100644 --- a/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleCommand.cs | |||
@@ -2,42 +2,51 @@ | |||
2 | 2 | ||
3 | namespace WixToolset.Core.Burn.Inscribe | 3 | namespace WixToolset.Core.Burn.Inscribe |
4 | { | 4 | { |
5 | using System; | ||
5 | using System.IO; | 6 | using System.IO; |
6 | using WixToolset.Core.Burn.Bundles; | 7 | using WixToolset.Core.Burn.Bundles; |
7 | using WixToolset.Core.Native; | 8 | using WixToolset.Core.Native; |
8 | using WixToolset.Extensibility.Data; | ||
9 | using WixToolset.Extensibility.Services; | 9 | using WixToolset.Extensibility.Services; |
10 | 10 | ||
11 | internal class InscribeBundleCommand | 11 | internal class InscribeBundleCommand |
12 | { | 12 | { |
13 | public InscribeBundleCommand(IInscribeContext context) | 13 | public InscribeBundleCommand(IServiceProvider serviceProvider, string inputPath, string signedEngineFile, string outputPath, string intermediateFolder) |
14 | { | 14 | { |
15 | this.Context = context; | 15 | this.Messaging = serviceProvider.GetService<IMessaging>(); |
16 | 16 | this.IntermediateFolder = intermediateFolder; | |
17 | this.Messaging = context.ServiceProvider.GetService<IMessaging>(); | 17 | this.InputFilePath = inputPath; |
18 | this.SignedEngineFile = signedEngineFile; | ||
19 | this.OutputFile = outputPath; | ||
18 | } | 20 | } |
19 | |||
20 | private IInscribeContext Context { get; } | ||
21 | 21 | ||
22 | public IMessaging Messaging { get; } | 22 | private IMessaging Messaging { get; } |
23 | |||
24 | private string IntermediateFolder { get; } | ||
25 | |||
26 | private string InputFilePath { get; } | ||
27 | |||
28 | private string SignedEngineFile { get; } | ||
29 | |||
30 | private string OutputFile { get; } | ||
23 | 31 | ||
24 | public bool Execute() | 32 | public bool Execute() |
25 | { | 33 | { |
26 | var inscribed = false; | 34 | var inscribed = false; |
27 | var tempFile = Path.Combine(this.Context.IntermediateFolder, "bundle_engine_signed.exe"); | 35 | var tempFile = Path.Combine(this.IntermediateFolder, "~bundle_engine_signed.exe"); |
28 | 36 | ||
29 | using (var reader = BurnReader.Open(this.Context.InputFilePath)) | 37 | using (var reader = BurnReader.Open(this.Messaging, this.InputFilePath)) |
30 | { | 38 | { |
31 | FileSystem.CopyFile(this.Context.SignedEngineFile, tempFile, allowHardlink: false); | 39 | FileSystem.CopyFile(this.SignedEngineFile, tempFile, allowHardlink: false); |
32 | using (BurnWriter writer = BurnWriter.Open(this.Messaging, tempFile)) | 40 | |
41 | using (var writer = BurnWriter.Open(this.Messaging, tempFile)) | ||
33 | { | 42 | { |
34 | inscribed = writer.ReattachContainers(reader); | 43 | inscribed = writer.ReattachContainers(reader); |
35 | } | 44 | } |
36 | } | 45 | } |
37 | 46 | ||
38 | Directory.CreateDirectory(Path.GetDirectoryName(this.Context.OutputFile)); | 47 | Directory.CreateDirectory(Path.GetDirectoryName(this.OutputFile)); |
39 | 48 | ||
40 | FileSystem.MoveFile(tempFile, this.Context.OutputFile); | 49 | FileSystem.MoveFile(tempFile, this.OutputFile); |
41 | 50 | ||
42 | return inscribed; | 51 | return inscribed; |
43 | } | 52 | } |
diff --git a/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleEngineCommand.cs b/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleEngineCommand.cs index a6789796..e607a28f 100644 --- a/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleEngineCommand.cs +++ b/src/wix/WixToolset.Core.Burn/Inscribe/InscribeBundleEngineCommand.cs | |||
@@ -6,28 +6,31 @@ namespace WixToolset.Core.Burn.Inscribe | |||
6 | using System.IO; | 6 | using System.IO; |
7 | using WixToolset.Core.Burn.Bundles; | 7 | using WixToolset.Core.Burn.Bundles; |
8 | using WixToolset.Core.Native; | 8 | using WixToolset.Core.Native; |
9 | using WixToolset.Extensibility.Data; | 9 | using WixToolset.Extensibility.Services; |
10 | 10 | ||
11 | internal class InscribeBundleEngineCommand | 11 | internal class InscribeBundleEngineCommand |
12 | { | 12 | { |
13 | public InscribeBundleEngineCommand(IInscribeContext context) | 13 | public InscribeBundleEngineCommand(IServiceProvider serviceProvider, string inputPath, string outputPath, string intermediateFolder) |
14 | { | 14 | { |
15 | this.IntermediateFolder = context.IntermediateFolder; | 15 | this.Messaging = serviceProvider.GetService<IMessaging>(); |
16 | this.InputFilePath = context.InputFilePath; | 16 | this.IntermediateFolder = intermediateFolder; |
17 | this.OutputFile = context.OutputFile; | 17 | this.InputFilePath = inputPath; |
18 | this.OutputFile = outputPath; | ||
18 | } | 19 | } |
19 | 20 | ||
21 | private IMessaging Messaging { get; } | ||
22 | |||
20 | private string IntermediateFolder { get; } | 23 | private string IntermediateFolder { get; } |
21 | 24 | ||
22 | private string InputFilePath { get; } | 25 | private string InputFilePath { get; } |
23 | 26 | ||
24 | private string OutputFile { get; } | 27 | private string OutputFile { get; } |
25 | 28 | ||
26 | public bool Execute() | 29 | public void Execute() |
27 | { | 30 | { |
28 | var tempFile = Path.Combine(this.IntermediateFolder, "bundle_engine_unsigned.exe"); | 31 | var tempFile = Path.Combine(this.IntermediateFolder, "bundle_engine_unsigned.exe"); |
29 | 32 | ||
30 | using (var reader = BurnReader.Open(this.InputFilePath)) | 33 | using (var reader = BurnReader.Open(this.Messaging, this.InputFilePath)) |
31 | using (var writer = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.Read | FileShare.Delete)) | 34 | using (var writer = File.Open(tempFile, FileMode.Create, FileAccess.Write, FileShare.Read | FileShare.Delete)) |
32 | { | 35 | { |
33 | reader.Stream.Seek(0, SeekOrigin.Begin); | 36 | reader.Stream.Seek(0, SeekOrigin.Begin); |
@@ -56,8 +59,6 @@ namespace WixToolset.Core.Burn.Inscribe | |||
56 | Directory.CreateDirectory(Path.GetDirectoryName(this.OutputFile)); | 59 | Directory.CreateDirectory(Path.GetDirectoryName(this.OutputFile)); |
57 | 60 | ||
58 | FileSystem.MoveFile(tempFile, this.OutputFile); | 61 | FileSystem.MoveFile(tempFile, this.OutputFile); |
59 | |||
60 | return true; | ||
61 | } | 62 | } |
62 | } | 63 | } |
63 | } | 64 | } |
diff --git a/src/wix/WixToolset.Core.Burn/ReattachSubcommand.cs b/src/wix/WixToolset.Core.Burn/ReattachSubcommand.cs new file mode 100644 index 00000000..ce2af2d3 --- /dev/null +++ b/src/wix/WixToolset.Core.Burn/ReattachSubcommand.cs | |||
@@ -0,0 +1,101 @@ | |||
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.Burn | ||
4 | { | ||
5 | using System; | ||
6 | using System.IO; | ||
7 | using System.Threading; | ||
8 | using System.Threading.Tasks; | ||
9 | using WixToolset.Core.Burn.Inscribe; | ||
10 | using WixToolset.Extensibility.Services; | ||
11 | |||
12 | internal class ReattachSubcommand : BurnSubcommandBase | ||
13 | { | ||
14 | public ReattachSubcommand(IServiceProvider serviceProvider) | ||
15 | { | ||
16 | this.ServiceProvider = serviceProvider; | ||
17 | this.Messaging = serviceProvider.GetService<IMessaging>(); | ||
18 | } | ||
19 | |||
20 | private IServiceProvider ServiceProvider { get; } | ||
21 | |||
22 | private IMessaging Messaging { get; } | ||
23 | |||
24 | private string InputPath { get; set; } | ||
25 | |||
26 | private string SignedEnginePath { get; set; } | ||
27 | |||
28 | private string IntermediateFolder { get; set; } | ||
29 | |||
30 | private string OutputPath { get; set; } | ||
31 | |||
32 | public override Task<int> ExecuteAsync(CancellationToken cancellationToken) | ||
33 | { | ||
34 | if (String.IsNullOrEmpty(this.InputPath)) | ||
35 | { | ||
36 | Console.Error.WriteLine("Path to input bundle is required"); | ||
37 | return Task.FromResult(-1); | ||
38 | } | ||
39 | |||
40 | if (String.IsNullOrEmpty(this.SignedEnginePath)) | ||
41 | { | ||
42 | Console.Error.WriteLine("Path to detached signed bundle engine is required"); | ||
43 | return Task.FromResult(-1); | ||
44 | } | ||
45 | |||
46 | if (String.IsNullOrEmpty(this.IntermediateFolder)) | ||
47 | { | ||
48 | this.IntermediateFolder = Path.GetTempPath(); | ||
49 | } | ||
50 | |||
51 | if (String.IsNullOrEmpty(this.OutputPath)) | ||
52 | { | ||
53 | this.OutputPath = this.InputPath; | ||
54 | } | ||
55 | |||
56 | var command = new InscribeBundleCommand(this.ServiceProvider, this.InputPath, this.SignedEnginePath, this.OutputPath, this.IntermediateFolder); | ||
57 | var didWork = command.Execute(); | ||
58 | |||
59 | // If the detach subcommand did not encounter an error but did no work | ||
60 | // then return the special exit code that indicates no work was done (-1000). | ||
61 | var exitCode = this.Messaging.LastErrorNumber; | ||
62 | |||
63 | if (!didWork && exitCode == 0) | ||
64 | { | ||
65 | exitCode = -1000; | ||
66 | } | ||
67 | |||
68 | return Task.FromResult(exitCode); | ||
69 | } | ||
70 | |||
71 | public override bool TryParseArgument(ICommandLineParser parser, string argument) | ||
72 | { | ||
73 | if (parser.IsSwitch(argument)) | ||
74 | { | ||
75 | var parameter = argument.Substring(1); | ||
76 | switch (parameter.ToLowerInvariant()) | ||
77 | { | ||
78 | case "engine": | ||
79 | this.SignedEnginePath = parser.GetNextArgumentAsFilePathOrError(argument); | ||
80 | return true; | ||
81 | |||
82 | case "intermediatefolder": | ||
83 | this.IntermediateFolder = parser.GetNextArgumentAsDirectoryOrError(argument); | ||
84 | return true; | ||
85 | |||
86 | case "o": | ||
87 | case "out": | ||
88 | this.OutputPath = parser.GetNextArgumentAsFilePathOrError(argument); | ||
89 | return true; | ||
90 | } | ||
91 | } | ||
92 | else if (String.IsNullOrEmpty(this.InputPath)) | ||
93 | { | ||
94 | this.InputPath = argument; | ||
95 | return true; | ||
96 | } | ||
97 | |||
98 | return false; | ||
99 | } | ||
100 | } | ||
101 | } | ||
diff --git a/src/wix/WixToolset.Sdk/tools/wix.signing.targets b/src/wix/WixToolset.Sdk/tools/wix.signing.targets index 45556e23..cdaee4a2 100644 --- a/src/wix/WixToolset.Sdk/tools/wix.signing.targets +++ b/src/wix/WixToolset.Sdk/tools/wix.signing.targets | |||
@@ -20,6 +20,14 @@ | |||
20 | <UsingTask TaskName="InscribeMsiWithCabinetSignatures" Condition=" '$(WixTasksPath64)' != '' " AssemblyFile="$(WixTasksPath)" Architecture="x86" /> | 20 | <UsingTask TaskName="InscribeMsiWithCabinetSignatures" Condition=" '$(WixTasksPath64)' != '' " AssemblyFile="$(WixTasksPath)" Architecture="x86" /> |
21 | <UsingTask TaskName="InscribeMsiWithCabinetSignatures" Condition=" '$(WixTasksPath64)' != '' " AssemblyFile="$(WixTasksPath64)" Architecture="x64" /> | 21 | <UsingTask TaskName="InscribeMsiWithCabinetSignatures" Condition=" '$(WixTasksPath64)' != '' " AssemblyFile="$(WixTasksPath64)" Architecture="x64" /> |
22 | 22 | ||
23 | <UsingTask TaskName="DetachBundleEngineForSigning" Condition=" '$(WixTasksPath64)' == '' " AssemblyFile="$(WixTasksPath)" /> | ||
24 | <UsingTask TaskName="DetachBundleEngineForSigning" Condition=" '$(WixTasksPath64)' != '' " AssemblyFile="$(WixTasksPath)" Architecture="x86" /> | ||
25 | <UsingTask TaskName="DetachBundleEngineForSigning" Condition=" '$(WixTasksPath64)' != '' " AssemblyFile="$(WixTasksPath64)" Architecture="x64" /> | ||
26 | |||
27 | <UsingTask TaskName="ReattachSignedBundleEngine" Condition=" '$(WixTasksPath64)' == '' " AssemblyFile="$(WixTasksPath)" /> | ||
28 | <UsingTask TaskName="ReattachSignedBundleEngine" Condition=" '$(WixTasksPath64)' != '' " AssemblyFile="$(WixTasksPath)" Architecture="x86" /> | ||
29 | <UsingTask TaskName="ReattachSignedBundleEngine" Condition=" '$(WixTasksPath64)' != '' " AssemblyFile="$(WixTasksPath64)" Architecture="x64" /> | ||
30 | |||
23 | <!-- Default Inscribe properties. --> | 31 | <!-- Default Inscribe properties. --> |
24 | <PropertyGroup> | 32 | <PropertyGroup> |
25 | <InscribeNoLogo Condition=" '$(InscribeNoLogo)' == '' ">$(NoLogo)</InscribeNoLogo> | 33 | <InscribeNoLogo Condition=" '$(InscribeNoLogo)' == '' ">$(NoLogo)</InscribeNoLogo> |
@@ -230,22 +238,26 @@ | |||
230 | Inputs="@(SignTargetPath)" | 238 | Inputs="@(SignTargetPath)" |
231 | Outputs="$(SignedFilePath)"> | 239 | Outputs="$(SignedFilePath)"> |
232 | 240 | ||
233 | <Insignia | 241 | <DetachBundleEngineForSigning |
234 | BundleFile="@(SignTargetPath)" | 242 | BundleFile="@(SignTargetPath)" |
235 | OutputFile="$(IntermediateOutputPath)%(SignTargetPath.Filename)%(SignTargetPath.Extension)" | 243 | OutputFile="$(IntermediateOutputPath)%(SignTargetPath.Filename)%(SignTargetPath.Extension)" |
236 | ToolPath="$(WixToolPath)" | 244 | IntermediateDirectory="%(SignTargetPath.RootDir)%(SignTargetPath.Directory)" |
245 | |||
237 | NoLogo="$(InscribeNoLogo)" | 246 | NoLogo="$(InscribeNoLogo)" |
238 | RunAsSeparateProcess="$(RunWixToolsOutOfProc)" | ||
239 | SuppressAllWarnings="$(InscribeSuppressAllWarnings)" | 247 | SuppressAllWarnings="$(InscribeSuppressAllWarnings)" |
240 | SuppressSpecificWarnings="$(InscribeSuppressSpecificWarnings)" | 248 | SuppressSpecificWarnings="$(InscribeSuppressSpecificWarnings)" |
241 | TreatWarningsAsErrors="$(InscribeTreatWarningsAsErrors)" | 249 | TreatWarningsAsErrors="$(InscribeTreatWarningsAsErrors)" |
242 | TreatSpecificWarningsAsErrors="$(InscribeTreatSpecificWarningsAsErrors)" | 250 | TreatSpecificWarningsAsErrors="$(InscribeTreatSpecificWarningsAsErrors)" |
243 | VerboseOutput="$(InscribeVerboseOutput)" | 251 | VerboseOutput="$(InscribeVerboseOutput)" |
244 | AdditionalOptions="$(InscribeAdditionalOptions)"> | 252 | AdditionalOptions="$(InscribeAdditionalOptions)" |
253 | |||
254 | RunAsSeparateProcess="$(RunWixToolsOutOfProc)" | ||
255 | ToolExe="$(WixToolExe)" | ||
256 | ToolPath="$(WixToolDir)"> | ||
245 | <Output TaskParameter="Output" ItemName="SignBundleEngine" /> | 257 | <Output TaskParameter="Output" ItemName="SignBundleEngine" /> |
246 | </Insignia> | 258 | </DetachBundleEngineForSigning> |
247 | 259 | ||
248 | <!-- Explicitly add output to FileWrites to ensure they are included even when the target is up to date. --> | 260 | <!-- Explicitly add output to FileWrites to ensure it is included even when the target is up to date. --> |
249 | <ItemGroup> | 261 | <ItemGroup> |
250 | <FileWrites Include="$(IntermediateOutputPath)%(SignTargetPath.Filename)%(SignTargetPath.Extension)" /> | 262 | <FileWrites Include="$(IntermediateOutputPath)%(SignTargetPath.Filename)%(SignTargetPath.Extension)" /> |
251 | </ItemGroup> | 263 | </ItemGroup> |
@@ -274,22 +286,26 @@ | |||
274 | Inputs="@(SignTargetPath)" | 286 | Inputs="@(SignTargetPath)" |
275 | Outputs="$(SignedFilePath)"> | 287 | Outputs="$(SignedFilePath)"> |
276 | 288 | ||
277 | <Insignia | 289 | <ReattachSignedBundleEngine |
278 | BundleFile="@(SignBundleEngine)" | 290 | BundleFile="@(SignTargetPath)" |
279 | OriginalBundleFile="@(SignTargetPath)" | 291 | BundleEngineFile="@(SignBundleEngine)" |
280 | OutputFile="@(SignTargetPath)" | 292 | OutputFile="@(SignTargetPath)" |
281 | ToolPath="$(WixToolPath)" | 293 | IntermediateDirectory="%(SignTargetPath.RootDir)%(SignTargetPath.Directory)" |
294 | |||
282 | NoLogo="$(InscribeNoLogo)" | 295 | NoLogo="$(InscribeNoLogo)" |
283 | RunAsSeparateProcess="$(RunWixToolsOutOfProc)" | ||
284 | SuppressAllWarnings="$(InscribeSuppressAllWarnings)" | 296 | SuppressAllWarnings="$(InscribeSuppressAllWarnings)" |
285 | SuppressSpecificWarnings="$(InscribeSuppressSpecificWarnings)" | 297 | SuppressSpecificWarnings="$(InscribeSuppressSpecificWarnings)" |
286 | TreatWarningsAsErrors="$(InscribeTreatWarningsAsErrors)" | 298 | TreatWarningsAsErrors="$(InscribeTreatWarningsAsErrors)" |
287 | TreatSpecificWarningsAsErrors="$(InscribeTreatSpecificWarningsAsErrors)" | 299 | TreatSpecificWarningsAsErrors="$(InscribeTreatSpecificWarningsAsErrors)" |
288 | VerboseOutput="$(InscribeVerboseOutput)" | 300 | VerboseOutput="$(InscribeVerboseOutput)" |
289 | AdditionalOptions="$(InscribeAdditionalOptions)"> | 301 | AdditionalOptions="$(InscribeAdditionalOptions)" |
302 | |||
303 | RunAsSeparateProcess="$(RunWixToolsOutOfProc)" | ||
304 | ToolExe="$(WixToolExe)" | ||
305 | ToolPath="$(WixToolDir)"> | ||
290 | <Output TaskParameter="Output" ItemName="SignBundle" /> | 306 | <Output TaskParameter="Output" ItemName="SignBundle" /> |
291 | <Output TaskParameter="Output" ItemName="FileWrites" /> | 307 | <Output TaskParameter="Output" ItemName="FileWrites" /> |
292 | </Insignia> | 308 | </ReattachSignedBundleEngine> |
293 | </Target> | 309 | </Target> |
294 | 310 | ||
295 | <!-- | 311 | <!-- |
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/SigningFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/SigningFixture.cs index 79896172..1da449fd 100644 --- a/src/wix/test/WixToolsetTest.CoreIntegration/SigningFixture.cs +++ b/src/wix/test/WixToolsetTest.CoreIntegration/SigningFixture.cs | |||
@@ -62,5 +62,117 @@ namespace WixToolsetTest.CoreIntegration | |||
62 | }, rows); | 62 | }, rows); |
63 | } | 63 | } |
64 | } | 64 | } |
65 | |||
66 | [Fact] | ||
67 | public void CanInscribeBundle() | ||
68 | { | ||
69 | var folder = TestData.Get(@"TestData", "SimpleBundle"); | ||
70 | var signedFolder = TestData.Get(@"TestData", ".Data"); | ||
71 | |||
72 | using (var fs = new DisposableFileSystem()) | ||
73 | { | ||
74 | var baseFolder = fs.GetFolder(); | ||
75 | var intermediateFolder = Path.Combine(baseFolder, "obj"); | ||
76 | var exePath = Path.Combine(baseFolder, @"bin\test.exe"); | ||
77 | var signedExe = Path.Combine(intermediateFolder, @"signed.exe"); | ||
78 | var reattachedExe = Path.Combine(baseFolder, @"bin\final.exe"); | ||
79 | |||
80 | var result = WixRunner.Execute(new[] | ||
81 | { | ||
82 | "build", | ||
83 | Path.Combine(folder, "Bundle.wxs"), | ||
84 | "-loc", Path.Combine(folder, "Bundle.en-us.wxl"), | ||
85 | "-bindpath", Path.Combine(folder, "data"), | ||
86 | "-bindpath", signedFolder, | ||
87 | "-intermediateFolder", intermediateFolder, | ||
88 | "-o", exePath, | ||
89 | }); | ||
90 | |||
91 | result.AssertSuccess(); | ||
92 | |||
93 | result = WixRunner.Execute(new[] | ||
94 | { | ||
95 | "burn", | ||
96 | "detach", | ||
97 | exePath, | ||
98 | "-engine", signedExe | ||
99 | }); | ||
100 | |||
101 | result.AssertSuccess(); | ||
102 | |||
103 | // Swap in a pre-signed executable since signing during the unit test | ||
104 | // is a challenge. The exe isn't an exact match but that's okay for | ||
105 | // these testing purposes. | ||
106 | File.Copy(Path.Combine(signedFolder, "signed_bundle_engine.exe"), signedExe, true); | ||
107 | |||
108 | result = WixRunner.Execute(new[] | ||
109 | { | ||
110 | "burn", | ||
111 | "reattach", | ||
112 | exePath, | ||
113 | "-engine", signedExe, | ||
114 | "-o", reattachedExe | ||
115 | }); | ||
116 | |||
117 | result.AssertSuccess(); | ||
118 | Assert.True(File.Exists(reattachedExe)); | ||
119 | } | ||
120 | } | ||
121 | |||
122 | [Fact] | ||
123 | public void CanInscribeUncompressedBundle() | ||
124 | { | ||
125 | var folder = TestData.Get(@"TestData", "BundleUncompressed"); | ||
126 | var bindPath = TestData.Get(@"TestData", "SimpleBundle", "data"); | ||
127 | var signedFolder = TestData.Get(@"TestData", ".Data"); | ||
128 | |||
129 | using (var fs = new DisposableFileSystem()) | ||
130 | { | ||
131 | var baseFolder = fs.GetFolder(); | ||
132 | var intermediateFolder = Path.Combine(baseFolder, "obj"); | ||
133 | var exePath = Path.Combine(baseFolder, @"bin\test.exe"); | ||
134 | var signedExe = Path.Combine(intermediateFolder, @"signed.exe"); | ||
135 | var reattachedExe = Path.Combine(baseFolder, @"bin\final.exe"); | ||
136 | |||
137 | var result = WixRunner.Execute(new[] | ||
138 | { | ||
139 | "build", | ||
140 | Path.Combine(folder, "UncompressedBundle.wxs"), | ||
141 | "-bindpath", bindPath, | ||
142 | "-bindpath", signedFolder, | ||
143 | "-intermediateFolder", intermediateFolder, | ||
144 | "-o", exePath, | ||
145 | }); | ||
146 | |||
147 | result.AssertSuccess(); | ||
148 | |||
149 | result = WixRunner.Execute(new[] | ||
150 | { | ||
151 | "burn", | ||
152 | "detach", | ||
153 | exePath, | ||
154 | "-engine", signedExe | ||
155 | }); | ||
156 | |||
157 | result.AssertSuccess(); | ||
158 | |||
159 | // Swap in a pre-signed executable since signing during the unit test | ||
160 | // is a challenge. The exe isn't an exact match but that's okay for | ||
161 | // these testing purposes. | ||
162 | File.Copy(Path.Combine(signedFolder, "signed_bundle_engine.exe"), signedExe, true); | ||
163 | |||
164 | result = WixRunner.Execute(new[] | ||
165 | { | ||
166 | "burn", | ||
167 | "reattach", | ||
168 | exePath, | ||
169 | "-engine", signedExe, | ||
170 | "-o", reattachedExe | ||
171 | }); | ||
172 | |||
173 | Assert.True(File.Exists(reattachedExe)); | ||
174 | Assert.Equal(-1000, result.ExitCode); | ||
175 | } | ||
176 | } | ||
65 | } | 177 | } |
66 | } | 178 | } |
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/.Data/signed_bundle_engine.exe b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/.Data/signed_bundle_engine.exe new file mode 100644 index 00000000..f4f15e85 --- /dev/null +++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/.Data/signed_bundle_engine.exe | |||
Binary files differ | |||