Skip to content
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

Auto update failed while executing the powershell command #7127

Closed
davidcgi opened this issue Sep 6, 2022 · 38 comments · Fixed by #8051
Closed

Auto update failed while executing the powershell command #7127

davidcgi opened this issue Sep 6, 2022 · 38 comments · Fixed by #8051

Comments

@davidcgi
Copy link

davidcgi commented Sep 6, 2022

  • 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.

@RMorgan-Evernote
Copy link

RMorgan-Evernote commented Sep 13, 2022

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

@gpronet
Copy link

gpronet commented Nov 1, 2022

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. (node:internal/child_process:451:11)
at Socket.emit (node:events:527:28)
at Pipe. (node:net:709:12)

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.

@apayet974
Copy link

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($_)) }

@quolpr
Copy link

quolpr commented Nov 17, 2022

We have the same issue, and not sure under what condition it happens. The code fails here

@ruthieballenger
Copy link

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.

@M3ales
Copy link

M3ales commented Dec 22, 2022

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.

@gujinku
Copy link

gujinku commented Jan 16, 2023

Any update on this issue? Thank you!

@M3ales
Copy link

M3ales commented Jan 18, 2023

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 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.

@beyondkmp
Copy link
Contributor

@M3ales You can replace the PowerShell with a native verify signature module to resolve all powershell problems.

#7337

@juwonjung-hdj
Copy link

This issue might be fixed by #7230 which is included since electron-updater@6.0.0-alpha.3

@NoahAndrews
Copy link
Contributor

I saw this issue with the recently-released electron-updater 6.1.0

@mfranzs
Copy link

mfranzs commented May 19, 2023

We are also still seeing this issue in 6.0.0

@github-actions
Copy link
Contributor

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.

@github-actions github-actions bot added the Stale label Jul 19, 2023
@panther7
Copy link
Contributor

Still issue: 6.1.4

Maybe need add some delay for check...

@panther7
Copy link
Contributor

Duplicate issue #7051

@github-actions github-actions bot removed the Stale label Aug 17, 2023
@seanssel
Copy link

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...

@piotr-chowaniec
Copy link

piotr-chowaniec commented Oct 18, 2023

+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

@rasgo-cc
Copy link

rasgo-cc commented Nov 10, 2023

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 #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]

Copy link
Contributor

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.

@github-actions github-actions bot added the Stale label Jan 10, 2024
@ShubhamSurya06
Copy link

ShubhamSurya06 commented Jan 15, 2024

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 -
image

Its been very long time, still we haven't found any solution yet.
Is anyone else facing same issue?

@github-actions github-actions bot removed the Stale label Jan 16, 2024
@piotr-chowaniec
Copy link

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:

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

@ShubhamSurya06
Copy link

ShubhamSurya06 commented Feb 8, 2024

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.

@Jaifroid
Copy link

Jaifroid commented Feb 9, 2024

Same issue here.

@mmaietta
Copy link
Collaborator

Thank you @piotr-chowaniec for the very detailed writeup #7127 (comment). 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.

@mmaietta
Copy link
Collaborator

@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 🙃

@piotr-chowaniec
Copy link

@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?

@mmaietta
Copy link
Collaborator

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.

@piotr-chowaniec
Copy link

@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.

@mmaietta
Copy link
Collaborator

@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.

@mmaietta
Copy link
Collaborator

@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

@piotr-chowaniec
Copy link

@mmaietta Thanks for your time investigating and fixing it! Definitely, I'll take a look and try 6.1.9 soon!

@reddybhavanish
Copy link

@mmaietta may i know which version of electron-updater might solve the above error ?
should i go with 6.1.9 or 6.2.1 ?

@mmaietta
Copy link
Collaborator

@reddybhavanish electron-updater@6.1.9 has the fix.

@reddybhavanish
Copy link

reddybhavanish commented Mar 14, 2024

Hi @mmaietta, i am still facing the error even after updating the electron-updater@6.1.9, electron-updater@6.2.1 and these are versions i am using "electron": "^26.2.0",
"electron-builder": "24.13.3",

image

@reddybhavanish
Copy link

@mmaietta any idea what might be causing the issue, the update is getting downloaded for the two consecutive latest version, facing the above error on the third attempt of testing auto update.

@mmaietta
Copy link
Collaborator

That sounds like it may be a separate issue? Can you confirm your flow? From what I understand, you're attempting 3 update flows? i.e. canceling the first two updates and retrying a third time

@reddybhavanish
Copy link

reddybhavanish commented Mar 15, 2024

@mmaietta I am using bitbucket as provider.
As part of testing autoupdater, I have pushed version(2.1.1) to bitbucket, the autoupdate worked.
Later pushed version(2.1.2), the autoupdate worked.
Later pushed version (2.1.3), this time autoupdate throwing below error while installing latest version (2.1.3)
(Error in auto-updater. Error: Command failed: set "PSModulePath="; chcp 65001 >NUL & powershell.exe -NoProfile -NonInteractive -InputFormat None -Command "Get-AuthenticodeSignature -LiteralPath 'C:\Users\Bhavanish\AppData\Local\xxxx\pending\temp-xxxx-setup-2.2.3.exe' | ConvertTo-Json -Compress").

Is it something problem with my system or any cache of dependencies ? Please enlighten me.

@beyondkmp
Copy link
Contributor

https://www.npmjs.com/package/win-verify-signature

There are prebuild binaries. https://github.com/beyondkmp/win-verify-signature/releases/tag/v1.7.0

Thank you @piotr-chowaniec for the very detailed writeup #7127 (comment). 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.

There are prebuild binaries in https://github.com/beyondkmp/win-verify-signature/releases/tag/v1.7.0.
If you are willing to make it the default, I can implement an automatic download of prebuilds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment