Sign in to follow this  
Followers 0

UDF: _ExpandEnvStrings()

6 posts in this topic

Posted

I ran into some quirks while trying to control environmental variable expansion using the ExpandEnvStrings option, so I wrote a function to parse a string and return an expanded version of that string:

CODE

Func _ExpandEnvStrings($sInput)

Dim $aPart = StringSplit($sInput,'%')

If @error Then

SetError(1)

Return $sInput

EndIf

Dim $sOut = $aPart[1], $i = 2, $env = ''

;loop through the parts

While $i <= $aPart[0]

$env = EnvGet($aPart[$i])

If $env <> '' Then ;this part is an expandable environment variable

$sOut = $sOut & $env

$i = $i + 1

If $i <= $aPart[0] Then $sOut = $sOut & $aPart[$i]

ElseIf $aPart[$i] = '' Then ;a double-percent is used to force a single percent

$sOut = $sOut & '%'

$i = $i + 1

If $i <= $aPart[0] Then $sOut = $sOut & $aPart[$i]

Else ;this part is to be returned literally

$sOut = $sOut & '%' & $aPart[$i]

EndIf

$i = $i + 1

WEnd

Return $sOut

EndFunc

Example:

CODE

MsgBox(0, '', _ExpandEnvStrings('the file "%comspec%" is your command interpreter'), 5)

Share this post


Link to post
Share on other sites



Posted (edited)

Awesome function! :(

Just tried on this string.

"Path=%PATH% %%"

It even knew to take the two %'s literally.

Better than Opt("ExpandEnvStrings",1) becuase as you said it's not quirky and it does not affect all strings , only the ones you want.

Good Job! :(

P.S. I might make an _ExpandVariables func like this if you woundn't mind me using your idea.

Edited by SolidSnake

Share this post


Link to post
Share on other sites

Posted

Awesome function!  :( 

Just tried on this string.

"Path=%PATH% %%"

It even knew to take the two %'s literally.

Better than Opt("ExpandEnvStrings",1) becuase as you said it's not quirky and it does not affect all strings , only the ones you want.

Good Job! :(

P.S. I might make an _ExpandVariables func like this if you woundn't mind me using your idea.

<{POST_SNAPBACK}>

Yup, I tested it and tried to make it as close to "normal" (ie, as the command intrepreter would handle it) as I could. It successfully handles these tricky ones:

'%%path%%'

'%path%path%'

If you want to make a generic version (one that can use any character to "wrap" a variable), Change the header:

Func _ExpandEnvStrings($sInput, $Delim='%')

And then replace any '%' in the function with $Delim.

Replace the EnvGet with your own function, or I'd recommend using my table UDF to store your own variables.

Share this post


Link to post
Share on other sites

Posted

OK, I just added another feature to this routine. Now, in addition to looking for variables like %SystemDir%, it also looks for passes parameters, such as %1 %2 %3 etc. It takes an optional array of parameters (this array is assumed to be 1-base, like the $CmdLine built-in) and replaces %1 with element 1 of the array, %2 with the element 2, etc.

I am now working on wrapping it to find default commands for a particular filetype (so that I don't have to do a ShellExecute, I can actually look at the shell command and execute it myself)

Here's the code:

CODE

;Expands environment variables in a string, such as %COMSPEC% etc

;Also looks for %1 %2 %3 etc and substitutes from $aParameter, which is a 1-based 1-dimensional array

Func _ExpandEnvStrings($sInput, $aParameter=0)

Dim $aPart = StringSplit($sInput,'%')

If @error Then

SetError(1)

Return $sInput

EndIf

Dim $sOut = $aPart[1], $i = 2, $env = ''

;loop through the parts

While $i <= $aPart[0]

$env = EnvGet($aPart[$i])

If $env <> '' Then ;this part is an expandable environment variable

$sOut = $sOut & $env

$i = $i + 1

If $i <= $aPart[0] Then $sOut = $sOut & $aPart[$i]

ElseIf $aPart[$i] = '' Then ;a double-percent is used to force a single percent

$sOut = $sOut & '%'

$i = $i + 1

If $i <= $aPart[0] Then $sOut = $sOut & $aPart[$i]

Else ;this part may be literal, or may request a parameter

;first check for a parameter request

if Not UBound($aParameter,0) = 1 Then

If IsString($aParameter) Then

$aParameter = _ArrayCreate(1, $aParameter)

Else

Local $aParameter[1]

EndIf

EndIf

Local $j = 1, $num

While $j <= StringLen($aPart[$i]) And StringIsDigit(stringmid($aPart[$i], $j, 1))

$j = $j + 1

WEnd

$Num = StringLeft($aPart[$i], $j - 1)

If StringIsInt($num) Then ;parameter requested

If Int($num)<=$aParameter[0] Then ;allowed

$sOut = $sOut & $aParameter[int($num)] & StringTrimLeft($aPart[$i], $j - 1)

Else ;denied

$sOut = $sOut & StringTrimLeft($aPart[$i], $j - 1)

EndIf

Else ;return literal

$sOut = $sOut & '%' & $aPart[$i]

EndIf

EndIf

$i = $i + 1

WEnd

Return $sOut

EndFunc

Share this post


Link to post
Share on other sites

Posted (edited)

Here is another example using RegEx:

Func _ExpandEnvStrings($sExpr)
    Local Const $sPattern = "\%[\d\w()_]+\%"
    Local $a
    Local $sEnv
    Local $p1, $p2
    Local $sMatch
    Local $sMatchStripPct
    Local $sResult

    $a = StringRegExp ($sExpr, $sPattern, 3)
    $sResult = $sExpr

    If IsArray($a) Then
        For $sMatch In $a
            $p1 = StringInStr($sMatch, "%", 0, 1)
            $p2 = StringInStr($sMatch, "%", 0, 2)
            $sMatchStripPct = StringMid($sMatch, $p1+1, $p2-$p1-1)
            $sEnv = EnvGet($sMatchStripPct)
            If $sEnv = "" Then $sEnv = $sMatch
            $sResult = StringReplace($sResult, $sMatch, $sEnv, 1)
        Next
    EndIf

    Return $sResult
EndFunc
Edited by MAli

Share this post


Link to post
Share on other sites

Posted (edited)

MAli,

Oh come on! The post above yours dates from nearly 8 years ago. Please pay attention when you post - we do not approve of resurrecting threds this old as the language has changed so much since then. :naughty:

M23

P.S. Welcome to the AutoIt forum anyway - just be more careful in future. ;)

Edited by Melba23
Fixed BB tags

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Recently Browsing   0 members

    No registered users viewing this page.