Setting Environment Variables: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
(→‎How To Use: linkfix)
(Added EnVar_plug-in link)
 
(12 intermediate revisions by 7 users not shown)
Line 1: Line 1:
{{PageAuthor|KiCHiK}}
{{PageAuthor|KiCHiK}}


== How To Use ==
<div style="background-color:#ff9999; color:#f00; border:2px solid #f00; padding:1em;"><font size="+1"><b>WARNING:</b> Strings longer than ${NSIS_MAX_STRLEN} will get truncated/corrupted. Do NOT use this function to update %PATH%, use the [[EnVar_plug-in]] instead.</font></div>
If you want to change the path environment variable see: [Path Manipulation].
 
 
== Setting Environmental Variables Temporarily ==
 
If you want to set an environment variable only for the installer process and its sub-processes use:
If you want to set an environment variable only for the installer process and its sub-processes use:
<highlight-nsis>System::Call 'Kernel32::SetEnvironmentVariableA(t, t) i("name", "value").r0'
<highlight-nsis>System::Call 'Kernel32::SetEnvironmentVariable(t, t)i ("name", "value").r0'
StrCmp $0 0 error
StrCmp $0 0 error
   ExecWait ProgThatReadsEnv.exe
   ExecWait ProgThatReadsEnv.exe
Line 11: Line 14:
   MessageBox MB_OK "Can't set environment variable"
   MessageBox MB_OK "Can't set environment variable"
done:</highlight-nsis>
done:</highlight-nsis>
To work around the NSIS_MAX_STRLEN limit when updating %Path% you can try [http://stackoverflow.com/a/32384667/3501 this function].
{{PageAuthor|turnec2}}
== Setting Environmental Variables Permanently ==
=== Exisiting Variables ===
The WriteEnvStr and un.DeleteEnvStr functions in this page have been obsoleted by EnvVarUpdate for path settings and other variables for path lists. For simple one-value environment variables however, the following does apply.
The un.DeleteEnvStr function can corrupt the contents of the PATH variable if the path being removed happens to be a subset of another path. For example, if PATH contains "C:\Windows\system32\wbem" and you remove "C:\Windows\system32" the result is "\wbem".  WriteEnvStr does not prevent the duplication of entries if the user runs the installer multiple times (and the installer code does not otherwise check for duplicates). However, these routines are retained for Windows 9x and ME in the next section since EnvVarUpdate does not support the update of variables in the autoexec.bat file.
See [[Environmental_Variables:_append%2C_prepend%2C_and_remove_entries]] for more information.
=== Your own variable ===
If you're setting / deleting your own environment variable MYVAR, rather than adjusting an existing one such as the PATH environment variable:
    ; include for some of the windows messages defines
    !include "winmessages.nsh"
    ; HKLM (all users) vs HKCU (current user) defines
    !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
    !define env_hkcu 'HKCU "Environment"'
    ; set variable for local machine
    WriteRegExpandStr ${env_hklm} MYVAR MYVAL
    ; and current user
    WriteRegExpandStr ${env_hkcu} MYVAR MYVAL
    ; make sure windows knows about the change
    SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
And for your uninstaller
    ; delete variable
    DeleteRegValue ${env_hklm} MYVAR
    DeleteRegValue ${env_hkcu} MYVAR
    ; make sure windows knows about the change
    SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
==== Function Code ====
[[http://nsis.sourceforge.net/Environmental_Variables:_append%2C_prepend%2C_and_remove_entries#Function_Code EnvVarUpdate function code]]
{{PageAuthor|KiCHiK}}
=== Functions for Windows 95, 98, and ME ===
If you want to set an environment variable that will stick for every other process and after reboots too you should use the functions below. To use them either save them as a .NSH file and include them in your script, or just copy paste them in your script. If you choose to save them as a .NSH file use:
If you want to set an environment variable that will stick for every other process and after reboots too you should use the functions below. To use them either save them as a .NSH file and include them in your script, or just copy paste them in your script. If you choose to save them as a .NSH file use:
<highlight-nsis>!include WriteEnvStr.nsh # or the name you chose
<highlight-nsis>!include WriteEnvStr.nsh # or the name you chose
Line 30: Line 77:
!include WriteEnvStr.nsh # or the name you chose</highlight-nsis>
!include WriteEnvStr.nsh # or the name you chose</highlight-nsis>


== The Functions ==
==== Function Code ====
'''Note:''' under Windows 9x a reboot is required for changes to take affect. The reboot flag will be set by these functions if a reboot is required.
'''Note:''' under Windows 9x a reboot is required for changes to take effect. The reboot flag will be set by these functions if a reboot is required.
'''Warning:''' this script will only work on NSIS 2.0b2 and above!
'''Warning:''' this script will only work on NSIS 2.0b2 and above!
<highlight-nsis>!ifndef _WriteEnvStr_nsh
<highlight-nsis>!ifndef _WriteEnvStr_nsh

Latest revision as of 23:36, 27 November 2018

Author: KiCHiK (talk, contrib)


WARNING: Strings longer than ${NSIS_MAX_STRLEN} will get truncated/corrupted. Do NOT use this function to update %PATH%, use the EnVar_plug-in instead.


Setting Environmental Variables Temporarily

If you want to set an environment variable only for the installer process and its sub-processes use:

System::Call 'Kernel32::SetEnvironmentVariable(t, t)i ("name", "value").r0'
StrCmp $0 0 error
  ExecWait ProgThatReadsEnv.exe
  Goto done
error:
  MessageBox MB_OK "Can't set environment variable"
done:

To work around the NSIS_MAX_STRLEN limit when updating %Path% you can try this function.

Author: turnec2 (talk, contrib)


Setting Environmental Variables Permanently

Exisiting Variables

The WriteEnvStr and un.DeleteEnvStr functions in this page have been obsoleted by EnvVarUpdate for path settings and other variables for path lists. For simple one-value environment variables however, the following does apply. The un.DeleteEnvStr function can corrupt the contents of the PATH variable if the path being removed happens to be a subset of another path. For example, if PATH contains "C:\Windows\system32\wbem" and you remove "C:\Windows\system32" the result is "\wbem". WriteEnvStr does not prevent the duplication of entries if the user runs the installer multiple times (and the installer code does not otherwise check for duplicates). However, these routines are retained for Windows 9x and ME in the next section since EnvVarUpdate does not support the update of variables in the autoexec.bat file.

See Environmental_Variables:_append,_prepend,_and_remove_entries for more information.

Your own variable

If you're setting / deleting your own environment variable MYVAR, rather than adjusting an existing one such as the PATH environment variable:

   ; include for some of the windows messages defines
   !include "winmessages.nsh"
   ; HKLM (all users) vs HKCU (current user) defines
   !define env_hklm 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
   !define env_hkcu 'HKCU "Environment"'
   ; set variable for local machine
   WriteRegExpandStr ${env_hklm} MYVAR MYVAL
   ; and current user
   WriteRegExpandStr ${env_hkcu} MYVAR MYVAL
   ; make sure windows knows about the change
   SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000

And for your uninstaller

   ; delete variable
   DeleteRegValue ${env_hklm} MYVAR
   DeleteRegValue ${env_hkcu} MYVAR
   ; make sure windows knows about the change
   SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000


Function Code

[EnvVarUpdate function code]

Author: KiCHiK (talk, contrib)


Functions for Windows 95, 98, and ME

If you want to set an environment variable that will stick for every other process and after reboots too you should use the functions below. To use them either save them as a .NSH file and include them in your script, or just copy paste them in your script. If you choose to save them as a .NSH file use:

!include WriteEnvStr.nsh # or the name you chose
# ...
Section "Add Env Var"
  Push MyEnvVar
  Push MyEnvVarValue
  Call WriteEnvStr
SectionEnd
# ...
Section uninstall
  # remove the variable
  Push MyEnvVar
  Call un.DeleteEnvStr
SectionEnd

If you want the environment variable to be available to all of the users using the computer define ALL_USERS before you include WriteEnvStr.nsh (or before the part of the script holding these functions if you didn't save it as a .NSH file). For example:

!define ALL_USERS
!include WriteEnvStr.nsh # or the name you chose

Function Code

Note: under Windows 9x a reboot is required for changes to take effect. The reboot flag will be set by these functions if a reboot is required. Warning: this script will only work on NSIS 2.0b2 and above!

!ifndef _WriteEnvStr_nsh
!define _WriteEnvStr_nsh
 
!include WinMessages.nsh
 
!ifndef WriteEnvStr_RegKey
  !ifdef ALL_USERS
    !define WriteEnvStr_RegKey \
       'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
  !else
    !define WriteEnvStr_RegKey 'HKCU "Environment"'
  !endif
!endif
 
#
# WriteEnvStr - Writes an environment variable
# Note: Win9x systems requires reboot
#
# Example:
#  Push "HOMEDIR"           # name
#  Push "C:\New Home Dir\"  # value
#  Call WriteEnvStr
#
Function WriteEnvStr
  Exch $1 ; $1 has environment variable value
  Exch
  Exch $0 ; $0 has environment variable name
  Push $2
 
  Call IsNT
  Pop $2
  StrCmp $2 1 WriteEnvStr_NT
    ; Not on NT
    StrCpy $2 $WINDIR 2 ; Copy drive of windows (c:)
    FileOpen $2 "$2\autoexec.bat" a
    FileSeek $2 0 END
    FileWrite $2 "$\r$\nSET $0=$1$\r$\n"
    FileClose $2
    SetRebootFlag true
    Goto WriteEnvStr_done
 
  WriteEnvStr_NT:
      WriteRegExpandStr ${WriteEnvStr_RegKey} $0 $1
      SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} \
        0 "STR:Environment" /TIMEOUT=5000
 
  WriteEnvStr_done:
    Pop $2
    Pop $0
    Pop $1
FunctionEnd
 
#
# un.DeleteEnvStr - Removes an environment variable
# Note: Win9x systems requires reboot
#
# Example:
#  Push "HOMEDIR"           # name
#  Call un.DeleteEnvStr
#
Function un.DeleteEnvStr
  Exch $0 ; $0 now has the name of the variable
  Push $1
  Push $2
  Push $3
  Push $4
  Push $5
 
  Call un.IsNT
  Pop $1
  StrCmp $1 1 DeleteEnvStr_NT
    ; Not on NT
    StrCpy $1 $WINDIR 2
    FileOpen $1 "$1\autoexec.bat" r
    GetTempFileName $4
    FileOpen $2 $4 w
    StrCpy $0 "SET $0="
    SetRebootFlag true
 
    DeleteEnvStr_dosLoop:
      FileRead $1 $3
      StrLen $5 $0
      StrCpy $5 $3 $5
      StrCmp $5 $0 DeleteEnvStr_dosLoop
      StrCmp $5 "" DeleteEnvStr_dosLoopEnd
      FileWrite $2 $3
      Goto DeleteEnvStr_dosLoop
 
    DeleteEnvStr_dosLoopEnd:
      FileClose $2
      FileClose $1
      StrCpy $1 $WINDIR 2
      Delete "$1\autoexec.bat"
      CopyFiles /SILENT $4 "$1\autoexec.bat"
      Delete $4
      Goto DeleteEnvStr_done
 
  DeleteEnvStr_NT:
    DeleteRegValue ${WriteEnvStr_RegKey} $0
    SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} \
      0 "STR:Environment" /TIMEOUT=5000
 
  DeleteEnvStr_done:
    Pop $5
    Pop $4
    Pop $3
    Pop $2
    Pop $1
    Pop $0
FunctionEnd
 
!ifndef IsNT_KiCHiK
!define IsNT_KiCHiK
 
#
# [un.]IsNT - Pushes 1 if running on NT, 0 if not
#
# Example:
#   Call IsNT
#   Pop $0
#   StrCmp $0 1 +3
#     MessageBox MB_OK "Not running on NT!"
#     Goto +2
#     MessageBox MB_OK "Running on NT!"
#
!macro IsNT UN
Function ${UN}IsNT
  Push $0
  ReadRegStr $0 HKLM \
    "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
  StrCmp $0 "" 0 IsNT_yes
  ; we are not NT.
  Pop $0
  Push 0
  Return
 
  IsNT_yes:
    ; NT!!!
    Pop $0
    Push 1
FunctionEnd
!macroend
!insertmacro IsNT ""
!insertmacro IsNT "un."
 
!endif ; IsNT_KiCHiK
 
!endif ; _WriteEnvStr_nsh