-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: support completely custom AppxManifest.xml #8609
base: master
Are you sure you want to change the base?
feat: support completely custom AppxManifest.xml #8609
Conversation
🦋 Changeset detectedLatest commit: bf91a11 The changes in this PR will be included in the next version bump. This PR includes changesets to release 8 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
Thanks for the contribution! 🙂 This functionality should already exist in an electron-builder electron-builder/packages/app-builder-lib/src/configuration.ts Lines 343 to 346 in 74d98d8
|
@mmaietta It is very confusing - I don't see how I think the PR should offer a way to replace two types of manifests, one just like the default, that has template variables and one raw XML - as is, no interpolation at all. So that const manifestFile = this.options.customManifestPath || stageDir.getTempFile("AppxManifest.xml")
await this.writeManifest(manifestFile, arch, await this.computePublisherName(), userAssets) But I don't know how distinguish between raw and template based one. |
I think I got it, but let's say we have this So to support such a thing, the original template namespaces must be extended, plus new expressions for extensions. If one would have direct template access, he could just
xmlns:desktop2="http://schemas.microsoft.com/appx/manifest/desktop/windows10/2"
<Extensions>
<desktop2:Extension Category="windows.firewallRules">
<desktop2:FirewallRules>
<desktop2:Rule Direction="in" Protocol="TCP" LocalPortMin="22022" LocalPortMax="24044" Profile="all" Action="allow" />
</desktop2:FirewallRules>
</desktop2:Extension>
</Extensions> With the existing hook, I came up to this - it does the job, but it is horrendous appxManifestCreated: async (appxPath) => {
const manifest = await xml2js.parseStringPromise(fs.readFileSync(appxPath, "utf8").toString());
manifest.Package.$["xmlns:desktop2"] = "http://schemas.microsoft.com/appx/manifest/desktop/windows10/2";
const application = manifest.Package.Applications[0].Application[0];
application.Extensions = application.Extensions || [];
application.Extensions.push({
"desktop2:Extension": {
$: {
Category: "windows.fileTypeAssociation",
},
"desktop2:FirewallRules": {
"desktop2:Rule": {
$: {
Direction: "in",
Profile: "private",
Protocol: "TCP",
LocalPortMin: "22022",
LocalPortMax: "24044",
Action: "allow",
},
},
},
},
});
const builder = new xml2js.Builder();
const manifestDocument = builder.buildObject(manifest);
fs.writeFileSync(appxPath, manifestDocument);
} |
Ohhhh I see, you want to be able to provide a custom AppxManifest that allows for both template or raw. The hook only allows to replace the file with a raw manifest.
What if we allow both? Let the
Related note, I'll also need two unit test cases written for this functionality if we go with that approach ☝️ . One with a raw manifest, and the other with a template manifest. I'm happy to help contribute to this PR by writing the unit tests, but I'll need both manifests from you committed to this branch first for me to build on top of 😄 |
That's great Here it is a manifest that totally works for my project https://container-desktop.com <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10" xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities" xmlns:desktop2="http://schemas.microsoft.com/appx/manifest/desktop/windows10/2">
<Identity Name="IonutStoica.ContainerDesktop" ProcessorArchitecture="x64" Publisher="CN=52408AA8-2ECC-4E48-9A2C-6C1F69841C79" Version="5.2.13.0"/>
<Properties>
<DisplayName>Container Desktop</DisplayName>
<PublisherDisplayName>Ionut.Stoica</PublisherDisplayName>
<Description>Container Desktop</Description>
<Logo>assets\StoreLogo.png</Logo>
</Properties>
<Resources>
<Resource Language="en-US"/>
</Resources>
<Dependencies>
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.18362.0" MaxVersionTested="10.0.18362.0"/>
</Dependencies>
<Capabilities>
<Capability Name="internetClient"/>
<Capability Name="privateNetworkClientServer"/>
<rescap:Capability Name="runFullTrust"/>
</Capabilities>
<Applications>
<Application Id="IonutStoica.ContainerDesktop" Executable="app\Container Desktop.exe" EntryPoint="Windows.FullTrustApplication">
<uap:VisualElements BackgroundColor="#464646" DisplayName="Container Desktop" Square150x150Logo="assets\Square150x150Logo.png" Square44x44Logo="assets\Square44x44Logo.png" Description="Container Desktop">
<uap:DefaultTile Wide310x150Logo="assets\Wide310x150Logo.png" Square310x310Logo="assets\LargeTile.png" Square71x71Logo="assets\SmallTile.png"/>
</uap:VisualElements>
</Application>
</Applications>
<Extensions>
<desktop2:Extension Category="windows.firewallRules">
<desktop2:FirewallRules Executable="app\bin\container-desktop-ssh-relay.exe">
<desktop2:Rule Direction="in" Profile="private" IPProtocol="TCP" LocalPortMin="22022" LocalPortMax="24044"/>
</desktop2:FirewallRules>
</desktop2:Extension>
</Extensions>
</Package> To generate this manifest with the hook, I had to do this: appxManifestCreated: async (appxPath) => {
const manifest = await xml2js.parseStringPromise(fs.readFileSync(appxPath, "utf8").toString());
manifest.Package.$["xmlns:uap"] = "http://schemas.microsoft.com/appx/manifest/uap/windows10";
manifest.Package.$["xmlns:desktop"] = "http://schemas.microsoft.com/appx/manifest/desktop/windows10";
manifest.Package.$["xmlns:desktop2"] = "http://schemas.microsoft.com/appx/manifest/desktop/windows10/2";
manifest.Package.Capabilities = [
[
{ Capability: { $: { Name: "internetClient" } } },
{ Capability: { $: { Name: "privateNetworkClientServer" } } },
{ "rescap:Capability": { $: { Name: "runFullTrust" } } },
],
];
manifest.Package.Extensions = manifest.Package.Extensions || [];
manifest.Package.Extensions.push({
"desktop2:Extension": {
$: {
Category: "windows.firewallRules",
},
"desktop2:FirewallRules": {
$: {
Executable: "app\\bin\\container-desktop-ssh-relay.exe",
},
"desktop2:Rule": {
$: {
Direction: "in",
Profile: "private",
IPProtocol: "TCP",
LocalPortMin: "22022",
LocalPortMax: "24044",
},
},
},
},
});
const builder = new xml2js.Builder();
const manifestDocument = builder.buildObject(manifest);
fs.writeFileSync(appxPath, manifestDocument);
} Because of the use of You can close the ticket and not do anything if we can somehow improve just the documentation on how to use the custom hook with good examples as above as it touches all points. Basically |
Thanks! Alrighty, I can take it from here if you'd like (unless you have commits to still push 🙂 ) Thoughts on having the manifest default to reading from the Resources dir unless it's an absolute path? |
Nothing more to add, go for it, thank you so much! |
…build resources directory. added unit tests
@iongion PR is ready but I need the snapshots regenerated for it as I can't build the AppX on my mac M2.
|
Just did, it needs some changes
pnpm compile && cross-env UPDATE_SNAPSHOT=true TEST_FILES=appxTest pnpm ci:test
<desktop2:FirewallRules Executable="${executable}">
<desktop2:Rule Direction="in" Profile="private" IPProtocol="TCP" LocalPortMin="22022" LocalPortMax="24044"/>
</desktop2:FirewallRules>
<desktop2:FirewallRules Executable="app\\Test App ßW.exe">
<desktop2:Rule Direction="in" Profile="private" IPProtocol="TCP" LocalPortMin="22022" LocalPortMax="24044"/>
</desktop2:FirewallRules>
$env:SIGNTOOL_PATH="C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\signtool.exe"
pnpm compile && cross-env UPDATE_SNAPSHOT=true TEST_FILES=appxTest pnpm ci:test Now all tests pass
NOTE - If using the bundled signtool, then the tests will fail because of this
Just a FYI, there is another tool to sign windows executables, which works on all operating systems - https://ebourg.github.io/jsign/ but it is java based |
So I don't seem to be running into any issue with signtool, rather it's something wrong with the template manifest (probably why allowing a custom one was never previously implemented since the error messages are so obscure.
Can you take a look at |
@iongion are you willing to try this out in an alpha release of electron-builder or do you need the electron-builder version be in GA (non-alpha)? |
@@ -10,7 +10,7 @@ | |||
"console": "integratedTerminal", | |||
"internalConsoleOptions": "openOnFirstSessionStart", | |||
"env": { | |||
"TEST_FILES": "BuildTest" | |||
"TEST_FILES": "appxTest" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this need to be modified? Was it forgotten to be deleted?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forgot to be deleted. I'll update the PR
PR tries to give total control over the manifest to the users.
To provide mitigation for issues like