AutoHotkey: Resolve Environment Variables in an Input String

As the last little hack session of the year I wanted to build a AutoHotkey function to resolve all occurences of environment variables within an input string.

Normally, this would be pretty straight forward. Use WScript.Shell and call the ExpandEnvironmentStrings function with the input string.

Given that VBScript – and to my understanding WSH – are being deprecated by Microsoft, this solution would run on borrowed time.

Therefore the somewhat more clunky but more “future-proof” method is to rely on locating the %-characters and trying to parse the contents inbetween as environment variables.

We need to be wary of regular %-characters within the string to prevent accidental destruction of string values or false-positives.

So a pure AutoHotkey implementation could look like this:

; Input string
str := "This is 100% true! -- C:\Users\%USERNAME%\test -- %LOCALAPPDATA% -- %"

; Marks the last position of a %-character
lastPos := 0

Loop
{
    ; Find the next environment variable in the string
    pos1 := InStr(str, "%", false, lastPos + 1)
    if !pos1
        break
    pos2 := InStr(str, "%", false, pos1 + 1)
    if !pos2
        break

    ; Extract the environment variable name
    envVar := SubStr(str, pos1 + 1, pos2 - pos1 - 1)
    
    ; Try to get the value of the environment variable
    envValue := EnvGet(envVar)

    ; If the environment variable exists, replace it in the string
    if envValue
        str := SubStr(str, 1, pos1 - 1) . envValue . SubStr(str, pos2 + 1)

    ; Set the last position to the end of the replaced string
    lastPos := pos1
}

; Show the result
MsgBox(str)

This is, however, not the best way to do it. Since Kernel32.dll is loaded automatically in AutoHotkey anyway, using the ExpandEnvironmentStringsW function seems like a much better option:

; Input string
str := "This is 100% true! -- C:\Users\%USERNAME%\test -- %LOCALAPPDATA% -- %"

; Allocate buffer for the expanded string
VarSetStrCapacity(&str2, 1024)

; Call ExpandEnvironmentStringsW to expand environment variables
DllCall("ExpandEnvironmentStringsW", "wstr", str, "wstr", &str2, "uint", 1024)

; Show the result
MsgBox(str2)

Why reinvent the wheel when the platform developer already provides a function for it?

Published by

tsukasa

The fool's herald.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.