electron-builder
electron-builder copied to clipboard
Auto update failed while executing the powershell command
- Electron-Builder Version: 22.2.0
- Node Version: 14.16.0
- Electron Version: 17.4.9
- Electron Type (current, beta, nightly): current
- Electron Updater: 5.2.1
- Target: nsis
Using Electron updater and git hub provider for auto update. After the update downloaded from github, A JavaScript error message displayed.
[Window Title] Error
[Main Instruction] A JavaScript error occurred in the main process
[Content] Uncaught Exception: Error: Command failed: powershell.exe -NoProfile -NonInteractive -InputFormat None -Command Get-AuthenticodeSignature -LiteralPath 'C:\Users\Administrator\AppData\Local\testApp-updater\pending\temp-update.exe' | ConvertTo-Json -Compress | ForEach-Object { [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($_)) }
at ChildProcess.exithandler (node:child_process:406:12) at ChildProcess.emit (node:events:390:28) at maybeClose (node:internal/child_process:1064:16) at Process.ChildProcess._handle.onexit (node:internal/child_process:301:5)
[OK]
This is occurring only in Windows thin clients. I couldn't able to reproduce in my windows laptop. I tried few other Windows laptops to test, but I couldn't able to reproduce it other than thin clients.
I tried to manually run this command to see, if there is any issue. but the command is executed fine without any error.
We've had 16k reports of this error in Evernote's updater.
Error: Command failed: powershell.exe -NoProfile -NonInteractive -InputFormat None -Command Get-AuthenticodeSignature -LiteralPath '***********AppData\Local\evernote-client-updater\pending\temp-Evernote-10.43.7-win-ddl-ga-3598-a51c0cce94-setup.exe' | ... File "node:child_process", line 406, in ChildProcess.exithandler File "node:events", line 390, in ChildProcess.emit File "node:domain", line 475, in ChildProcess.emit File "node:internal/child_process", line 1064, in maybeClose File "node:internal/child_process", line 301, in Process.ChildProcess._handle.onexit
Our error logs are also filled with this error:
Unhandled Error
Error: Command failed: powershell.exe -NoProfile -NonInteractive -InputFormat None -Command Get-AuthenticodeSignature -LiteralPath 'C:/Users/User/AppData/Local/appname-updater/pending/temp-AppName-Setup-1.0.99.exe' | ConvertTo-Json -Compress | ForEach-Object { [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($_)) }
at ChildProcess.exithandler (node:child_process:407:12)
at ChildProcess.emit (node:events:527:28)
at maybeClose (node:internal/child_process:1092:16)
at Socket.
Any clues how to fix or silence this error? It seems to occur only the first time the app is started according to one user report we got.
Hi! We are also experiencing the issue mentioned above. A lot of our users can't perform the auto update properly and this is a major issue for us as some of them are not up to date with the current version. Is there any updates on this issue? Did someone find a workaround or manage to figure out where this was coming from?
Here is the command that is failing on Windows if it can be helpful :
Command failed: powershell.exe -NoProfile -NonInteractive -InputFormat None -Command Get-AuthenticodeSignature -LiteralPath 'C:\Users\username\AppData\Local\appname-updater\pending\temp-appname-setup-X.X.X.exe' | ConvertTo-Json -Compress | ForEach-Object { [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($_)) }
We have the same issue, and not sure under what condition it happens. The code fails here https://github.com/electron-userland/electron-builder/blob/346af1d470ebbf12733a9619a2389bcfdf452bc6/packages/electron-updater/src/windowsExecutableCodeSignatureVerifier.ts#L33
We had the issue that appears to occur when the machine doesn't have enough CPU/memory. It was timing out before the certification verification could complete.
I've also been running into this issue -- but intermittently, even on the same machine. I haven't really noticed a pattern but sometimes it'll resolve itself with a restart of the application in question. Worth noting it doesn't just happen on thin clients for me, reproducible intermittently on my lappy.
Powershell version I'm working with
PS C:\code> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.19041.2364
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.19041.2364
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
Attempt to run command manually
I attempted to run the command in it's entirety manually, and was immediately confronted with:
powershell.exe -NoProfile -NonInteractive -InputFormat None -Command Get-AuthenticodeSignature -LiteralPath './electron/output/MyApp Setup 9.1.52.exe' | ConvertTo-Json -Compress | ForEach-Object { [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($_)) }
WyJHZXQtQXV0aGVudGljb2RlU2lnbmF0dXJlIDogQSBwb3NpdGlvbmFsIHBhcmFtZXRlciBjYW5ub3QgYmUgZm91bmQgdGhhdCBhY2NlcHRzIGFyZ3VtZW50IFx1MDAyN1NldHVwXHUwMDI3LiIsIkF0IGxpbmU6MSBjaGFyOjEiLCIrIEdldC1BdXRoZW50aWNvZGVTaWduYXR1cmUgLUxpdGVyYWxQYXRoIC4vZWxlY3Ryb24vb3V0cHV0L015QXBwIFNldHVwICAuLi4iLCIrIH5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fiIsIiAgICArIENhdGVnb3J5SW5mbyAgICAgICAgICA6IEludmFsaWRBcmd1bWVudDogKDopIFtHZXQtQXV0aGVudGljb2RlU2lnbmF0dXJlXSwgUGFyYW1ldGVyQmluZGluZ0V4Y2VwdGlvbiIsIiAgICArIEZ1bGx5UXVhbGlmaWVkRXJyb3JJZCA6IFBvc2l0aW9uYWxQYXJhbWV0ZXJOb3RGb3VuZCxNaWNyb3NvZnQuUG93ZXJTaGVsbC5Db21tYW5kcy5HZXRBdXRoZW50aWNvZGVTaWduYXR1cmVDb21tYW5kIiwiICJd
The base64 decodes to:
powershell.exe -NoProfile -NonInteractive -InputFormat None -Command Get-AuthenticodeSignature -LiteralPath './electron/output/MyApp Setup 9.1.52.exe' | ConvertTo-Json -Compress | ForEach-Object { [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($_)) }
["Get-AuthenticodeSignature : A positional parameter cannot be found that accepts argument \u0027Setup\u0027.","At line:1 char:1","+ Get-AuthenticodeSignature -LiteralPath ./electron/output/MyApp Setup ...","+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"," + CategoryInfo : InvalidArgument: (:) [Get-AuthenticodeSignature], ParameterBindingException"," + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.GetAuthenticodeSignatureCommand"," "]
This lead me down to reading a bit more about the -Command
parameter. It looks like you can make use of it like: powershell.exe -Command { Get-Authenticode -LiteralPath './path/to/file with spaces.exe' }
Attempt to run with braces
powershell.exe -NoProfile -NonInteractive -InputFormat None -Command {Get-AuthenticodeSignature -LiteralPath './electron/output/MyApp Setup 9.1.52.exe'}
powershell.exe : A value that is not valid (None) was specified for the inputFormat parameter. Valid values are Text and Xml.
At line:1 char:1
+ powershell.exe -NoProfile -NonInteractive -InputFormat None -Command ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], ParameterBindingException
+ FullyQualifiedErrorId : IncorrectValueForFormatParameter
Seems to be that valid inputs are only Text
and Xml
. So I switched it to Text
. (I'm not entirely sure the implications of this)
powershell.exe -NoProfile -NonInteractive -InputFormat Text -Command {Get-AuthenticodeSignature -LiteralPath './electron/output/MyApp Setup 9.1.52.exe'}
Directory: C:\code\myapp\electron\output
SignerCertificate Status Path
----------------- ------ ----
CF4XXXXBB52627BXXXXXXXXDFDBAB67DA Valid MyApp Setup 9.1.52.exe
Testing the changes
To double check my results I edited node_modules/electron_updater/out/windowsExecutableCodeSignatureVerifier.js
directly as follows:
child_process_1.execFile("powershell.exe", [
"-NoProfile",
"-NonInteractive",
"-InputFormat",
"Text",
"-Command",
`{Get-AuthenticodeSignature -LiteralPath '${tempUpdateFile}'} | ConvertTo-Json -Compress | ForEach-Object { [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($_)) }`,
]
It does seem to not exhibit the issue anymore with my local testing but I'm unsure if this has introduced other issues. I'll update this as and when I test on a few different devices.
I'll escalate it up to a proper PR if it seems to be fixed wholesale.
Any update on this issue? Thank you!
Unfortunately this doesn't work, it resolves the powershell error but seems to cause publisher verification errors when checking the signatures later in the process.
I've also been running into this issue -- but intermittently, even on the same machine. I haven't really noticed a pattern but sometimes it'll resolve itself with a restart of the application in question. Worth noting it doesn't just happen on thin clients for me, reproducible intermittently on my lappy.
Powershell version I'm working with
PS C:\code> $PSVersionTable Name Value ---- ----- PSVersion 5.1.19041.2364 PSEdition Desktop PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...} BuildVersion 10.0.19041.2364 CLRVersion 4.0.30319.42000 WSManStackVersion 3.0 PSRemotingProtocolVersion 2.3 SerializationVersion 1.1.0.1
Attempt to run command manually
I attempted to run the command in it's entirety manually, and was immediately confronted with:
powershell.exe -NoProfile -NonInteractive -InputFormat None -Command Get-AuthenticodeSignature -LiteralPath './electron/output/MyApp Setup 9.1.52.exe' | ConvertTo-Json -Compress | ForEach-Object { [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($_)) } WyJHZXQtQXV0aGVudGljb2RlU2lnbmF0dXJlIDogQSBwb3NpdGlvbmFsIHBhcmFtZXRlciBjYW5ub3QgYmUgZm91bmQgdGhhdCBhY2NlcHRzIGFyZ3VtZW50IFx1MDAyN1NldHVwXHUwMDI3LiIsIkF0IGxpbmU6MSBjaGFyOjEiLCIrIEdldC1BdXRoZW50aWNvZGVTaWduYXR1cmUgLUxpdGVyYWxQYXRoIC4vZWxlY3Ryb24vb3V0cHV0L015QXBwIFNldHVwICAuLi4iLCIrIH5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fiIsIiAgICArIENhdGVnb3J5SW5mbyAgICAgICAgICA6IEludmFsaWRBcmd1bWVudDogKDopIFtHZXQtQXV0aGVudGljb2RlU2lnbmF0dXJlXSwgUGFyYW1ldGVyQmluZGluZ0V4Y2VwdGlvbiIsIiAgICArIEZ1bGx5UXVhbGlmaWVkRXJyb3JJZCA6IFBvc2l0aW9uYWxQYXJhbWV0ZXJOb3RGb3VuZCxNaWNyb3NvZnQuUG93ZXJTaGVsbC5Db21tYW5kcy5HZXRBdXRoZW50aWNvZGVTaWduYXR1cmVDb21tYW5kIiwiICJd
The base64 decodes to:
powershell.exe -NoProfile -NonInteractive -InputFormat None -Command Get-AuthenticodeSignature -LiteralPath './electron/output/MyApp Setup 9.1.52.exe' | ConvertTo-Json -Compress | ForEach-Object { [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($_)) } ["Get-AuthenticodeSignature : A positional parameter cannot be found that accepts argument \u0027Setup\u0027.","At line:1 char:1","+ Get-AuthenticodeSignature -LiteralPath ./electron/output/MyApp Setup ...","+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"," + CategoryInfo : InvalidArgument: (:) [Get-AuthenticodeSignature], ParameterBindingException"," + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.GetAuthenticodeSignatureCommand"," "]
This lead me down to reading a bit more about the
-Command
parameter. It looks like you can make use of it like:powershell.exe -Command { Get-Authenticode -LiteralPath './path/to/file with spaces.exe' }
Attempt to run with braces
powershell.exe -NoProfile -NonInteractive -InputFormat None -Command {Get-AuthenticodeSignature -LiteralPath './electron/output/MyApp Setup 9.1.52.exe'} powershell.exe : A value that is not valid (None) was specified for the inputFormat parameter. Valid values are Text and Xml. At line:1 char:1 + powershell.exe -NoProfile -NonInteractive -InputFormat None -Command ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [], ParameterBindingException + FullyQualifiedErrorId : IncorrectValueForFormatParameter
Seems to be that valid inputs are only
Text
andXml
. So I switched it toText
. (I'm not entirely sure the implications of this)powershell.exe -NoProfile -NonInteractive -InputFormat Text -Command {Get-AuthenticodeSignature -LiteralPath './electron/output/MyApp Setup 9.1.52.exe'} Directory: C:\code\myapp\electron\output SignerCertificate Status Path ----------------- ------ ---- CF4XXXXBB52627BXXXXXXXXDFDBAB67DA Valid MyApp Setup 9.1.52.exe
Testing the changes
To double check my results I edited
node_modules/electron_updater/out/windowsExecutableCodeSignatureVerifier.js
directly as follows:child_process_1.execFile("powershell.exe", [ "-NoProfile", "-NonInteractive", "-InputFormat", "Text", "-Command", `{Get-AuthenticodeSignature -LiteralPath '${tempUpdateFile}'} | ConvertTo-Json -Compress | ForEach-Object { [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($_)) }`, ]
It does seem to not exhibit the issue anymore with my local testing but I'm unsure if this has introduced other issues. I'll update this as and when I test on a few different devices.
I'll escalate it up to a proper PR if it seems to be fixed wholesale.
@M3ales You can replace the PowerShell with a native verify signature module to resolve all powershell problems.
https://github.com/electron-userland/electron-builder/pull/7337
This issue might be fixed by https://github.com/electron-userland/electron-builder/pull/7230 which is included since [email protected]
I saw this issue with the recently-released electron-updater 6.1.0
We are also still seeing this issue in 6.0.0
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 30 days.
Still issue: 6.1.4
Maybe need add some delay for check...
Duplicate issue #7051
Seeing this pretty frequently in 6.0.3. Haven't discovered any kind of pattern yet.
Error: Command failed: chcp 65001 >NUL & powershell.exe -NoProfile -NonInteractive -InputFormat None -Command "Get-AuthenticodeSignature -LiteralPath 'C:\Users\<user>\AppData\Local\<updater_dir>\pending\temp-<application_name>.exe' | ConvertTo...
+1
We're seeing it since updated from electron-updater
4.3.5
-> 5.2.1
. Right now we're at 6.1.4
and don't see any improvement.
Haven't figured out any pattern in it other than the fact that most of the cases (but not all of them) are happening when performing full download
due to auto-update performed between multiple releases (eg. 1.0.0
-> 1.3.0
skipping 1.2.0
and anything else in between) :
Cannot download differentially, fallback to full download: Error: Cannot download "<scrubbed>.exe.blockmap", status 404:
at ClientRequest.<anonymous> (C:\Program Files\<scrubbed>\resources\app.asar\node_modules\electron-updater\node_modules\builder-util-runtime\out\httpExecutor.js:204:34)
at ClientRequest.emit (node:events:525:35)
at ClientRequest.emit (node:domain:489:12)
at SimpleURLLoaderWrapper.<anonymous> (node:electron/js2c/browser_init:2:49128)
at SimpleURLLoaderWrapper.emit (node:events:513:28)
at SimpleURLLoaderWrapper.emit (node:domain:489:12)
Any chance it may get resolved soon? Happy to perform some tests if anyone figured out reproduction steps and/or fix
Also hitting this one. Even though I can't reproduce this myself (through the updater), this is what I get when I run this on my machine (both with Powershell 5 as well as 7)
➜ powershell.exe -NoProfile -NonInteractive -InputFormat None -Command Get-AuthenticodeSignature -LiteralPath 'C:/Users/<redacted>/AppData/Local/<redacted>-updater/pending/temp-<redacted>.exe'
Get-AuthenticodeSignature : A positional parameter cannot be found that accepts argument 'Setup'.
At line:1 char:1
+ Get-AuthenticodeSignature -LiteralPath C:/Users/<redacted>/AppData/Loca ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-AuthenticodeSignature], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.GetAuthenticodeSignatureComman
d
So, a different error than @M3ales got. I got a similar error when trying to release the app on a Powershell 7 terminal though (as described on https://github.com/electron-userland/electron-builder/issues/7729)
Could this info be useful? Any suggestions what could be done here?
Edit: The only way I'm able to run the above command is on the "Windows Command Prompt" (so, cmd, not powershell). I'm on Windows 11 and "cmd" version is:
C:\Users\<redacted>\ver
Microsoft Windows [Version 10.0.22621.2428]
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 30 days.
Hello,
We are also facing same issue on clients machines.
Issue is only replicable at client end. We, developers of our organization have ADMIN access to their allotted machines, so we are not facing this issue, hence its becoming impossible to replicate this issue at our end.
And our clients have machines are in which they have non-admin permissions.
When they are trying to update our application, they are getting this error -
Its been very long time, still we haven't found any solution yet. Is anyone else facing same issue?
Hey there!
We've managed to create a setup for which it's failing with 100% repeatability.
Context
It was purely coincidental as it surfaced while we were working on e2e tests for auto-update. Why do we bother to do this? Well, it's crucial for us to ensure that our app can auto-update without any issues. The challenge is, you wouldn't discover it's faulty until it's already on users' machines, and you released a newer version. From that point, there's no turning back other than asking people to install it manually.
How to reproduce
Create a GitHub Action which should run your app assuming it should auto-update. You most likely need to point it to a different update source where you host the test version eg v99.0.0-e2e
name: E2E auto-update
on:
workflow_call:
env:
NPM_READ_TOKEN: ${{ secrets.GITHUB_TOKEN }}
jobs:
windows:
runs-on: windows-latest
steps:
- uses: actions/checkout@v3
- uses: actions/download-artifact@v3
with:
name: windows-binary
path: installer
- name: List downloaded installer
run: ls -R installer
- name: Find installer name
run: |
$EXE_INSTALLER = Get-ChildItem -Path 'installer' -Filter '*.exe' -Recurse | ForEach-Object { $_.FullName }
echo "EXE_INSTALLER=$EXE_INSTALLER" >> $env:GITHUB_ENV
- name: Test Get-AuthenticodeSignature on cmd
shell: cmd
run: powershell -Command "Get-AuthenticodeSignature -LiteralPath '${{ env.EXE_INSTALLER }}' | ConvertTo-Json -Compress"
- name: Test Get-AuthenticodeSignature on powershell
shell: powershell
run: Get-AuthenticodeSignature -LiteralPath '${{ env.EXE_INSTALLER }}' | ConvertTo-Json -Compress
- name: Check verifySignature cmd
shell: cmd
run: chcp 65001 >NUL & powershell.exe -NoProfile -NonInteractive -InputFormat None -Command "Get-AuthenticodeSignature -LiteralPath '${{ env.EXE_INSTALLER }}' | ConvertTo-Json -Compress"
- name: Run copy of electron-builder verifySignature
run: node ./verifySignature.js
verifySignature.js
script that is nothing more than extracted electron-builder windowsExecutableCodeSignatureVerifier.ts -> verifySignature which is causing problems
const { execFile } = require("child_process");
function verifySignature(unescapedTempUpdateFile) {
return new Promise((resolve, reject) => {
const tempUpdateFile = unescapedTempUpdateFile.replace(/'/g, "''");
execFile(
"chcp 65001 >NUL & powershell.exe",
[
"-NoProfile",
"-NonInteractive",
"-InputFormat",
"None",
"-Command",
`"Get-AuthenticodeSignature -LiteralPath '${tempUpdateFile}' | ConvertTo-Json -Compress"`,
],
{
shell: true,
timeout: 20 * 1000,
},
(error, stdout, stderr) => {
try {
if (error != null || stderr) {
console.log(error, stderr);
reject(error);
}
console.log(stdout);
resolve(JSON.parse(stdout));
} catch (e) {
reject(e);
}
},
);
});
}
function importModule() {
return new Promise((resolve, reject) => {
execFile(
"chcp 65001 >NUL & powershell.exe",
[
"-NoProfile",
"-NonInteractive",
"-InputFormat",
"None",
"-Command",
"Import-Module Microsoft.PowerShell.Security",
],
{
shell: true,
timeout: 20 * 1000,
},
(error, stdout, stderr) => {
try {
if (error != null || stderr) {
console.log(error, stderr);
reject(error);
}
console.log(stdout);
resolve(stdout);
} catch (e) {
reject(e);
}
},
);
});
}
(async () => {
try {
console.log("[verifySignature] starting...");
await importModule();
await verifySignature("path_to_installer_at_gh_worker.exe");
console.log("[verifySignature] done...");
process.exit(0);
} catch (error) {
console.error("[verifySignature] failed", error);
process.exit(1);
}
})();
Findings
verifySignature fails with error
Error: Command failed: chcp 65001 >NUL & powershell.exe -NoProfile -NonInteractive -InputFormat None -Command "Get-AuthenticodeSignature -LiteralPath PATH_TO_INSTALLER | ConvertTo-Json -Compress"
Get-AuthenticodeSignature : The 'Get-AuthenticodeSignature' command was found in the module
'Microsoft.PowerShell.Security', but the module could not be loaded. For more information, run 'Import-Module
[verifySignature] failed Error: Command failed: chcp 65001 >NUL & powershell.exe -NoProfile -NonInteractive -InputFormat None -Command "Get-AuthenticodeSignature -LiteralPath PATH_TO_INSTALLER | ConvertTo-Json -Compress"
Microsoft.PowerShell.Security'.
Get-AuthenticodeSignature : The 'Get-AuthenticodeSignature' command was found in the module
'Microsoft.PowerShell.Security', but the module could not be loaded. For more information, run 'Import-Module
Microsoft.PowerShell.Security'.
At line:1 char:1
+ Get-AuthenticodeSignature -LiteralPath PATH_TO_INSTALLER ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-AuthenticodeSignature:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CouldNotAutoloadMatchingModule
Given the error message:
Get-AuthenticodeSignature : The 'Get-AuthenticodeSignature' command was found in the module 'Microsoft.PowerShell.Security', but the module could not be loaded. For more information, run 'Import-Module Microsoft.PowerShell.Security'.
I did a test with manually importing it - see importModule()
Which fails with:
Command failed: chcp 65001 >NUL & powershell.exe -NoProfile -NonInteractive -InputFormat None -Command Import-Module Microsoft.PowerShell.Security
"System.Security.AccessControl.ObjectSecurity": The member AuditToString is already present.
Import-Module : The following error occurred while loading the extended type data file: Error in TypeData
"System.Security.AccessControl.ObjectSecurity": The member AuditToString is already present.
Error in TypeData "System.Security.AccessControl.ObjectSecurity": The member AccessToString is already present.
Error in TypeData "System.Security.AccessControl.ObjectSecurity": The member Sddl is already present.
Error in TypeData "System.Security.AccessControl.ObjectSecurity": The member Access is already present.
Error in TypeData "System.Security.AccessControl.ObjectSecurity": The member Group is already present.
Error in TypeData "System.Security.AccessControl.ObjectSecurity": The member Owner is already present.
Error in TypeData "System.Security.AccessControl.ObjectSecurity": The member Path is already present.
At line:1 char:1
+ Import-Module Microsoft.PowerShell.Security
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [Import-Module], RuntimeException
+ FullyQualifiedErrorId : FormatXmlUpdateException,Microsoft.PowerShell.Commands.ImportModuleCommand
}
⚠️
What's interesting, when running the verifySignature
command directly in the workflow - it does not fail.
It fails only when it's executed by node script which later on runs:
execFile("chcp 65001 >NUL & powershell.exe")
I did a bit of research and found the following threads:
- https://github.com/PowerShell/PowerShell/issues/18530
- https://stackoverflow.com/a/74869395
However, with hours of try-and-error, I didn't manage to make it pass
Impact
As of today, we see ~40k of these errors a month which varies depending on how often we release. Due to this error, we can't auto-update app for certain group of users, hence they either are stuck at a version they already have or need to install it manually
Hello @piotr-chowaniec, Yes, you are right. We were also facing the same issue on some clients machine. Below is the solution which we have applied, give it try at your end.
import win-verify-signature package in your appUpdater file. then add below code where autoUpdater's verifyUpdaterCodeSignature will get replace,
winVerifySign = require("win-verify-signature")
// Verify application after update downloaded successfully
autoUpdater.verifyUpdateCodeSignature = (publisherName, path) => {
log.info('autoUpdaterService.ts::verifyUpdateCodeSignature::starting verification::-', path, publisherName);
const result = winVerifySign.verifySignatureByPublishName(path, publisherName);
if (result.signed) return Promise.resolve(null);
log.info('autoUpdaterService.ts::verifyUpdateCodeSignature::225::-', result, result.message);
return Promise.resolve(result.message);
};
With this change, we are not facing same issue which we were facing earlier. Give it a try.
Same issue here.
Thank you @piotr-chowaniec for the very detailed writeup https://github.com/electron-userland/electron-builder/issues/7127#issuecomment-1931610372. I'll look into that
As @ShubhamSurya06 pointed out, there's an additional hook you can use to write your own code-verifying process or leverage a native module. https://www.electron.build/configuration/win#how-do-use-a-custom-verify-function-to-enable-nsis-signature-verification-alternatives-instead-of-powershell I would recommend the native module approach that leverages https://www.npmjs.com/package/win-verify-signature. It unfortunately can't be the default implementation of electron-builder though as there's no prebuild of the repo's native binaries, so it requires a Windows build machine to be integrated.
@piotr-chowaniec, quick Q. What happens for you if you set the first exec in your verifySignature.js to be
set "PSModulePath="; chcp 65001 >NUL & powershell.exe
The suggestion came from one of the docs/posts that you linked. I was receiving signature validation errors on the CI tests on a windows machine, but don't seem to be any longer with that change. https://github.com/electron-userland/electron-builder/actions/runs/7874990028/job/21485844914
● valid signature using DN
Command failed: chcp 65001 >NUL & powershell.exe -NoProfile -NonInteractive -InputFormat None -Command "Get-AuthenticodeSignature -LiteralPath 'C:\Users\RUNNER~1\AppData\Local\Temp\et-d8d6360ca6c99632f01b203b451e295c\t-8kecNa\1h\test-updater-app\pending\temp-TestApp-Setup-1.1.0.exe' | ConvertTo-Json -Compress"
Get-AuthenticodeSignature : The 'Get-AuthenticodeSignature' command was found in the module
'Microsoft.PowerShell.Security', but the module could not be loaded. For more information, run 'Import-Module
Microsoft.PowerShell.Security'.
At line:1 char:1
+ Get-AuthenticodeSignature -LiteralPath 'C:\Users\RUNNER~1\AppData\Loc ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-AuthenticodeSignature:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CouldNotAutoloadMatchingModule
Versus having set "PSModulePath="
in command
https://github.com/electron-userland/electron-builder/actions/runs/7874884860/job/21485522063
Signature tests are passing
I'm still trying to get WSL working in my Windows VM, getting other odd errors like chcp not found
and could use someone more experienced in Windows Development than I am to help here 🙃
@mmaietta Thanks for taking a look at it!
Following @ShubhamSurya06 advice I ended up with a custom verify signature implementation, but I took a bit more defensive approach trying to use win-verify-signature
only if the default one fails:
const customVerifyUpdateCodeSignature = async (publisherName: string[], path: string) => {
try {
const nsisUpdater = new NsisUpdater();
nsisUpdater.logger = autoUpdaterLogger;
const defaultSignatureVerification = nsisUpdater.verifyUpdateCodeSignature;
try {
const defaultStatus = await defaultSignatureVerification(publisherName, path);
if (defaultStatus !== null) {
throw new Error(defaultStatus);
}
return defaultStatus;
} catch (error) {
// If the default verification fails, we will try to verify the signature using win-verify-signature
}
const winVerifySign = await import("win-verify-signature");
const customStatus = winVerifySign.verifySignatureByPublishName(
path,
publisherName,
);
if (!customStatus.signed) {
return customStatus.message;
}
return null;
} catch (error) {
return "Error while verifying update code signature with custom verifyUpdateCodeSignature implementation.";
}
};
(autoUpdater as NsisUpdater).verifyUpdateCodeSignature = customVerifyUpdateCodeSignature;
Considering the fact we're building not only for windows. I had to add win-verify-signature
as an optionalDependency
so it can fail preinstall silently on macOS. Later on, it's imported only on Windows.
With that change, our tests work as expected. For now, I can't tell much about how it behaves in prod as we haven't released it yet.
@mmaietta speaking about set "PSModulePath=";
It works 🥳
Before posting a summary, I tried on my own with such command:
chcp 65001 >NUL & PSModulePath= & powershell.exe
But without success so I dropped it.
Regarding chpc
an Windows WSL - please correct me if I'm wrong but isn't chpc
available only on Windows hence you won't be able to access it on Windows WSL?
Wonderful news! I'll open a PR fixing that and getting more unit tests up and running.
Regarding chpc an Windows WSL - please correct me if I'm wrong but isn't chpc available only on Windows hence you won't be able to access it on Windows WSL?
You're right, that makes sense. It's working in powershell, but my pnpm Windows dev environment is completely wrecked outside of WSL, so I need to figure that out as well.
@mmaietta I'm a bit hesitant about whether that "small" change won't introduce regression issues. Do you have a way to test it heavily beforehand? If there is any issue caused by it, it'll be very hard to recover other than forcing people to manually install the app.
@piotr-chowaniec the windows signing verification tests were only running on linux for some reason, so the moment I added them to the windows-latest
github runner, the tests started failing and matching the error log you had provided previously. Now it passes successfully.
In the PR, the unit tests can validate up until the point of installing the app as on windows, the exe can't clean up the process due to the parent test process, and on linux, the rpm/deb changes require an authentication agent (for sudo) for the install to go through. I also tried adding the native signing method to the unit tests, but that caused test failures on mac even with win-verify-signature as an optional dependency.
That all being said, I'm am still trying to create a dev self-signed cert on windows to test further with, but it's proving to be quite difficult. electron-builder's create-self-signed-cert
CLI option isn't working for me and I can't tell why.
@piotr-chowaniec following up back here. I was able to get windows auto-update on a local minio server working on my windows Parallels VM with a self-signed certificate. I wasn't able to reproduce the original error here where signature verification fails on my VM though, only could via the CI unit tests on a windows-latest GH runner.
With my code changes in PR #8051, the update flow still works on my VM.
As with all electron-updater releases, this will be a next
pre-release. Please make sure to test with your own processes as usual