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

MSI fails to install when deployed machine-wide via GPO #6508

Closed
aplum opened this issue Dec 17, 2021 · 3 comments · Fixed by #6514
Closed

MSI fails to install when deployed machine-wide via GPO #6508

aplum opened this issue Dec 17, 2021 · 3 comments · Fixed by #6514

Comments

@aplum
Copy link
Contributor

aplum commented Dec 17, 2021

  • Electron-Builder Version: 22.14.5
  • Node Version: 14.17.1
  • Electron Version: 16.0.2
  • Electron Type (current, beta, nightly): current
  • Target: MSI, Windows 10 x64

This is a duplicate of #5476, but it's closed and its title doesn't match the issue.

I'm going to add a lot of details in the hope that this will help someone else with their MSI debugging.

The problem

MSIs built by electron-builder fail to install when deployed machine-wide via GPO Computer Configuration. They work in every other context I tried (double-click, msiexec /i MyExampleApp.msi /qn, msiexec run as System account with psexec -s, msiexec run from Task Scheduler as System account triggered by startup or triggered in 2min then logging out and waiting), which is unfortunate because that makes testing a pain.

I enabled Windows Installer logging (setting to voicewarmupx), which logs to C:\Windows\temp\MSIrandomdigits.LOG. The failing MSI installation creates two log files after a reboot, which are mostly the same aside from a few lines.

Example logs

(Names of files and paths have been edited to remove company information.)

Example Event Viewer log entries:

Log Name: System
Level: Error
Source: Application Management Group Policy
Event ID: 101
User: SYSTEM
Description: The assignment of application My Example App from policy MyTestGpo failed.  The error was : %%1603

Log Name: System
Level: Error
Source: Application Management Group Policy
Event ID: 103
User: SYSTEM
Description: The removal of the assignment of application My Example App from policy MyTestGpo failed.  The error was : %%1603

Log Name: System
Level: Error
Source: Application Management Group Policy
Event ID: 108
User: SYSTEM
Description: Failed to apply changes to software installation settings.  Software changes could not be applied.  A previous log entry with details should exist.  The error was : %%1603

Log Name: System
Level: Warning
Source: Microsoft-Windows-GroupPolicy
Event ID: 1085
User: SYSTEM
Description: Windows failed to apply the Software Installation settings. Software Installation settings might have its own log file. Please click on the "More information" link.

Example MSI*.LOG file:

=== Verbose logging started: 2021-12-16  17:08:21  Build type: SHIP UNICODE 5.00.10011.00  Calling process: C:\WINDOWS\system32\svchost.exe ===
MSI (c) (04:5C) [17:08:21:504]: User policy value 'DisableRollback' is 0
MSI (c) (04:5C) [17:08:21:504]: Machine policy value 'DisableRollback' is 0
MSI (c) (04:5C) [17:08:21:504]: Note: 1: 2318 2:  
MSI (c) (04:5C) [17:08:21:504]: Note: 1: 2318 2:  
MSI (c) (04:5C) [17:08:21:504]: Note: 1: 1402 2: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Installer\Rollback\Scripts 3: 2 
MSI (c) (04:5C) [17:08:21:504]: Executing op: Header(Signature=1397708873,Version=500,Timestamp=1401979022,LangId=1033,Platform=589824,ScriptType=3,ScriptMajorVersion=21,ScriptMinorVersion=4,ScriptAttributes=0)
MSI (c) (04:5C) [17:08:21:504]: Executing op: ProductInfo(ProductKey={C4016754-4CC6-4E52-9ACA-16CF4E4263BA},ProductName=My Example App,PackageName=My Example App 1.0.0.msi,Language=1033,Version=16777216,Assignment=1,ObsoleteArg=0,ProductIcon=MyExampleAppIcon.exe,,PackageCode={E81268FB-F36C-44B1-B5AA-C5C6490D9B7D},,,InstanceType=0,LUASetting=0,RemoteURTInstalls=0,ProductDeploymentFlags=3)
MSI (c) (04:5C) [17:08:21:504]: Executing op: DialogInfo(Type=0,Argument=1033)
MSI (c) (04:5C) [17:08:21:504]: Executing op: DialogInfo(Type=1,Argument=My Example App)
MSI (c) (04:5C) [17:08:21:504]: Executing op: RollbackInfo(,RollbackAction=Rollback,RollbackDescription=Rolling back action:,RollbackTemplate=[1],CleanupAction=RollbackCleanup,CleanupDescription=Removing backup files,CleanupTemplate=File: [1])
MSI (c) (04:5C) [17:08:21:504]: Executing op: ActionStart(Name=CreateShortcuts,Description=Creating shortcuts,Template=Shortcut: [1])
MSI (c) (04:5C) [17:08:21:504]: Executing op: IconCreate(Icon=MyExampleAppIcon.exe,Data=BinaryData)
MSI (c) (04:5C) [17:08:21:504]: Scheduling file 'C:\WINDOWS\Installer\{C4016754-4CC6-4E52-9ACA-16CF4E4263BA}\MyExampleAppIcon.exe' for deletion during post-install cleanup (not post-reboot).
MSI (c) (04:5C) [17:08:21:504]: Executing op: SetTargetFolder(Folder=23\My Company\)
MSI (c) (04:5C) [17:08:21:504]: SHELL32::SHGetFolderPath returned: C:\ProgramData\Microsoft\Windows\Start Menu\Programs
MSI (c) (04:5C) [17:08:21:504]: Executing op: ShortcutCreate(Name=5cm8kaui|My Example App,Feature=ProductFeature,Component={AB2E00FC-6086-58D0-AC58-5B114C319824}[~]2,,,WorkingDir=C:\Program Files\My Company\My Example App\,Icon=MyExampleAppIcon.exe,,,,,,,,)
MSI (c) (04:5C) [17:08:21:504]: Executing op: ShortcutPropertyCreate(ShortcutName=5cm8kaui|My Example App,PropertyKey=System.AppUserModel.ID,PropVariantValue=com.mycompany.myexampleapp)
1: 2902 2: ixoShortcutPropertyCreate 
MSI (c) (04:5C) [17:08:21:504]: Note: 1: 2318 2:  
MSI (c) (04:5C) [17:08:21:504]: Executing op: Header(Signature=1397708873,Version=500,Timestamp=1401981195,LangId=1033,Platform=589824,ScriptType=2,ScriptMajorVersion=21,ScriptMinorVersion=4,ScriptAttributes=1)
MSI (c) (04:5C) [17:08:21:504]: Executing op: DialogInfo(Type=0,Argument=1033)
MSI (c) (04:5C) [17:08:21:504]: Executing op: DialogInfo(Type=1,Argument=My Example App)
MSI (c) (04:5C) [17:08:21:504]: Executing op: RollbackInfo(,RollbackAction=Rollback,RollbackDescription=Rolling back action:,RollbackTemplate=[1],CleanupAction=RollbackCleanup,CleanupDescription=Removing backup files,CleanupTemplate=File: [1])
MSI (c) (04:5C) [17:08:21:504]: Executing op: ActionStart(Name=CreateShortcuts,Description=Creating shortcuts,Template=Shortcut: [1])
MSI (c) (04:5C) [17:08:21:504]: Executing op: RegOpenKey(Root=-2147483646,Key=Software\Microsoft\Windows\CurrentVersion\Installer\TempPackages,,BinaryType=1,,)
MSI (c) (04:5C) [17:08:21:504]: Executing op: SetTargetFolder(Folder=23\My Company\)
MSI (c) (04:5C) [17:08:21:504]: SHELL32::SHGetFolderPath returned: C:\ProgramData\Microsoft\Windows\Start Menu\Programs
MSI (c) (04:5C) [17:08:21:504]: Executing op: ProductInfo(ProductKey={C4016754-4CC6-4E52-9ACA-16CF4E4263BA},ProductName=My Example App,PackageName=My Example App 1.0.0.msi,Language=1033,Version=16777216,Assignment=1,ObsoleteArg=0,ProductIcon=MyExampleAppIcon.exe,,PackageCode={E81268FB-F36C-44B1-B5AA-C5C6490D9B7D},,,InstanceType=0,LUASetting=0,RemoteURTInstalls=0,ProductDeploymentFlags=3)
MSI (c) (04:5C) [17:08:21:504]: Executing op: RegRemoveValue(Name=C:\WINDOWS\Installer\{C4016754-4CC6-4E52-9ACA-16CF4E4263BA}\MyExampleAppIcon.exe,Value=#1,)
MSI (c) (04:5C) [17:08:21:504]: Executing op: RegRemoveKey()
MSI (c) (04:5C) [17:08:21:504]: Note: 1: 1402 2: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Installer\TempPackages 3: 2 
MSI (c) (04:5C) [17:08:21:504]: Executing op: End(Checksum=0,ProgressTotalHDWord=0,ProgressTotalLDWord=0)
MSI (c) (04:5C) [17:08:21:504]: Error in rollback skipped.	Return: 5
MSI (c) (04:5C) [17:08:21:504]: Note: 1: 2318 2:  
MSI (c) (04:5C) [17:08:21:504]: DoAdvertiseScript is returning: 1603
=== Verbose logging stopped: 2021-12-16  17:08:21 ===

Debugging

The error seems to be this line in the log: 1: 2902 2: ixoShortcutPropertyCreate. This is right after it tries to create the shortcut property System.AppUserModel.ID on the Start Menu shortcut, which is why the solution mentioned in #5476 ("createStartMenuShortcut": false) works. So, I tried using Orca to create an MST that drops the MsiShortcutProperty table (or maybe just deletes the entry in it; I don't remember). Deploying that sort of worked - I think it installed the advertised shortcuts, but not the rest of the app. Not certain about this though, since I wasn't quite in my debugging flow yet. In any case, it's not a good solution since that property exists for a reason (see PR #2908 that adds it, and corresponding issue #2906).

Details about my debugging workflow

(Some of these steps might be overkill, but 🤷‍♂️)

I mostly reused the same GPO, but early on I was recreating it for each installation attempt. Just a simple GPO, applied to the OU with my Windows VM "MyClient" in it, security filtering set to only MyClient, and the only setting is a single package under Computer Configuration > Policies > Software Settings > Software installation. The package is "Assigned" with default settings, except sometimes with an MST applied.

For each attempted installation via GPO:

  1. Uninstall app (if already installed) via "Apps & Features" or msiexec /x MyExampleApp.msi /qn.
  2. Remove package from GPO (so GPO is empty).
  3. On the Domain Controller, ensure all other DCs are in sync with repadmin /syncall /AdeP (in case MyClient is using a different DC).
  4. On MyClient, gpupdate /force /sync and restart.
  5. Open rsop.msc and ensure "My Example App" is not still showing up there.
  6. Add the MSI (with MST, if applicable) to the GPO.
  7. On DC, repadmin /syncall /AdeP.
  8. On MyClient, gpupdate /force /sync and restart.
  9. Inspect whatever I'm looking for (C:\Windows\temp\MSI*.LOG files, rsop.msc, Program Files, Start Menu shortcuts, etc.)

Next, I tried making an MST to change the shortcuts (Desktop and Start Menu, but only the latter is necessary) from advertised to non-advertised, by changing the Shortcut table's Target from ProductFeature to [#mainExecutable] (I'm not certain, but I think the only difference between non-advertised and advertised is the Target column using square brackets [ ] or not. See MS docs for what that means.). Success! It deploys! …But when I tried doing this straight from electron-builder by editing node_modules/app-builder-lib/out/targets/MsiTarget.js in my project by removing Advertise="yes" here (WiX docs), I discovered this causes some ICE validation errors and it fails to build (verified using Orca on my MST; same errors). Fixing these errors looks like a bit of a pain.

On to the next solution: DISABLEADVTSHORTCUTS. Made an MST that adds DISABLEADVTSHORTCUTS=1 to the Property table. Success again! And it validates in Orca this time! Tried building from electron-builder by editing node_modules/app-builder-lib/templates/msi/template.xml to add <Property Id="DISABLEADVTSHORTCUTS" Value="1"/> under this line, and that worked too!

(Btw, the value of the DISABLEADVTSHORTCUTS property apparently doesn't matter. I tried setting it to 0 instead of 1, and it had the same effect. If you want to create an MST to reverse this change, you must delete the property from the table.)

Solution

The best solution I've found is DISABLEADVTSHORTCUTS. It is technically a breaking change for anyone deploying using advertisement, but from what I've seen that's less common and those admins can easily reverse this change with a simple MST to delete the DISABLEADVTSHORTCUTS property. The alternative of not making any changes here and expecting admins to add the property themselves when their GPO deployment fails is much harder to diagnose for those admins.

I tested upgrading from a manually-installed MyApp v1.0.0 built using the current electron-builder to a GPO-deployed MyApp v1.0.1 built using a patched electron-builder, and that seems to have worked fine.

Of course, it would be even better if someone could find a solution that fixes this issue without disabling advertisement, but I think it might just be a bug in Windows. I haven't found a working MSI with both advertised shortcuts and the MsiShortcutProperty table to compare against.

Similar issues / research

I've found the following issues directly affected by this bug using electron-builder:

Slack's MSI has the MsiShortcutProperty table, but has non-advertised shortcuts. It works fine via GPO.

This Spiceworks post about Skype from 2014 might be the same issue. I looked at the archived MSIs from around 2014 with Orca, but didn't actually try installing any of them.

  • v6.22 has an MsiShortcutProperty for its Start Menu shortcut, but that shortcut is non-advertised.
  • v7.0 (released shortly before the Spiceworks post) has the MsiShortcutProperty System.AppUserModel.ID for both its Start Menu and Desktop shortcuts. Start Menu shortcut is non-advertised, Desktop shortcut is advertised. From my very limited research, I think setting System.AppUserModel.ID is only necessary for Start Menu shortcuts and has no effect on Desktop shortcuts.
  • In v7.8.32.102 they removed the MsiShortcutProperty for the Desktop Shortcut (which is still advertised; Start Menu is still non-advertised).
  • So it looks like Skype >= v7.0 && < v7.8.32.102 may have had the same issue, but I'm not inclined to try installing them.

I also looked at several other MSIs for popular software, but couldn't find any with both advertised shortcuts and the MsiShortcutProperty table. The only other one I found with advertised shortcuts was Acrobat Reader.

@mmaietta
Copy link
Collaborator

Thank you for the detailed write-up!
I'm not sure what the next steps are here though, is it just by adding <Property Id="DISABLEADVTSHORTCUTS" Value="1"/> to electron-builder? Do we need to worry about any adverse effects in doing so?

@aplum
Copy link
Contributor Author

aplum commented Dec 21, 2021

I believe the best option is to just add <Property Id="DISABLEADVTSHORTCUTS" Value="1"/> to electron-builder. I was intending to submit a PR doing that, but haven't gotten around to it yet.

The only adverse effect I'm aware of is for admins who are deploying these MSIs using advertisement – they'll need to apply an MST to reverse this change. (To be pedantic, we also lose self-healing/resiliency, but I doubt anyone will care.)

Since people might currently be using advertisement for user installs, I was considering using SetProperty to conditionally set DISABLEADVTSHORTCUTS for machine installs only. However, that seems more complicated to a) ensure it correctly detects machine-vs-user, b) debug if someone's having an issue, c) reverse it with an MST. So I thought simpler and predictable would be better here.

And since acquiring Orca is more effort than it should be, here's a PowerShell script to create the MST instead:

Create-Remove-DISABLEADVTSHORTCUTS-MST.ps1
<#
    .SYNOPSIS
    Creates a `Remove-DISABLEADVTSHORTCUTS.mst` beside the given MSI.

    .NOTES
    This script will produce one `Exception calling "InvokeMember"...` error if the MSI does not have the DISABLEADVTSHORTCUTS property.
#>

# Reference used while writing this script: https://www.alkanesolutions.co.uk/2014/10/30/powershell-windows-installer-msi-transforms-mst/

param (
    [Parameter(Mandatory=$true)] [string]$MsiPath
)

Set-StrictMode -Version 2.0

if (!(Test-Path $MsiPath)) {
    throw "File '$MsiPath' does not exist"
}

$MsiFolder = Split-Path $MsiPath -Parent -Resolve
$MsiFilename = Split-Path $MsiPath -Leaf
$Msi1Path = "$MsiFolder\$MsiFilename"
$Msi2Path = $Msi1Path + "_tempCopyForCreatingMst"
$MstPath = "$MsiFolder\Remove-DISABLEADVTSHORTCUTS.mst"

$MsiOpenDatabaseModeReadOnly = 0
$MsiOpenDatabaseModeTransact = 1
$MsiTransformErrorNone = 0
$MsiTransformValidationNone = 0

Copy-Item -Path $Msi1Path -Destination $Msi2Path
if (Test-Path $MstPath) {
    Remove-Item $MstPath
}

# Open original MSI in ReadOnly mode.
$WindowsInstaller = New-Object -ComObject WindowsInstaller.Installer
$Msi1 = $WindowsInstaller.GetType().InvokeMember(
    "OpenDatabase",
    "InvokeMethod",
    $null,
    $WindowsInstaller,
    @($Msi1Path, $MsiOpenDatabaseModeReadOnly)
)

# Open temp MSI in transact mode.
$Msi2 = $WindowsInstaller.GetType().InvokeMember(
    "OpenDatabase",
    "InvokeMethod",
    $null,
    $WindowsInstaller,
    @($Msi2Path, $MsiOpenDatabaseModeTransact)
)

# Delete DISABLEADVTSHORTCUTS from Property table.
$Query = "DELETE FROM ``Property`` WHERE ``Property`` = 'DISABLEADVTSHORTCUTS'"
$View = $Msi2.GetType().InvokeMember(
    "OpenView",
    "InvokeMethod",
    $null,
    $Msi2,
    ($Query)
)
$View.GetType().InvokeMember("Execute", "InvokeMethod", $null, $View, $null)
$View.GetType().InvokeMember("Close", "InvokeMethod", $null, $View, $null)
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($View) | Out-Null

# Commit the changes to the temp MSI.
$Msi2.GetType().InvokeMember("Commit", "InvokeMethod", $null, $Msi2, $null)

# Generate a transform (the difference between the original MSI and temp MSI).
$Msi2.GetType().InvokeMember(
    "GenerateTransform",
    "InvokeMethod",
    $null,
    $Msi2,
    @($Msi1, $MstPath)
) | Out-Null

# Create a Summary Information Stream for the MST.
$Msi2.GetType().InvokeMember(
    "CreateTransformSummaryInfo",
    "InvokeMethod",
    $null,
    $Msi2,
    @($Msi1, $MstPath, $MsiTransformErrorNone, $MsiTransformValidationNone)
) | Out-Null

# Release objects from memory.
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($Msi1) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($Msi2) | Out-Null
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($WindowsInstaller) | Out-Null

Remove-Item $Msi2Path

@DCzajkowski
Copy link

Regular deployments via GPO did not work for us with almost the same logs and same error codes as reported by @aplum.

We have added a part in our build script that modifies node_modules by appending <Property Id="DISABLEADVTSHORTCUTS" Value="1"/> under this line as suggested by @aplum. I've verified the table in Orca and the property was set successfully. I can confirm that deployments started to work as expected after this change. 🎉

Huge thanks to @aplum for their incredible investigation and solution finding on this issue. 👏

aplum added a commit to aplum/electron-builder that referenced this issue Dec 23, 2021
…ectron-userland#6508)

Disable advertised shortcuts, since MSIs with advertised Start Menu shortcuts that have a
Shortcut Property fail to install when deployed machine-wide via GPO, but work fine in all
other contexts. This might be a bug in Windows, or a misdiagnosis; see electron-userland#6508 for more details.

Closes electron-userland#6508
BREAKING CHANGE: Admins using advertisement must apply an MST to re-enable it. See electron-userland#6508.
aplum added a commit to aplum/electron-builder that referenced this issue Dec 23, 2021
Disable advertised shortcuts, since MSIs with advertised Start Menu shortcuts that have a
Shortcut Property fail to install when deployed machine-wide via GPO, but work fine in all
other contexts. This might be a bug in Windows, or a misdiagnosis; see electron-userland#6508 for more details.

Closes electron-userland#6508
BREAKING CHANGE: Admins using advertisement must apply an MST to re-enable it. See electron-userland#6508.
mmaietta pushed a commit that referenced this issue Jan 7, 2022
)

* fix(msi): MSI fails to install when deployed machine-wide via GPO
Disable advertised shortcuts, since MSIs with advertised Start Menu shortcuts that have a
Shortcut Property fails to install when deployed machine-wide via GPO but works fine in all
other contexts. This might be a bug in Windows or a misdiagnosis; see #6508 for more details.
Closes #6508
BREAKING CHANGE: Admins using advertisement must apply an MST to re-enable it. See #6508.
mergify bot pushed a commit to enso-org/enso that referenced this issue Apr 21, 2022
[ci no changelog needed]

[Task link](https://www.pivotaltracker.com/story/show/181944234).

It fixes the build issue on Mac OS 12.3.1 that is caused by removed `/usr/bin/python` executable.

Also applied `enso-formatter` to the sources.

# Important Notes
We're basically updating for one major `electron-builder` release - from `v22` to `v23`. I didn't spot anything in the changelog that could affect us. See features + breaking changes excerpt:

```
Features:

- feat(msi): add fileAssociation support for MSI target (electron-userland/electron-builder#6530)
- feat(mac): ElectronAsarIntegrity in electron@15 - See: electron/electron#30667 (electron-userland/electron-builder#6506 electron-userland/electron-builder#6507)
- feat(snap): add lzo to Snap compression options (also as new default) (electron-userland/electron-builder#6201) Upgraded app-builder-bin dependency required newer version of Go
- feat(msi): support assisted installer for MSI target (electron-userland/electron-builder#6550)

Breaking changes:

- Removing Bintray support since it was sunset. Ref: https://jfrog.com/blog/into-the-sunset-bintray-jcenter-gocenter-and-chartcenter/
- Fail-fast for windows signature verification failures. Adding -LiteralPath to update file path to disregard injected wildcards
- Force strip path separators for backslashes on Windows during update process
- Authentication for local mac squirrel update server
- Disabled advertised shortcuts, since MSIs with advertised Start Menu shortcuts that have a
Shortcut Property fails to install when deployed machine-wide via GPO but works fine in all
other contexts. Admins using advertisement must apply an MST to re-enable it. See electron-userland/electron-builder#6508.
- Removing optional NSIS icon ID from config and generating it automatically to synchronize IDs with Advertised Shortcuts and future features
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants