Function:
EnvVars
Description
- Replace environment variables in text.
- Convert legacy Pre-Vista paths to their Vista equivalent - when on a Vista comptuer.
- Specify user-defined "environment variables" to also replace.
DownloadEnvVars.zipRequirementsNone.
I wrote this function because I want to write programs that are truly portable. One annoyance with portability is that Vista uses different paths than the Pre-Vista paths. This causes problems for folders, such as All Users -> My Music. Pre-Vista you would specify "%AllUsersProfile%\Documents\My Music", making use of the AllUsersProfile
environment variable. On Vista, the equivalent folder is "C:\Users\Public\Music".
Since I have gotten use to
Free Commander which allows navigating using the Pre-Vista paths, even on a Vista computer, I thought I would write a function to expand on this idea, so that I could write programs that would have path portability.
FunctionEnvVars(String, ExtraEnvVars = "", CaseSensitive = false)Replace all
Environment variables with their associated value.
Supported environment variables: ALLUSERSPROFILE, APPDATA, COMPUTERNAME, COMMONPROGRAMFILES, COMMONPROGRAMFILES(X86), COMSPEC, PROGRAMFILES, PROGRAMFILES(X86), TMP, TEMP, USERNAME, USERPROFILE, WINDIR, and PUBLIC.
Additionally, converts legacy Pre-Vista paths to their Vista equivalent - when on a Vista computer. This allows for path portability. For example, below are examples of paths that are specified using legacy paths. On a Vista computer, these are converted to their Vista equivalent. This means, regardless if on a Vista computer or not, the paths work as they should.
ParametersString - String which has evironment variables and paths replaced
ExtraEnvVars - a list of any extra "environment variables" to convert. Must be in this form (one variable per line): Var = Value. All occurrances of "%Var%" in the inputted string would be replaced with "Value". See example at the end, for a demonstration.
CaseSensitive - whether the matching of environment variable names is case-sensitive.
ReturnValueThe inputted string with any environment variables and paths replaced.
CodeCode:
/*
Function to replace any environment variable references in a String
Additionally, converts from Pre-vista path to the Vista equivalent - when running a Vista computer
This allows using the same Path on a Vista and non-vista computer - path portability
*/
EnvVars(String, ExtraEnvVars = "", CaseSensitive = false)
{
/*
ExtraEnvVars is a list of any extra EnvVar replacements
ex.
ExtraEnvVars =
(LTrim Commments
Var1 = Value1
Var2 = Value2
*/
static EnvVars, VistaSpecific, Vista
if (!EnvVars)
{
;Note: Vista running in compatability mode isn't seen as Vista
Vista := A_OSVersion = "WIN_VISTA"
AllUsersProfile := Vista ? "C:\ProgramData" : "C:\Documents and Settings\All Users"
Public := Vista ? "C:\Users\Public" : ""
EnvGet, ProgramFilesX86, PROGRAMFILES(X86)
UserProfile := (Vista ? "C:\Users\" : "C:\Documents and Settings\") . A_UserName
EnvVars =
(LTrim Comments
ALLUSERSPROFILE = %AllUsersProfile%
APPDATA = %A_AppData%
COMPUTERNAME = %A_ComputerName%
COMMONPROGRAMFILES = C:\Program Files\Common Files
COMMONPROGRAMFILES(X86) = C:\Program Files (x86)\Common Files
COMSPEC = %ComSpec%
;HOMEDRIVE
;HOMEPATH
;PATH
;PATHEXT
PROGRAMFILES = %ProgramFiles%
PROGRAMFILES(X86) = %ProgramFilesX86%
;PROMPT
;SYSTEMDRIVE
;SystemRoot
TMP = %A_Temp%
TEMP = %A_Temp%
USERNAME = %A_UserName%
USERPROFILE = %UserProfile%
WINDIR = %A_WinDir%
PUBLIC = %PUBLIC%
)
;vista modifications for the basic paths
;ex. %USERPROFILE%\Start Menu -> %USERPROFILE%\AppData\Roaming\Microsoft\Windows\Start Menu
;replaced only on a Vista machine
VistaSpecific =
(LTrim Comments
C:\Documents and Settings = C:\Users
C:\Users\All Users = C:\ProgramData
C:\ProgramData\Application Data = C:\ProgramData
C:\ProgramData\Desktop = C:\Users\Public\Desktop
C:\ProgramData\Documents = C:\Users\Public\Documents
C:\ProgramData\Favorites = C:\Users\Public\Favorites
C:\ProgramData\Start Menu = C:\ProgramData\Microsoft\Windows\Start Menu
C:\ProgramData\Templates = C:\ProgramData\Microsoft\Windows\Templates
C:\Users\Default User = C:\Users\Default
)
}
oldStringCaseSense := A_StringCaseSense
if (CaseSensitive)
StringCaseSense, On
else if (A_StringCaseSense = "On")
StringCaseSense, Locale
UsedEnvVars := EnvVars . (ExtraEnvVars ? "`n" . ExtraEnvVars : "")
Loop, Parse, UsedEnvVars, `n
{
CurrentField := A_LoopField
if !RegExMatch(CurrentField, "^(?<Var>.*?)\s*+=\s*+(?<Value>.*)$", Env)
continue
if inStr(String, "%" EnvVar "%", CaseSensitive)
StringReplace, String, String, % "%" EnvVar "%", %EnvValue%, All
}
if (Vista)
{
Loop, Parse, VistaSpecific, `n
{
CurrentField := A_LoopField
if !RegExMatch(CurrentField, "^(?<Find>.*?)\s*+=\s*+(?<Replace>.*)$", Env)
continue
if inStr(String, EnvFind, CaseSensitive)
StringReplace, String, String, %EnvFind%, %EnvReplace%, All
}
;in the below replaces, any "valid" username is allowed
;a "valid" username is [\w ]++
String := RegExReplace(String, "i)C:\\Users\\(?!Public)([\w ]++)\\Application Data"
, "C:\Users\$1\AppData\Roaming", "", -1)
String := RegExReplace(String, "i)C:\\Users\\(?!Public)([\w ]++)\\"
. "(Cookies|Recent|SendTo|Start Menu|Templates)"
, "C:\Users\$1\AppData\Roaming\Microsoft\Windows\$2", "", -1)
String := RegExReplace(String, "i)C:\\Users\\(?!Public)([\w ]++)\\Local Settings"
, "C:\Users\$1\AppData\Local", "", -1)
String := RegExReplace(String, "i)C:\\Users\\(?!Public)([\w ]++)\\My Documents"
, "C:\Users\$1\Documents", "", -1)
String := RegExReplace(String, "i)C:\\Users\\([\w ]++)\\Documents\\"
. "My (Music|Pictures|Videos)"
, "C:\Users\$1\$2", "", -1)
String := RegExReplace(String, "i)C:\\Users\\(?!Public)([\w ]++)\\NetHood"
, "C:\Users\$1\AppData\Roaming\Microsoft\Windows\Network Shortcuts", "", -1)
String := RegExReplace(String, "i)C:\\Users\\(?!Public)([\w ]++)\\PrintHood"
, "C:\Users\$1\AppData\Roaming\Microsoft\Windows\Printer Shortcuts", "", -1)
}
StringCaseSense, %oldStringCaseSense%
return String
}
ExampleCode:
/*
These examples return the desired path for XP and Vista alike
When running on Vista, the paths are converted
*/
;the my documents folder
MsgBox, % "My Documents folder (1): `n`n"
. EnvVars("%UserProfile%\My Documents")
;another way to get the my documents folder
MsgBox, % "My Documents folder (2): `n`n"
. EnvVars("C:\Documents and Settings\%UserName%\My Documents")
;the All Users -> My Music folder
MsgBox, % "All Users -> My Music (1): `n`n"
. EnvVars("%AllUsersProfile%\Documents\My Music")
;another way to get the All Users -> My Music Folder
MsgBox, % "All Users -> My Music (2): `n`n"
. EnvVars("C:\Documents and Settings\All Users\Documents\My Music")
;Note: the passed string need not be just the directory
;the temp folder
MsgBox, % "Tmp directory: `n`n"
. EnvVars("The temp directory is: ""%TMP%""")
;allows specifying additional "environment variables" to use
SRC := "C:\SomeFolder"
DEST := "E:\A new folder"
File := "ThisFile.txt"
ExtraEnvVars =
(LTrim Comments
SRC = %SRC%
DEST = %DEST%
File = %File%
)
;an example "file transfer" notice
MsgBox, % "Example file transfor notice (1): `n`n"
. EnvVars("Copying ""%SRC%\%File%"" to ""%DEST%"".", ExtraEnvVars)
;a single double quote
quote = "
;or you could only pass the file to EnvVars
MsgBox, % "Example file transfor notice (2): `n`n"
. "Copying " quote . EnvVars("%SRC%\%File%", ExtraEnvVars) . quote
. " to " quote . EnvVars("%DEST%", ExtraEnvVars) . quote "."
;The start menu for a different user
;valid user names consist of letters, numbers, underscores, and spaces
;(I can modify this to allow additional valid characters, if needed)
MsgBox, % "Start Menu directory for SomeNoNamePerson: `n`n"
. EnvVars("C:\Documents and Settings\SomeNoNamePerson\Start Menu")
How to useExtract the zip's contents to a
library folder for automatic inclusion - StdLib compliant.
A copy of the above example can be found in the "Func Examples" folder.
Things to come- If AHK is running in compatability mode, Vista won't be seen as Vista - thus, Pre-Vista paths won't be converted. If this is not desired, I can modify this behavior.
- Currently a "valid" username consists of only letters, numbers, underscrores, and spaces - does this need to be expanded? See the last output in the example (the Start Menu), for an example of usage.
Download EnvVars function