Building Electron for Windows
This page contains all the details and requirements to build an electron application that can be submitted to the windows store.
The build process is already setup using the provided script package-electron.js. However, you may need to setup python dependencies and a EVS account to be able to play DRM content. For that you can go directly to VMP Signing section.
Prerequisites
Ensure you have setup your development environment as explained in setup page. Make sure the Windows 10 sdk is correctly installed before proceeding.
Dependencies
Packaging for windows require the following NPM dependencies
electron-vite@electron/packagerelectron-windows-store
They should be included in the package.json. Ensure you have installed all the dependencies before proceeding.
You will also require python installed and available in the path. You can find the latest python release in their website.
Build electron (typescript)
The electron application is build using electron-vite. This is a wrapper around vite for electron applications.
The project provides a build script that will produce the built typescript files under ./dist/vite.
The output has this structure:
<root>
└─ electron
├─ ... <other project files>
├─ electron.vite.config.ts
└─ dist
├─ ... <other output files>
└─ vite
├─ preload
└─ main
The configuration of electron-vite can be updated in the electron.vite.config.ts.
You can find the documentation here.
Packaging electron for windows
Packaging the built files into a valid electron application for windows is done using @electron/packager package.
The tool can be used at the command line with pnpx @electron/packager <args>. Documentation
It can also be used programmatically from Javascript. Documentation.
The project uses the later in a build script package-electron.js.
There is a pack script to produce the builds for windows. It will create a ia32, x64 and arm64 packages under ./dist/packager.
The output has this structure:
<root>
└─ electron
├─ ... <other project files>
└─ dist
├─ ... <other output files>
└─ packager
├─ elevate-win32-arm64
├─ elevate-win32-ia32
└─ elevate-win32-x64
Configuration
The configuration for @electron/packager can be found here.
Due to the need to support DRM, the project does not use a regular electron package but a fork from castLabs called Electron for Content Security (ECS). The releases are taken from the repo electron-releases.
In order to use this fork with @electron/packager the following configuration is needed to provide a mirror to the electron dependencies.
// Sample configuration
const { packager } = require('@electron/packager');
packager({
download: {
mirrorOptions: {
mirror:
'https://github.com/castlabs/electron-releases/releases/download/',
},
},
});
Verified Media Path (VMP) signing
This is a required step to Widevine Content Decryption Module (CDM) to work properly.
If you don't intend to play DRM content on the built application, you can skip this step.
A legal requirement for Widevine CDM is that the module needs to be downloaded dynamically at runtime. This means that it cannot be prepackaged and distributed along with the main build. The castLabs fork will do that automatically upon first launch of the application. The only requirement is to VMP sign the build. The castLabs team have set a service that can be used to VMP sign. It is called Electron for Content Security VMP signing or EVS for short.
The instructions to use EVS can be found here.
VMP signing
The EVS requires signup to be used. The signup and account management is done through the python command line package that castLabs provide.
Python dependencies
Using the evs commandline requires python. Make sure it is installed and in your path before proceeding.
On windows the python executable may be the python launcher or py command.
To install python dependencies it is recommended to use a virtual environment rather than install them globally. Run the following commands from windows powershell or cmd.exe to setup the environment from the <root>/electron directory.
# Create virtual environment
py -m venv venv # This will create a ./venv directory
# In Powershell run
.\venv\Scripts\Activate.ps1
# or in CMD run
venv\Scripts\activate.bat
# Install python dependencies
python -m pip install -r requirements.txt
# Notice that we now use `python` instead of `py`
On unix environments such as mac or linux the steps above can be performed with slightly differences.
The command to call python may vary but the most common command is python3. Distributions such as Ubuntu may provide a package python-is-python3 which will allow you to use python command. Make sure you use the correct command depending on your platform.
The second command to activate the virtual environment will be
. ./venv/bin/activate
You will know that the virtual environment is working correctly if you check for the location of python. In windows running where.exe python will yield something like
> where.exe python
C:\Users\eduardo\projects\hp-channels-desktop\electron\venv\Scripts\python.exe
C:\Users\eduardo\AppData\Local\Programs\Python\Python312\python.exe
C:\Users\eduardo\AppData\Local\Microsoft\WindowsApps\python.exe
Noticed that the top python.exe is under the venv directory from our virtual environment.. This means that the virtual environment is active.
The virtual environment will also register a command deactivate to deactivate the virtual environment, so you can use your global python installation again. Alternatively, open another terminal window.
After installing the dependencies in requirements.txt the castlabs_evs package will be available.
Signin EVS
Use the account stored in evs_accedo_account entry in HP Channels vault in 1Password. If you do not have access to the vault, please open an IT ticket.
Then signin with the command
python -m castlabs_evs.account reauth
## interactive prompt
Discarding authorization token(s)
Refreshing authorization token(s)
>> Account Name [example]:
>> Password []: XXXXXXXX
Now we can sign the builds
<root>
└─ electron
└─ dist
└─ packager
├─ telvie-win32-arm64
├─ telvie-win32-ia32
└─ telvie-win32-x64
To VMP sign the builds run the command
# Path to directory containing the .exe file
python -m castlabs_evs.vmp sign-pkg ./dist/packager/telvie-win32-x64
# Signing: ./dist/packager/telvie-win32-x64
# Verifying any existing VMP signature
# - Signature invalid: Failed to verify signature
# - Requesting VMP signature
Notice that you need to do this to each build that you want signed
For more information about signing, account creation, recover account, change account information, etc. Please check the documentation for EVS
Packaging APPX
To distribute the application through the Microsoft Store the application needs to be bundled using the APPX format.
In the partner portal for the Microsoft Store you need to create a new product to get the required information for the manifest file.
It is also important that the type of submission is MSIX or PWA and not MSI or EXE. It is one of the first options and it can only be set at the beginning.
Certificates
Follow the setup to create developer certificates. The certificates are only needed for sideloading the application. You won't be able to install the application if you don't sign it.
For release on the store the certificates are not needed because Microsoft will sign the packages after passing certification.
Required information
Information in the manifest AppXManifest.xml needs to match the information of the account that publishes the application.
Ensure you have the following information available.
publisher: 'CN=71709e75-e14d-4178-ba73-f3b9e422bc10 (sample value)'
publisherDisplayName: 'Publisher' (name registered in microsoft partner portal)
name (packageName): 'Publisher.NamedReserved' (combination of publisher + reserved name in pascal case)
displayName (packageDisplayName): 'Named reserved' (name of the product that was reserved when creating a new product)
Creating APPX bundle
The packaging is handle by electron-windwos-store package. It offers a cli interface that you can find here.
A sample command to package
pnpx electron-windows-store --input-directory .\dist\packager\telvie-win32-x64 --output-directory .\dist\appx\telvie-win32-x64 --windows-build --package-version 1.0.0.0 --package-name 'telvie'
The project uses the programmatic approach in a build script package-electron.js.
The api documentation to use the package programmatically is here.
Use the provided pack:appx script to create a set of appx builds. The output will be as follows.
<root>
└─ electron
├─ ... <other project files>
└─ dist
├─ ... <other output files>
└─ appx
├─ telvie-win32-arm64
├─ telvie-win32-ia32
└─ telvie-win32-x64
Configuration
Sample configuration for programmatic use
const convertToWindowsStore = require('electron-windows-store');
const windowsKit = process.env.WINDOWSSDKDIR;
await convertToWindowsStore({
// Do not set to true
containerVirtualization: false,
// Output appx bundle
outputDirectory: '/path/to/output',
// Windows store requies 4 digits from which the last one needs to be 0 for the windows store use
// Ref https://learn.microsoft.com/en-us/windows/apps/publish/publish-your-app/msix/app-package-requirements#package-version-numbering
packageVersion: `1.0.0.0`,
// These depend on the publisher account. If the values
// does not match the account, the package won't be valid
packageName: 'AccedoNAM.PlayerTestAccedoElectron',
packageDisplayName: 'Player Test Accedo Electron',
packageDescription: 'Streaming application',
packageExecutable: `app/${appName}.exe`,
publisher: 'CN=3A39F9FB-26B4-4860-883E-ADCBDE36D984',
publisherDisplayName: 'Accedo NAM',
// Default location of windows 10 sdk.
// Only change it if you have not use the defualt
// installation path.
windowsKit, // default location --> 'C:\\Program Files (x86)\\Windows Kits\\10\\bin\\x64',
// Path to certificates or remove it if using
// a `~/.electron-windows-store` config.
devCert: path.resolve(
path.join(__dirname, '..', 'devcerts', 'developmentca.pfx'),
),
});
Creating MSIX package
The packaging is handle by electron-windwos-msix package.
Sample command to package
pnpm run pack:appx --msix
The project uses the programmatic approach in a build script package-electron.js.
The api documentation to use the package: documentation.
Use the provided pack:appx --msix script to create a set of msix builds. The output will be as follows.
<root>
└─ electron
├─ ... <other project files>
└─ msix
├─ telvie-win32-arm64
├─ telvie-win32-ia32
└─ telvie-win32-x64
const packageMSIX = require('electron-windows-msix');
const windowsKit =
process.env.WINDOWSSDKDIR ||
'C:\\Program Files (x86)\\Windows Kits\\10\\bin\\10.0.22621.0\\x64';
packageMSIX({
appDir: 'C:\\temp\\myapp', // Folder with your packaged Electron app
appManifest: 'C:\\temp\\AppxManifest.xml', // Your app manifest file
packageAssets: 'C:\\temp\\assets', // Folder with required assets
outputDir: 'C:\\temp\\out', // Output directory for the .msix package
windowsKitPath: windowsKit, // Specify custom Windows Kit path
createPri: false, // Disable creation of PRI resource files (if not needed)
cert: 'C:\\temp\\app_cert.pfx', // Path to your signing certificate
cert_pass: 'hellomsix', // Certificate password
packageName: 'MyApp.msix', // Name for the MSIX package
logLevel: 'warn', // Set to 'warn' or 'debug' if you need more detailed output
});