mirror of
https://github.com/electron/electron.git
synced 2026-05-02 03:00:22 -04:00
feat: msix auto-updater (#49585)
* feat: native auto updater for MSIX on Windows Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com> * doc: added MSIX debug documentation Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com> * fix: allow downgrade with json release file and emit update-available Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com> * test: msix auot-update tests Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com> * doc: API documentation Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com> * test: add package version validation Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com> * fix: docs typo Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com> * fix: don't allow auto-updating when using appinstaller manifest Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com> * fix: getPackageInfo interface implementation Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com> * fix: review feedback, add comment Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com> * fix: missed filename commit Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com> * fix: install test cert on demand Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com> * fix: time stamp mismatch in tests Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com> * fix: feedback - rename to MSIXPackageInfo Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com> * fix: update and reference windowsStore property Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com> * fix: remove getPackagInfo from public API Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com> * fix: type error bcause of removed API Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com> * fix: fix Windows MSIX release build errors (#49613) * fix: fix MSIX release build * fix: add C++/WinRT headers * build: modify include paths * fix: compile msix as seperate source set * build: add additional needed deps for msix --------- Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: Jan Hannemann <jan.hannemann@outlook.com> Co-authored-by: Keeley Hammond <vertedinde@electronjs.org>
This commit is contained in:
50
spec/fixtures/api/autoupdater/msix/ElectronDevAppxManifest.xml
vendored
Normal file
50
spec/fixtures/api/autoupdater/msix/ElectronDevAppxManifest.xml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Package
|
||||
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
|
||||
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
|
||||
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
||||
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
|
||||
xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
|
||||
xmlns:desktop2="http://schemas.microsoft.com/appx/manifest/desktop/windows10/2"
|
||||
IgnorableNamespaces="uap uap3 desktop2">
|
||||
<Identity Name="Electron.Dev.MSIX"
|
||||
ProcessorArchitecture="x64"
|
||||
Version="1.0.0.0"
|
||||
Publisher="CN=Electron"/>
|
||||
<Properties>
|
||||
<DisplayName>Electron Dev MSIX</DisplayName>
|
||||
<PublisherDisplayName>Electron</PublisherDisplayName>
|
||||
<Logo>assets\icon.png</Logo>
|
||||
</Properties>
|
||||
<Dependencies>
|
||||
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.17763.0" />
|
||||
</Dependencies>
|
||||
<Resources>
|
||||
<Resource Language="en-US" />
|
||||
</Resources>
|
||||
<Applications>
|
||||
<Application Id="ElectronMSIX" Executable="Electron.exe" EntryPoint="Windows.FullTrustApplication">
|
||||
<uap:VisualElements
|
||||
DisplayName="Electron Dev MSIX"
|
||||
Description="Electron running with Identity"
|
||||
Square44x44Logo="assets\Square44x44Logo.png"
|
||||
Square150x150Logo="assets\Square150x150Logo.png"
|
||||
BackgroundColor="transparent">
|
||||
</uap:VisualElements>
|
||||
<Extensions>
|
||||
<uap3:Extension
|
||||
Category="windows.appExecutionAlias"
|
||||
Executable="Electron.exe"
|
||||
EntryPoint="Windows.FullTrustApplication">
|
||||
<uap3:AppExecutionAlias>
|
||||
<desktop:ExecutionAlias Alias="ElectronMSIX.exe" />
|
||||
</uap3:AppExecutionAlias>
|
||||
</uap3:Extension>
|
||||
</Extensions>
|
||||
</Application>
|
||||
</Applications>
|
||||
<Capabilities>
|
||||
<rescap:Capability Name="runFullTrust" />
|
||||
<Capability Name="internetClient" />
|
||||
</Capabilities>
|
||||
</Package>
|
||||
BIN
spec/fixtures/api/autoupdater/msix/HelloMSIX_V1.msix
vendored
Normal file
BIN
spec/fixtures/api/autoupdater/msix/HelloMSIX_V1.msix
vendored
Normal file
Binary file not shown.
BIN
spec/fixtures/api/autoupdater/msix/HelloMSIX_V2.msix
vendored
Normal file
BIN
spec/fixtures/api/autoupdater/msix/HelloMSIX_V2.msix
vendored
Normal file
Binary file not shown.
BIN
spec/fixtures/api/autoupdater/msix/MSIXDevCert.cer
vendored
Normal file
BIN
spec/fixtures/api/autoupdater/msix/MSIXDevCert.cer
vendored
Normal file
Binary file not shown.
22
spec/fixtures/api/autoupdater/msix/install_test_cert.ps1
vendored
Normal file
22
spec/fixtures/api/autoupdater/msix/install_test_cert.ps1
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
Add-Type -AssemblyName System.Security.Cryptography.X509Certificates
|
||||
|
||||
# Path to cert file one folder up relative to script location
|
||||
$scriptDir = Split-Path -Parent $PSCommandPath
|
||||
$certPath = Join-Path $scriptDir "MSIXDevCert.cer" | Resolve-Path
|
||||
|
||||
# Load the certificate from file
|
||||
$cert = [System.Security.Cryptography.X509Certificates.X509CertificateLoader]::LoadCertificateFromFile($certPath)
|
||||
|
||||
$trustedStore = Get-ChildItem -Path "cert:\LocalMachine\TrustedPeople" | Where-Object { $_.Thumbprint -eq $cert.Thumbprint }
|
||||
if (-not $trustedStore) {
|
||||
# We gonna need admin privileges to install the cert
|
||||
if (-Not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
||||
Start-Process powershell -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs
|
||||
exit
|
||||
}
|
||||
# Install the public cert to LocalMachine\TrustedPeople (for MSIX trust)
|
||||
Import-Certificate -FilePath $certPath -CertStoreLocation "cert:\LocalMachine\TrustedPeople" | Out-Null
|
||||
Write-Host " 🏛️ Installed to: cert:\LocalMachine\TrustedPeople"
|
||||
} else {
|
||||
Write-Host " ✅ Certificate already trusted in: cert:\LocalMachine\TrustedPeople"
|
||||
}
|
||||
96
spec/fixtures/api/autoupdater/msix/main.js
vendored
Normal file
96
spec/fixtures/api/autoupdater/msix/main.js
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
const { app, autoUpdater } = require('electron');
|
||||
|
||||
// Parse command-line arguments
|
||||
const args = process.argv.slice(2);
|
||||
const command = args[0];
|
||||
const commandArg = args[1];
|
||||
|
||||
app.whenReady().then(() => {
|
||||
try {
|
||||
// Debug: log received arguments
|
||||
if (process.env.DEBUG) {
|
||||
console.log('Command:', command);
|
||||
console.log('Command arg:', commandArg);
|
||||
console.log('All args:', JSON.stringify(args));
|
||||
}
|
||||
|
||||
if (command === '--printPackageId') {
|
||||
const packageInfo = autoUpdater.getPackageInfo();
|
||||
if (packageInfo.familyName) {
|
||||
console.log(`Family Name: ${packageInfo.familyName}`);
|
||||
console.log(`Package ID: ${packageInfo.id || 'N/A'}`);
|
||||
console.log(`Version: ${packageInfo.version || 'N/A'}`);
|
||||
console.log(`Development Mode: ${packageInfo.developmentMode ? 'Yes' : 'No'}`);
|
||||
console.log(`Signature Kind: ${packageInfo.signatureKind || 'N/A'}`);
|
||||
if (packageInfo.appInstallerUri) {
|
||||
console.log(`App Installer URI: ${packageInfo.appInstallerUri}`);
|
||||
}
|
||||
app.quit();
|
||||
} else {
|
||||
console.error('No package identity found. Process is not running in an MSIX package context.');
|
||||
app.exit(1);
|
||||
}
|
||||
} else if (command === '--checkUpdate') {
|
||||
if (!commandArg) {
|
||||
console.error('Update URL is required for --checkUpdate');
|
||||
app.exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Use hardcoded headers if --useCustomHeaders flag is provided
|
||||
let headers;
|
||||
let allowAnyVersion = false;
|
||||
if (args[2] === '--useCustomHeaders') {
|
||||
headers = {
|
||||
'X-AppVersion': '1.0.0',
|
||||
Authorization: 'Bearer test-token'
|
||||
};
|
||||
} else if (args[2] === '--allowAnyVersion') {
|
||||
allowAnyVersion = true;
|
||||
}
|
||||
|
||||
// Set up event listeners
|
||||
autoUpdater.on('checking-for-update', () => {
|
||||
console.log('Checking for update...');
|
||||
});
|
||||
|
||||
autoUpdater.on('update-available', () => {
|
||||
console.log('Update available');
|
||||
});
|
||||
|
||||
autoUpdater.on('update-not-available', () => {
|
||||
console.log('Update not available');
|
||||
app.quit();
|
||||
});
|
||||
|
||||
autoUpdater.on('update-downloaded', (event, releaseNotes, releaseName, releaseDate, updateUrl) => {
|
||||
console.log('Update downloaded');
|
||||
console.log(`Release Name: ${releaseName || 'N/A'}`);
|
||||
console.log(`Release Notes: ${releaseNotes || 'N/A'}`);
|
||||
console.log(`Release Date: ${releaseDate || 'N/A'}`);
|
||||
console.log(`Update URL: ${updateUrl || 'N/A'}`);
|
||||
app.quit();
|
||||
});
|
||||
|
||||
autoUpdater.on('error', (error, message) => {
|
||||
console.error(`Update error: ${message || error.message || 'Unknown error'}`);
|
||||
app.exit(1);
|
||||
});
|
||||
|
||||
// Set the feed URL with optional headers and allowAnyVersion, then check for updates
|
||||
if (headers || allowAnyVersion) {
|
||||
autoUpdater.setFeedURL({ url: commandArg, headers, allowAnyVersion });
|
||||
} else {
|
||||
autoUpdater.setFeedURL(commandArg);
|
||||
}
|
||||
autoUpdater.checkForUpdates();
|
||||
} else {
|
||||
console.error(`Unknown command: ${command || '(none)'}`);
|
||||
app.exit(1);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Unhandled error:', error.message);
|
||||
console.error(error.stack);
|
||||
app.exit(1);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user