User story
As a setup developer, I wanna let system administrators extract embedded/cab packages from the bundle I provide so that they can customize the setup binary (injecting license key, forcing language, etc.) and deploy it automatically using their tools.
This is #3659.
First part of the issue is to agree on how to "expose the code to extract bundles as a service in WixToolsetServiceProvider" (Bob words). This is what this issue is about. The second part will need more work from me. If you want both to start discussing here, I'm sorry but you'll have to wait a bit.
Note: I've been working on this for 3 months now (only on Sundays though). It took me a bunch of time to understand how wix works internally, how to compile it, how to add a unit test, etc. I made sufficient progress to have on my computer a working solution for the first part of the issue. I know it's not a complete solution but I hope it'll help refining next steps.
Proposal
a) Create an interface
- named IBundleBackendHelper
- described as "Interface provided to help working on Bundles from backend extensions."
- interface definition located at wix/src/api/wix/WixToolset.Extensibility/Services/IBundleBackendHelper.cs
- containing 2 methods
- bool ExtractUXContainer(string input path, string outputDirectory);
- bool ExtractAttachedContainers(string input path, string outputDirectory);
b) Implement the interface
Implementation will be located at wix/src/api/wix/WixToolset.Core.Burn/ExtensibilityServices/BundleBackendHelper.cs.
Both methods simply open a reader (calling BurnReader.Open method), get a temp path and call reader ExtractUXContainer/ExtractAttachedContainers accordingly.
c) Expose the interface
I think returning it when calling AddBundleBackend makes sense.
So I would have to add a IBundleBackendHelper singleton in wix/src/wix/WixToolset.Core.Burn/WixToolsetCoreServiceProviderExtensions.cs AddServices method.
d) Add a unit test
I propose creating a BundleHelper.cs file in wix/src/wix/test/WixToolsetTest.Core.
It will contain 2 Facts CanExtractAttachedContainers and CanExtractUXContainer.
Test is simple : call a static GetServiceProvider, getting IBundleBackendHelper from it, calling ExtractUXContainer/ExtractAttachedContainers on the helper and checking (boolean) result.
We may want to check some files have been extracted and do some temp folder cleanup at the end.
Considerations
Pros
- I do not move existing (BurnReader) code
- I add a simple interface
- Implementation is a simple wrapper around existing (BurnReader) methods
- I can fix BurnReader.ExtractAttachedContainers to populate attachedContainerPayloadNames so that "wix.exe burn extract -o outputDir bundleFilePath" correctly name extracted files
Cons
- code is still Burn-side
- ExtractUXContainer and ExtractAttachedContainers in wix/src/wix/WixToolset.Core.Burn/Bundles/BurnReader.cs use Cabinet.Extract method which calls wixnative.exe (C++)
I made a diff.patch so you can read and/or test my approach.
Note: I'm not happy with this approach which is not very efficient: C++ (BA) → C# (Burn) → C++ (wixnative)
I will try another solution this weekend based on IBootstrapperApplication which is a C++ COM interface and exposed in C#.
Acknowledgements
Note The company I work for is not currently using wix because it misses some features they consider a requirement.
Once these are implemented, we will test setup generation internally and if all goes well, my company will pay the fee to support you.
User story
As a setup developer, I wanna let system administrators extract embedded/cab packages from the bundle I provide so that they can customize the setup binary (injecting license key, forcing language, etc.) and deploy it automatically using their tools.
This is #3659.
First part of the issue is to agree on how to "expose the code to extract bundles as a service in WixToolsetServiceProvider" (Bob words). This is what this issue is about. The second part will need more work from me. If you want both to start discussing here, I'm sorry but you'll have to wait a bit.
Note: I've been working on this for 3 months now (only on Sundays though). It took me a bunch of time to understand how wix works internally, how to compile it, how to add a unit test, etc. I made sufficient progress to have on my computer a working solution for the first part of the issue. I know it's not a complete solution but I hope it'll help refining next steps.
Proposal
a) Create an interface
b) Implement the interface
Implementation will be located at wix/src/api/wix/WixToolset.Core.Burn/ExtensibilityServices/BundleBackendHelper.cs.
Both methods simply open a reader (calling BurnReader.Open method), get a temp path and call reader ExtractUXContainer/ExtractAttachedContainers accordingly.
c) Expose the interface
I think returning it when calling AddBundleBackend makes sense.
So I would have to add a IBundleBackendHelper singleton in wix/src/wix/WixToolset.Core.Burn/WixToolsetCoreServiceProviderExtensions.cs AddServices method.
d) Add a unit test
I propose creating a BundleHelper.cs file in wix/src/wix/test/WixToolsetTest.Core.
It will contain 2 Facts CanExtractAttachedContainers and CanExtractUXContainer.
Test is simple : call a static GetServiceProvider, getting IBundleBackendHelper from it, calling ExtractUXContainer/ExtractAttachedContainers on the helper and checking (boolean) result.
We may want to check some files have been extracted and do some temp folder cleanup at the end.
Considerations
Pros
Cons
I made a diff.patch so you can read and/or test my approach.
Note: I'm not happy with this approach which is not very efficient: C++ (BA) → C# (Burn) → C++ (wixnative)
I will try another solution this weekend based on IBootstrapperApplication which is a C++ COM interface and exposed in C#.
Acknowledgements
wixtoolsetproject because I support the maintainers.Note The company I work for is not currently using wix because it misses some features they consider a requirement.
Once these are implemented, we will test setup generation internally and if all goes well, my company will pay the fee to support you.