0

I'm trying to automate the set up of an environment in Windows. As a part of this I'd like to ensure that a specific install of Java 11.0.11 appears first in the Path windows environment variable. I'm currently using NSIS to create an install and can do everything I want to except ensure that my version of Java appears first in the Path variable. It sounds like NSIS does not allow this purposefully as in a typical use case you would want to prevent installs from breaking other installed products by forcing a version change like this (I'm speculating here). See the comments in the accepted answer here: How to use NSIS EnVar plug in to edit path?.

How can I create an automated process (e.g. script) that will put my version of Java first in the Path variable?

--- EDIT----------------------------

The accepted example works perfectly (and even includes an example use case at the bottom). A full working example of this is available at https://github.com/NACHC-CAD/nsis-examples/tree/main/examples/006-envvar-prepend.

John
  • 3,458
  • 4
  • 33
  • 54

1 Answers1

1

Adapted from this answer:

!include LogicLib.nsh
!include WinCore.nsh

Function RegPrependString
System::Store S
Pop $R0 ; append
Pop $R1 ; separator
Pop $R2 ; reg value
Pop $R3 ; reg path
Pop $R4 ; reg hkey
System::Call 'ADVAPI32::RegCreateKey(i$R4,tR3,*p.r1)i.r0'
${If} $0 = 0
    System::Call 'ADVAPI32::RegQueryValueEx(pr1,tR2,p0,*i.r2,p0,*i0r3)i.r0'
    ${If} $0 <> 0
        StrCpy $2 ${REG_SZ}
        StrCpy $3 0
    ${EndIf}
    StrLen $4 $R0
    StrCpy $8 $4
    StrLen $5 $R1
    IntOp $4 $4 + $5
    System::Call '*(&t$4s,&t$5,&t$3,&t1"")p.r9' $R0
    ${If} $0 = 0
    ${AndIf} $3 <> 0
      System::Call 'KERNEL32::lstrcat(t)(pr9,tR1)'
      IntOp $8 $8 + $5
    ${EndIf}
     IntOp $3 $3 + 1 ; For \0
    !if ${NSIS_CHAR_SIZE} > 1
      IntOp $3 $3 * ${NSIS_CHAR_SIZE}
      IntOp $8 $8 * ${NSIS_CHAR_SIZE}
    !endif
    IntPtrOp $8 $9 + $8
    System::Call 'ADVAPI32::RegQueryValueEx(pr1,tR2,p0,p0,pr8,*ir3)i.r0'
    ${If} $0 = 0
    ${OrIf} $0 = ${ERROR_FILE_NOT_FOUND}
        System::Call 'KERNEL32::lstrlen(t)(pr9)i.r0'
        IntOp $0 $0 + 1
        !if ${NSIS_CHAR_SIZE} > 1
            IntOp $0 $0 * ${NSIS_CHAR_SIZE}
        !endif
        System::Call 'ADVAPI32::RegSetValueEx(pr1,tR2,i0,ir2,pr9,ir0)i.r0'
    ${EndIf}
    System::Free $9
    System::Call 'ADVAPI32::RegCloseKey(pr1)'
${EndIf}
Push $0
System::Store L
FunctionEnd

Section

Push ${HKEY_CURRENT_USER}
Push "Environment"
Push "Path"
Push ";"
Push "c:\whatever"
Call RegPrependString
Pop $0
DetailPrint RegPrependString:Error=$0

SectionEnd 

This will always prepend, use EnVar::Check first to see if it's already there. Or if specifically at the front:

!include LogicLib.nsh
StrCpy $0 "c:\whatever"
ReadRegStr $1 HKCU "Environment" "Path"
StrCpy $1 "$1;"
StrCpy $0 "$0;"
StrLen $2 $0
StrCpy $1 $1 $2
${If} $1 == $0
    DetailPrint "Already prepended"
${Else}
    DetailPrint "Does not start with $0"
${EndIf}
Anders
  • 97,548
  • 12
  • 110
  • 164