Windows Release Suggestions

I would like to suggest some changes (better say bug fixes) related to Windows release.

  1. The installer does not run under SYSTEM account properly and publishing the software with Intune or SCCM is out of the question - installation breaks, something like “unable to create Avogadro .lnk shortcut on SYSTEM- users desktop”. The Uninstall info in registry is properly created, but the program itself is not installed in designated location (FYI - SYSTEM account is used by Intune/SCCM agents for remote-without-logging-in installations of software. It does not have any profile like ordinary admin or non-admin interactive user.):
  • Unable to resolve the path [C:\WINDOWS\system32\config\systemprofile\Desktop\Avogadro2.lnk] because it does not exist.
    Unable to resolve the path [C:\WINDOWS\system32\config\systemprofile\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Avogadro2\Uninstall.lnk] because it does not exist.
  1. Avogadro 2 is aimed to be as 64-bit application, I presume. But as I can see in Uninstall info in registry, it still resides in 32-bit (WOW6432Node) registry path:
  • [HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Avogadro2]
    "DisplayName"="Avogadro2"
    "UninstallString"="C:\\Program Files\\Avogadro2\\Uninstall.exe"
    "DisplayIcon"="C:\\Program Files\\Avogadro2\\bin\\avogadro2.exe"
    "Publisher"="Avogadro"
    "DisplayVersion"="2.0.0"
    "NoModify"=dword:00000001
    "NoRepair"=dword:00000001
    
    

PS: Sorry, with all the project/repository relocations I have not found any fixed/determined place to report those bugs.

None of the active developers are Windows admins. The NSIS installer template can be found here:

I certainly welcome suggestions and patches / pull requests. As far as I can tell, the NSI installer puts things into the 64-bit path.

Or are you talking about the Microsoft Store .msix version?

I am not much of NSIS scripting specialist, but ChatGPT suggested the the following changes. These changes look okay to me, but need testing from your side:

; Avogadro2 Installer Script
!include "MUI2.nsh"
!include "x64.nsh"

; Compressor
SetCompressor /SOLID lzma

; Basic Information
!define APP_NAME "Avogadro2"
!define APP_VERSION "@AvogadroApp_VERSION@"
!define APP_PUBLISHER "Avogadro"
!define APP_EXE "avogadro2.exe"
!define INSTALL_DIR "$PROGRAMFILES64\${APP_NAME}"

; General Settings
Name "${APP_NAME}"
OutFile "Avogadro2-Setup.exe"
InstallDir "${INSTALL_DIR}"
InstallDirRegKey HKLM "Software\${APP_NAME}" "InstallDir"
RequestExecutionLevel admin

; Force a per-machine installation context.
; Important for Intune/SYSTEM installs: without this, $SMPROGRAMS and $DESKTOP
; resolve to the current user profile instead of the All Users/Public locations.
Function .onInit
    SetShellVarContext all
    ${If} ${RunningX64}
        SetRegView 64
    ${Else}
        MessageBox MB_ICONSTOP|MB_OK "${APP_NAME} is a 64-bit application and requires 64-bit Windows."
        Abort
    ${EndIf}
FunctionEnd

Function un.onInit
    SetShellVarContext all
    ${If} ${RunningX64}
        SetRegView 64
    ${EndIf}
FunctionEnd

; Interface Settings
!define MUI_ABORTWARNING
!define MUI_ICON "share\icons\avogadro.ico"
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"

; Pages
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH

!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES

; Language Selection
!insertmacro MUI_LANGUAGE "English"
!insertmacro MUI_LANGUAGE "Arabic"
!insertmacro MUI_LANGUAGE "Basque"
!insertmacro MUI_LANGUAGE "Croatian"
!insertmacro MUI_LANGUAGE "Czech"
!insertmacro MUI_LANGUAGE "Danish"
!insertmacro MUI_LANGUAGE "Dutch"
!insertmacro MUI_LANGUAGE "Esperanto"
!insertmacro MUI_LANGUAGE "Estonian"
!insertmacro MUI_LANGUAGE "Finnish"
!insertmacro MUI_LANGUAGE "French"
!insertmacro MUI_LANGUAGE "German"
!insertmacro MUI_LANGUAGE "Greek"
!insertmacro MUI_LANGUAGE "Hindi"
!insertmacro MUI_LANGUAGE "Hungarian"
!insertmacro MUI_LANGUAGE "Hebrew"
!insertmacro MUI_LANGUAGE "Indonesian"
!insertmacro MUI_LANGUAGE "Italian"
!insertmacro MUI_LANGUAGE "Japanese"
!insertmacro MUI_LANGUAGE "Korean"
!insertmacro MUI_LANGUAGE "Malay"
!insertmacro MUI_LANGUAGE "Norwegian"
!insertmacro MUI_LANGUAGE "Polish"
!insertmacro MUI_LANGUAGE "Portuguese"
!insertmacro MUI_LANGUAGE "PortugueseBR"
!insertmacro MUI_LANGUAGE "Romanian"
!insertmacro MUI_LANGUAGE "Russian"
!insertmacro MUI_LANGUAGE "Serbian"
!insertmacro MUI_LANGUAGE "SimpChinese"
!insertmacro MUI_LANGUAGE "Slovak"
!insertmacro MUI_LANGUAGE "Slovenian"
!insertmacro MUI_LANGUAGE "Spanish"
!insertmacro MUI_LANGUAGE "Swedish"
!insertmacro MUI_LANGUAGE "Thai"
!insertmacro MUI_LANGUAGE "TradChinese"
!insertmacro MUI_LANGUAGE "Turkish"
!insertmacro MUI_LANGUAGE "Vietnamese"


; Function to register file associations
Function RegisterFileAssociation
    ; Parameters: $0 = file extension (e.g., ".xyz")
    ;            $1 = file type name (e.g., "XYZ.File")
    ;            $2 = description (e.g., "XYZ Chemical File")
    ;            $3 = icon file path
    Pop $3
    Pop $2
    Pop $1
    Pop $0

    WriteRegStr HKCR "$0" "" "$1"
    WriteRegStr HKCR "$1" "" "$2"
    WriteRegStr HKCR "$1\DefaultIcon" "" "$3"
    WriteRegStr HKCR "$1\shell" "" "open"
    WriteRegStr HKCR "$1\shell\open" "" "Open with ${APP_NAME}"
    WriteRegStr HKCR "$1\shell\open\command" "" '"$INSTDIR\bin\${APP_EXE}" "%1"'
FunctionEnd

; Function to unregister file associations
Function un.UnregisterFileAssociation
    ; Parameter: $0 = file extension
    Pop $0

    ReadRegStr $1 HKCR "$0" ""
    DeleteRegKey HKCR "$1"
    DeleteRegKey HKCR "$0"
FunctionEnd

; Installer Section
Section "Install"
    SetShellVarContext all
    SetRegView 64

    SetOutPath "$INSTDIR"

    ; Copy bin directory
    SetOutPath "$INSTDIR\bin"
    File /r "bin\*.*"

    ; Copy lib directory
    SetOutPath "$INSTDIR\lib"
    File /r "lib\*.*"

    ; Copy share directory (includes icon files)
    SetOutPath "$INSTDIR\share"
    File /r "share\*.*"

    ; Create uninstaller
    SetOutPath "$INSTDIR"
    WriteUninstaller "$INSTDIR\Uninstall.exe"

    ; Create Start Menu shortcuts
    CreateDirectory "$SMPROGRAMS\${APP_NAME}"
    CreateShortcut "$SMPROGRAMS\${APP_NAME}\${APP_NAME}.lnk" "$INSTDIR\bin\${APP_EXE}"
    CreateShortcut "$SMPROGRAMS\${APP_NAME}\Uninstall.lnk" "$INSTDIR\Uninstall.exe"

    ; Create Desktop shortcut
    CreateShortcut "$DESKTOP\${APP_NAME}.lnk" "$INSTDIR\bin\${APP_EXE}"

    ; Register file associations
    Push ".xyz"
    Push "Avogadro2.XYZ"
    Push "XYZ Chemical File"
    Push "$INSTDIR\share\avogadro2\doc.ico"
    Call RegisterFileAssociation

    Push ".pdb"
    Push "Avogadro2.PDB"
    Push "Protein Data Bank File"
    Push "$INSTDIR\share\avogadro2\doc.ico"
    Call RegisterFileAssociation

    Push ".cml"
    Push "Avogadro2.CML"
    Push "Chemical Markup Language File"
    Push "$INSTDIR\share\avogadro2\cml.ico"
    Call RegisterFileAssociation

    Push ".cjson"
    Push "Avogadro2.CJSON"
    Push "Chemical JSON File"
    Push "$INSTDIR\share\avogadro2\cjson.ico"
    Call RegisterFileAssociation

    Push ".mol"
    Push "Avogadro2.MOL"
    Push "MDL Molfile"
    Push "$INSTDIR\share\avogadro2\doc.ico"
    Call RegisterFileAssociation

    Push ".mol2"
    Push "Avogadro2.MOL2"
    Push "Tripos Mol2 File"
    Push "$INSTDIR\share\avogadro2\doc.ico"
    Call RegisterFileAssociation

    Push ".sdf"
    Push "Avogadro2.SDF"
    Push "Structure Data File"
    Push "$INSTDIR\share\avogadro2\doc.ico"
    Call RegisterFileAssociation

    ; Notify Windows of file association changes
    System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'

    ; Write registry keys for Add/Remove Programs
    WriteRegStr HKLM "Software\${APP_NAME}" "InstallDir" "$INSTDIR"
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "DisplayName" "${APP_NAME}"
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "UninstallString" '"$INSTDIR\Uninstall.exe"'
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "QuietUninstallString" '"$INSTDIR\Uninstall.exe" /S'
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "InstallLocation" "$INSTDIR"
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "DisplayIcon" '"$INSTDIR\bin\${APP_EXE}"'
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "Publisher" "${APP_PUBLISHER}"
    WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "DisplayVersion" "${APP_VERSION}"
    WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "NoModify" 1
    WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}" "NoRepair" 1

SectionEnd

; Uninstaller Section
Section "Uninstall"
    SetShellVarContext all
    ${If} ${RunningX64}
        SetRegView 64
    ${EndIf}

    ; Unregister file associations
    Push ".xyz"
    Call un.UnregisterFileAssociation

    Push ".pdb"
    Call un.UnregisterFileAssociation

    Push ".cml"
    Call un.UnregisterFileAssociation

    Push ".cjson"
    Call un.UnregisterFileAssociation

    Push ".mol"
    Call un.UnregisterFileAssociation

    Push ".mol2"
    Call un.UnregisterFileAssociation

    Push ".sdf"
    Call un.UnregisterFileAssociation

    ; Notify Windows of file association changes
    System::Call 'shell32.dll::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)'

    ; Remove files and directories
    RMDir /r "$INSTDIR\bin"
    RMDir /r "$INSTDIR\lib"
    RMDir /r "$INSTDIR\share"
    Delete "$INSTDIR\Uninstall.exe"
    RMDir "$INSTDIR"

    ; Remove shortcuts
    Delete "$SMPROGRAMS\${APP_NAME}\${APP_NAME}.lnk"
    Delete "$SMPROGRAMS\${APP_NAME}\Uninstall.lnk"
    RMDir "$SMPROGRAMS\${APP_NAME}"
    Delete "$DESKTOP\${APP_NAME}.lnk"

    ; Remove registry keys
    DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}"
    DeleteRegKey HKLM "Software\${APP_NAME}"

SectionEnd

; End of script

Well. Hope that helped.

PS: M$ Store still offers Avogadro 2 ver 1.102.xxx. Also after installation and when the program is started it reminds that it needs update to version 2.0.xxx. By the way agreeing to update leads not to Store-type installer (MSIX?), but ordinary EXE installer. Unfortunately no success with ver 2.0.xx

PPS: Please pay attention to that the setting SetShellVarContext all sets All Users context not the current users context. And SetRegView 64 sets the installer to switch to 64-bit registry view on 64-bit systems (without it, as default, it is still 32-bit view on 64-bit systems). Also AI suggested the Public Desktop shortcut creation hardening (although I see no point doing that, since Win11 already has the Desktop folder by default)

; Create Desktop shortcut
CreateDirectory "$DESKTOP"
CreateShortcut "$DESKTOP\${APP_NAME}.lnk" "$INSTDIR\bin\${APP_EXE}"

I’ll take a look. I’m not an NSIS expert either.

I don’t have a great way of pushing the Microsoft Store installer to wait for the appropriate update from the store. Hopefully that will get approved / updated soon. I had to resubmit because I guess I wasn’t clear enough that Avogadro can install Python for some features.