Refactor Windows installer and scripts to enhance user access and installation behavior
Some checks reported errors
farmcontrol/farmcontrol-ui/pipeline/head Something is wrong with the build of this commit

- Updated `package.json` to change installation scope from `perMachine` to `perUser`, allowing installations for standard users without admin rights.
- Modified `farmcontrol.nsi` to adjust installation directory and registry keys to use `HKCU` instead of `HKLM`, improving accessibility for non-admin users.
- Refined `installer.nsh` and related scripts to ensure proper handling of the farmcontrol URI handler and shortcuts, aligning with the new user access model.
- Removed references to the `grant-users-access.nsh` script, as user access permissions are now managed directly within the installer.
This commit is contained in:
Tom Butcher 2026-08-03 01:17:00 +01:00
parent 7d48ab6e85
commit 9bd581ee03
7 changed files with 81 additions and 67 deletions

View File

@ -245,12 +245,12 @@
"oneClick": false,
"allowToChangeInstallationDirectory": true,
"include": "scripts/installer.nsh",
"perMachine": true
"perMachine": false
},
"msiWrapped": {
"upgradeCode": "{735812DB-E33B-57A0-8FBC-5FC3155925AA}",
"perMachine": true,
"impersonate": false,
"perMachine": false,
"impersonate": true,
"wrappedInstallerArgs": "/S"
}
}

View File

@ -20,9 +20,9 @@
Name "Farm Control"
OutFile "${OUTFILE}"
InstallDir "$PROGRAMFILES64\Farm Control"
InstallDirRegKey HKLM "Software\Tom Butcher\Farm Control" "InstallDir"
RequestExecutionLevel admin
InstallDir "$LOCALAPPDATA\Programs\Farm Control"
InstallDirRegKey HKCU "Software\Tom Butcher\Farm Control" "InstallDir"
RequestExecutionLevel user
!define MUI_ABORTWARNING
@ -58,23 +58,21 @@ Section "Farm Control" SecMain
!insertmacro customInstall
WriteRegStr HKLM "Software\Tom Butcher\Farm Control" "InstallDir" $INSTDIR
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control" \
WriteRegStr HKCU "Software\Tom Butcher\Farm Control" "InstallDir" $INSTDIR
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control" \
"DisplayName" "Farm Control"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control" \
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control" \
"DisplayVersion" "${VERSION}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control" \
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control" \
"Publisher" "Tom Butcher"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control" \
WriteRegStr HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control" \
"UninstallString" "$INSTDIR\Uninstall.exe"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control" \
WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control" \
"NoModify" 1
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control" \
WriteRegDWORD HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control" \
"NoRepair" 1
WriteUninstaller "$INSTDIR\Uninstall.exe"
!insertmacro grantUsersInstallAccess
SectionEnd
Section "Uninstall"
@ -83,6 +81,6 @@ Section "Uninstall"
Delete "$INSTDIR\Uninstall.exe"
RMDir /r "$INSTDIR"
DeleteRegKey HKLM "Software\Tom Butcher\Farm Control"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control"
DeleteRegKey HKCU "Software\Tom Butcher\Farm Control"
DeleteRegKey HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control"
SectionEnd

View File

@ -5,16 +5,30 @@
!macro uninstallPreviousFarmControl
ClearErrors
ReadRegStr $R0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control" "UninstallString"
ReadRegStr $R0 HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control" "UninstallString"
StrCmp $R0 "" check_install_dir run_uninstall
check_install_dir:
ReadRegStr $R0 HKCU "Software\Tom Butcher\Farm Control" "InstallDir"
StrCmp $R0 "" check_legacy_uninstall
StrCpy $R0 "$R0\Uninstall.exe"
Goto run_uninstall
check_legacy_uninstall:
ReadRegStr $R0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control" "UninstallString"
StrCmp $R0 "" check_legacy_install_dir run_uninstall
check_legacy_install_dir:
ReadRegStr $R0 HKLM "Software\Tom Butcher\Farm Control" "InstallDir"
StrCmp $R0 "" check_default_dir
StrCpy $R0 "$R0\Uninstall.exe"
Goto run_uninstall
check_default_dir:
StrCpy $R0 "$LOCALAPPDATA\Programs\Farm Control\Uninstall.exe"
IfFileExists $R0 run_uninstall check_legacy_default_dir
check_legacy_default_dir:
StrCpy $R0 "$PROGRAMFILES64\Farm Control\Uninstall.exe"
IfFileExists $R0 run_uninstall done_uninstall
@ -52,40 +66,38 @@
!macroend
!macro createDesktopShortcut
SetShellVarContext all
SetShellVarContext current
CreateShortCut "$DESKTOP\Farm Control.lnk" "$INSTDIR\bin\launcher.exe" "" "$INSTDIR\bin\launcher.exe" 0 SW_SHOWNORMAL "" "Farm Control"
!insertmacro fixShortcutWorkingDir "$DESKTOP\Farm Control.lnk" "$INSTDIR\bin"
!macroend
!macro createStartMenuShortcut
SetShellVarContext all
SetShellVarContext current
CreateDirectory "$SMPROGRAMS\Farm Control"
CreateShortCut "$SMPROGRAMS\Farm Control\Farm Control.lnk" "$INSTDIR\bin\launcher.exe" "" "$INSTDIR\bin\launcher.exe" 0 SW_SHOWNORMAL "" "Farm Control"
!insertmacro fixShortcutWorkingDir "$SMPROGRAMS\Farm Control\Farm Control.lnk" "$INSTDIR\bin"
!macroend
!macro removeDesktopShortcut
SetShellVarContext all
SetShellVarContext current
Delete "$DESKTOP\Farm Control.lnk"
!macroend
!macro removeStartMenuShortcut
SetShellVarContext all
SetShellVarContext current
Delete "$SMPROGRAMS\Farm Control\Farm Control.lnk"
RMDir "$SMPROGRAMS\Farm Control"
!macroend
!include "grant-users-access.nsh"
!macro customInstall
DetailPrint "Register farmcontrol URI Handler"
DeleteRegKey HKCR "farmcontrol"
WriteRegStr HKCR "farmcontrol" "" "URL:farmcontrol"
WriteRegStr HKCR "farmcontrol" "URL Protocol" ""
WriteRegStr HKCR "farmcontrol\DefaultIcon" "" "$INSTDIR\bin\launcher.exe"
WriteRegStr HKCR "farmcontrol\shell" "" ""
WriteRegStr HKCR "farmcontrol\shell\Open" "" ""
WriteRegStr HKCR "farmcontrol\shell\Open\command" "" '"$INSTDIR\bin\bun.exe" "$INSTDIR\bin\deeplink.js" "%1"'
DeleteRegKey HKCU "Software\Classes\farmcontrol"
WriteRegStr HKCU "Software\Classes\farmcontrol" "" "URL:farmcontrol"
WriteRegStr HKCU "Software\Classes\farmcontrol" "URL Protocol" ""
WriteRegStr HKCU "Software\Classes\farmcontrol\DefaultIcon" "" "$INSTDIR\bin\launcher.exe"
WriteRegStr HKCU "Software\Classes\farmcontrol\shell" "" ""
WriteRegStr HKCU "Software\Classes\farmcontrol\shell\Open" "" ""
WriteRegStr HKCU "Software\Classes\farmcontrol\shell\Open\command" "" '"$INSTDIR\bin\bun.exe" "$INSTDIR\bin\deeplink.js" "%1"'
DetailPrint "Creating shortcuts"
!insertmacro createDesktopShortcut
@ -95,5 +107,5 @@
!macro customUnInstall
!insertmacro removeDesktopShortcut
!insertmacro removeStartMenuShortcut
DeleteRegKey HKCR "farmcontrol"
DeleteRegKey HKCU "Software\Classes\farmcontrol"
!macroend

View File

@ -10,7 +10,7 @@
<Package
InstallerVersion="500"
Compressed="yes"
InstallScope="perMachine"
InstallScope="perUser"
Platform="x64" />
<Condition Message="Windows 7 and above is required"><![CDATA[Installed OR VersionNT >= 601]]></Condition>
@ -28,7 +28,7 @@
<Property Id="PREVIOUS_UNINSTALL_CMD">
<RegistrySearch
Id="PreviousUninstallCmdSearch"
Root="HKLM"
Root="HKCU"
Key="Software\Microsoft\Windows\CurrentVersion\Uninstall\Farm Control"
Name="UninstallString"
Type="raw" />
@ -37,7 +37,7 @@
<Property Id="PREVIOUS_INSTALL_DIR">
<RegistrySearch
Id="PreviousInstallDirSearch"
Root="HKLM"
Root="HKCU"
Key="Software\Tom Butcher\Farm Control"
Name="InstallDir"
Type="directory" />
@ -49,24 +49,24 @@
Id="KillFarmControl"
BinaryKey="WixCA"
DllEntry="WixQuietExec"
Execute="deferred"
Impersonate="no"
Execute="immediate"
Impersonate="yes"
Return="ignore" />
<CustomAction
Id="UninstallPrevious"
BinaryKey="WixCA"
DllEntry="WixQuietExec"
Execute="deferred"
Impersonate="no"
Execute="immediate"
Impersonate="yes"
Return="ignore" />
<CustomAction
Id="RunInstaller"
BinaryKey="WrappedExe"
ExeCommand="/S"
Execute="deferred"
Impersonate="no"
Execute="immediate"
Impersonate="yes"
Return="check" />
<Directory Id="TARGETDIR" Name="SourceDir">

View File

@ -48,7 +48,6 @@ function Get-DirectoryBytes {
$rootDir = Split-Path -Parent $PSScriptRoot
$nsiPath = Join-Path $rootDir "packaging/windows/farmcontrol.nsi"
$installerInclude = Join-Path $rootDir "packaging/windows/installer.nsh"
$grantUsersAccessInclude = Join-Path $rootDir "packaging/windows/grant-users-access.nsh"
$workDir = Join-Path $env:TEMP "farmcontrol-nsis"
$localInstallerName = "farmcontrol-installer.exe"
@ -81,7 +80,6 @@ if (-not (Test-Path $requiredDeeplinkScript)) {
Copy-Item -LiteralPath $nsiPath -Destination (Join-Path $workDir "farmcontrol.nsi")
Copy-Item -LiteralPath $installerInclude -Destination (Join-Path $workDir "installer.nsh")
Copy-Item -LiteralPath $grantUsersAccessInclude -Destination (Join-Path $workDir "grant-users-access.nsh")
$iconPath = Join-Path $rootDir "assets\installer.ico"
if (Test-Path $iconPath) {

View File

@ -1,14 +1,10 @@
!include "packaging\windows\grant-users-access.nsh"
!macro customInstall
!insertmacro grantUsersInstallAccess
!macro customInstall
DetailPrint "Register farmcontrol URI Handler"
DeleteRegKey HKCR "farmcontrol"
WriteRegStr HKCR "farmcontrol" "" "URL:farmcontrol"
WriteRegStr HKCR "farmcontrol" "URL Protocol" ""
WriteRegStr HKCR "farmcontrol\DefaultIcon" "" "$INSTDIR\${APP_EXECUTABLE_FILENAME}"
WriteRegStr HKCR "farmcontrol\shell" "" ""
WriteRegStr HKCR "farmcontrol\shell\Open" "" ""
WriteRegStr HKCR "farmcontrol\shell\Open\command" "" "$INSTDIR\${APP_EXECUTABLE_FILENAME} %1"
DeleteRegKey HKCU "Software\Classes\farmcontrol"
WriteRegStr HKCU "Software\Classes\farmcontrol" "" "URL:farmcontrol"
WriteRegStr HKCU "Software\Classes\farmcontrol" "URL Protocol" ""
WriteRegStr HKCU "Software\Classes\farmcontrol\DefaultIcon" "" "$INSTDIR\${APP_EXECUTABLE_FILENAME}"
WriteRegStr HKCU "Software\Classes\farmcontrol\shell" "" ""
WriteRegStr HKCU "Software\Classes\farmcontrol\shell\Open" "" ""
WriteRegStr HKCU "Software\Classes\farmcontrol\shell\Open\command" "" "$INSTDIR\${APP_EXECUTABLE_FILENAME} %1"
!macroend

View File

@ -5,10 +5,13 @@ import path from 'node:path'
import process from 'node:process'
const MAC_APP_NAME = 'Farm Control.app'
const WINDOWS_INSTALL_DIR_KEY =
const WINDOWS_INSTALL_DIR_KEYS = [
'HKCU\\Software\\Tom Butcher\\Farm Control',
'HKLM\\Software\\Tom Butcher\\Farm Control'
]
const WINDOWS_DEFAULT_LAUNCHER = path.join(
process.env.ProgramFiles || 'C:\\Program Files',
process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local'),
'Programs',
'Farm Control',
'bin',
'launcher.exe'
@ -39,16 +42,23 @@ const findMacAppBundle = (startPath) => {
}
const readWindowsInstallDirFromRegistry = () => {
try {
const output = execSync(
`reg query ${quoteBatchArg(WINDOWS_INSTALL_DIR_KEY)} /v InstallDir`,
{ encoding: 'utf8', windowsHide: true }
)
const match = output.match(/InstallDir\s+REG_\w+\s+(.+)/i)
return match?.[1]?.trim() || null
} catch {
return null
for (const registryKey of WINDOWS_INSTALL_DIR_KEYS) {
try {
const output = execSync(
`reg query ${quoteBatchArg(registryKey)} /v InstallDir`,
{ encoding: 'utf8', windowsHide: true }
)
const match = output.match(/InstallDir\s+REG_\w+\s+(.+)/i)
const installDir = match?.[1]?.trim()
if (installDir) {
return installDir
}
} catch {
// Try the next registry key.
}
}
return null
}
export const resolveAppLaunchPath = () => {