 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Tekl
Joined: 24 Sep 2004 Posts: 813 Location: Germany
|
Posted: Tue May 30, 2006 11:12 am Post subject: Transform, DerefEnv |
|
|
Hi,
I'm now missing that Transform, Deref does not expand environment variables anymore (due tue #NoEnv). Maybe there could be added a new command DerefEnv to Transform which also expands environment variables. Another solution could be EnvGet, *All. _________________ Tekl |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10467
|
Posted: Tue May 30, 2006 12:59 pm Post subject: |
|
|
Since #NoEnv operates at a low level, adding the ability to expand environment variables is somewhat difficult. In addition, I wouldn't expect such a feature to be used by very many people. For these reasons, perhaps some non-built-in solution can be found such as:
EnvGet, MyEnv1, MyEnv1
; ...etc.
Transform, OutputVar, Deref, ...
In other words, by fetching all your environment variables into identically-named normal variables (assuming you know all the names), you could then use Transform Deref as though #NoEnv weren't present.
Alternatively, perhaps you could use DllCall and GetEnvironmentStrings() to get the complete list of environment variables, then parse the list and use EnvGet on each one. |
|
| Back to top |
|
 |
Tekl
Joined: 24 Sep 2004 Posts: 813 Location: Germany
|
Posted: Tue May 30, 2006 5:14 pm Post subject: |
|
|
Hi Chris,
thanks for the idea with parsing the list of all envvars. I'll try that. _________________ Tekl |
|
| Back to top |
|
 |
Tekl
Joined: 24 Sep 2004 Posts: 813 Location: Germany
|
Posted: Wed May 31, 2006 8:15 am Post subject: |
|
|
Hi,
GetEnvironmentStrings just returns a numeric value. It's a pointer to the environment block, but how to read this environment block? _________________ Tekl |
|
| Back to top |
|
 |
corrupt
Joined: 29 Dec 2004 Posts: 2397
|
Posted: Wed May 31, 2006 8:35 am Post subject: |
|
|
You could use the CMDret function (no external .exe or .dll needed in this version) to retrieve the variables, values. Then, parse the output.
| Code: | MsgBox, % CMDret_RunReturn(comspec " /c set")
Return
CMDret_RunReturn(CMDin)
{
Global cmdretPID
idltm := A_TickCount + 20
CMsize = 1
VarSetCapacity(CMDout, 1, 32)
VarSetCapacity(sui,68, 0)
VarSetCapacity(pi, 16, 0)
VarSetCapacity(pa, 12, 0)
Loop, 4 {
DllCall("RtlFillMemory", UInt,&pa+A_Index-1, UInt,1, UChar,12 >> 8*A_Index-8)
DllCall("RtlFillMemory", UInt,&pa+8+A_Index-1, UInt,1, UChar,1 >> 8*A_Index-8)
}
IF (DllCall("CreatePipe", "UInt*",hRead, "UInt*",hWrite, "UInt",&pa, "Int",0) <> 0) {
Loop, 4
DllCall("RtlFillMemory", UInt,&sui+A_Index-1, UInt,1, UChar,68 >> 8*A_Index-8)
DllCall("GetStartupInfo", "UInt", &sui)
Loop, 4 {
DllCall("RtlFillMemory", UInt,&sui+44+A_Index-1, UInt,1, UChar,257 >> 8*A_Index-8)
DllCall("RtlFillMemory", UInt,&sui+60+A_Index-1, UInt,1, UChar,hWrite >> 8*A_Index-8)
DllCall("RtlFillMemory", UInt,&sui+64+A_Index-1, UInt,1, UChar,hWrite >> 8*A_Index-8)
DllCall("RtlFillMemory", UInt,&sui+48+A_Index-1, UInt,1, UChar,0 >> 8*A_Index-8)
}
IF (DllCall("CreateProcess", Int,0, Str,CMDin, Int,0, Int,0, Int,1, "UInt",0, Int,0, Int,0, UInt,&sui, UInt,&pi) <> 0) {
Loop, 4
cmdretPID += *(&pi+8+A_Index-1) << 8*A_Index-8
Loop {
idltm2 := A_TickCount - idltm
If (idltm2 < 10) {
DllCall("Sleep", Int, 10)
Continue
}
IF (DllCall("PeekNamedPipe", "uint", hRead, "uint", 0, "uint", 0, "uint", 0, "uint*", bSize, "uint", 0 ) <> 0 ) {
Process, Exist, %cmdretPID%
IF (ErrorLevel OR bSize > 0) {
IF (bSize > 0) {
VarSetCapacity(lpBuffer, bSize+1)
IF (DllCall("ReadFile", "UInt",hRead, "Str", lpBuffer, "Int",bSize, "UInt*",bRead, "Int",0) > 0) {
IF (bRead > 0) {
TRead += bRead
VarSetCapacity(CMcpy, (bRead+CMsize+1), 0)
CMcpy = a
DllCall("RtlMoveMemory", "UInt", &CMcpy, "UInt", &CMDout, "Int", CMsize)
DllCall("RtlMoveMemory", "UInt", &CMcpy+CMsize, "UInt", &lpBuffer, "Int", bRead)
CMsize += bRead
VarSetCapacity(CMDout, (CMsize + 1), 0)
CMDout=a
DllCall("RtlMoveMemory", "UInt", &CMDout, "UInt", &CMcpy, "Int", CMsize)
}
}
}
}
ELSE
break
}
ELSE
break
idltm := A_TickCount
}
}
cmdretPID=
DllCall("CloseHandle", UInt, hWrite)
DllCall("CloseHandle", UInt, hRead)
}
IF (StrLen(CMDout) < TRead) {
VarSetCapacity(CMcpy, TRead, 32)
TRead2 = %TRead%
Loop {
DllCall("RtlZeroMemory", "UInt", &CMcpy, Int, TRead)
NULLptr := StrLen(CMDout)
cpsize := Tread - NULLptr
DllCall("RtlMoveMemory", "UInt", &CMcpy, "UInt", (&CMDout + NULLptr + 2), "Int", (cpsize - 1))
DllCall("RtlZeroMemory", "UInt", (&CMDout + NULLptr), Int, cpsize)
DllCall("RtlMoveMemory", "UInt", (&CMDout + NULLptr), "UInt", &CMcpy, "Int", cpsize)
TRead2 --
IF (StrLen(CMDout) > TRead2)
break
}
}
StringTrimLeft, CMDout, CMDout, 1
Return, CMDout
}
|
|
|
| Back to top |
|
 |
Tekl
Joined: 24 Sep 2004 Posts: 813 Location: Germany
|
Posted: Wed May 31, 2006 9:02 am Post subject: |
|
|
Thanks,
well not the fastest way, but it works. Strange that Envget, %uh_EnvVar1%, %uh_EnvVar1% does not work.
| Code: |
uh_EnvVars := CMDret_RunReturn(comspec " /c set")
Loop, Parse, uh_EnvVars, `n, `r
{
StringSplit, uh_EnvVar, A_LoopField, =
If uh_EnvVar1 not in ComSpec,ProgramFiles
%uh_EnvVar1% = %uh_EnvVar2%%uh_EnvVar3%%uh_EnvVar4%%uh_EnvVar5%%uh_EnvVar6%%uh_EnvVar7%%uh_EnvVar8%%uh_EnvVar9%
}
|
_________________ Tekl |
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6721 Location: France (near Paris)
|
Posted: Wed May 31, 2006 10:06 am Post subject: |
|
|
Without using an external DLL:
| Code: | blockAddr := DllCall("GetEnvironmentStrings")
p := blockAddr
bGetVar := true
Loop
{
l := DllCall("lstrlen", "UInt", p)
; Skip first value
If (A_Index = 1)
{
p += l + 1
Continue ; Strange value...: "=::=::\"
}
VarSetCapacity(buffer, l+1, 0)
DllCall("lstrcpy", "Str", buffer, "UInt", p)
; Here, we have in buffer something like "var=value"
StringSplit v, buffer, =
; Avoid an error because these variables exist and are read-only
If (v1 != "ComSpec" && v1 != "ProgramFiles")
{
%v1% = %v2%
}
Tooltip (%A_Index%) %buffer% (%l% -> %p%)
Sleep 500
;~ result = %result%`n%buffer%
p += l + 1
If (*p = 0)
Break
}
Tooltip
DllCall("FreeEnvironmentStrings", "UInt", blockAddr)
MsgBox %windir%
Escape::ExitApp
|
_________________
vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2") |
|
| Back to top |
|
 |
Tekl
Joined: 24 Sep 2004 Posts: 813 Location: Germany
|
Posted: Wed May 31, 2006 12:33 pm Post subject: |
|
|
Hey! Thanks! That's great and quite faster. _________________ Tekl |
|
| Back to top |
|
 |
Androgen
Joined: 21 Feb 2006 Posts: 11 Location: Russia, Samara
|
Posted: Sun Aug 06, 2006 4:30 am Post subject: |
|
|
Sometimes this strange variable (=::=::\) is present, sometimes - is not present.
But such way always passes the first variable (even if it another)
| Code: | If (A_Index = 1)
{
p += l + 1
Continue ; Strange value...: "=::=::\"
} |
Therefore I have made in another way:
| Code: | Block_Pointer := DllCall( "GetEnvironmentStrings" )
String_Pointer := Block_Pointer
Loop
{
String_Length := DllCall( "lstrlen", UInt, String_Pointer )
If String_Length = 0
Break
VarSetCapacity( Cur_String, String_Length + 1, 0 )
DllCall( "lstrcpy", Str, Cur_String, UInt, String_Pointer )
String_Pointer := String_Pointer + String_Length + 1
If Cur_String = =S:=S:\
Continue
If NOT Env_List
Env_List = %Cur_String%
Else
Env_List = %Env_List%`n%Cur_String%
}
DllCall( "FreeEnvironmentStrings", UInt, Block_Pointer )
MsgBox, %Env_List% |
And I have not understood, what error we try to avoid? You could not explain me, PhiLho?
| Code: | ; Avoid an error because these variables exist and are read-only
If (v1 != "ComSpec" && v1 != "ProgramFiles")
{
%v1% = %v2%
} |
|
|
| Back to top |
|
 |
Tekl
Joined: 24 Sep 2004 Posts: 813 Location: Germany
|
Posted: Tue Aug 08, 2006 11:39 am Post subject: |
|
|
Hello,
btw. the routine crashes on systems which have environment-variables with characters, which arent allowed in autohotkey. Users reported they have variables like {32134:34234:32234:34324}. _________________ Tekl |
|
| Back to top |
|
 |
Androgen
Joined: 21 Feb 2006 Posts: 11 Location: Russia, Samara
|
Posted: Wed Aug 09, 2006 5:40 am Post subject: |
|
|
| Tekl wrote: | Hello,
btw. the routine crashes on systems which have environment-variables with characters, which arent allowed in autohotkey. Users reported they have variables like {32134:34234:32234:34324}. |
I add this environment variable and no crashes. Both the name and value of a variable - does not cause problems. Or I have not understood something?
| Code: | EnvSet, {32134:34234:32234:34324}, {32134:34234:32234:34324} ; ==> Test
Block_Pointer := DllCall( "GetEnvironmentStrings" )
String_Pointer := Block_Pointer
Loop
{
String_Length := DllCall( "lstrlen", UInt, String_Pointer )
If String_Length = 0
Break
VarSetCapacity( Cur_String, String_Length + 1, 0 )
DllCall( "lstrcpy", Str, Cur_String, UInt, String_Pointer )
String_Pointer := String_Pointer + String_Length + 1
If Cur_String = =S:=S:\
Continue
If NOT Env_List
Env_List = %Cur_String%
Else
Env_List = %Env_List%`n%Cur_String%
}
DllCall( "FreeEnvironmentStrings", UInt, Block_Pointer )
MsgBox, %Env_List% |
|
|
| Back to top |
|
 |
Tekl
Joined: 24 Sep 2004 Posts: 813 Location: Germany
|
Posted: Wed Aug 09, 2006 7:40 am Post subject: |
|
|
Hi,
the variable is set from outside and not inside a script. { and : are illegal characters for AutoHotkey but not for Windows. _________________ Tekl |
|
| Back to top |
|
 |
Androgen
Joined: 21 Feb 2006 Posts: 11 Location: Russia, Samara
|
Posted: Wed Aug 09, 2006 8:33 am Post subject: |
|
|
I do not see a difference between the set of a variable inside or outside of script. But well. I set this variable via standard applet, and script works well and in this case too.
(Windows XP with Service Pack 2) |
|
| Back to top |
|
 |
Tekl
Joined: 24 Sep 2004 Posts: 813 Location: Germany
|
Posted: Wed Aug 09, 2006 10:01 am Post subject: |
|
|
Ok, you're just listing the variables. But if you try to set them in AutoHotkey you'll get the error because it's not allowed to use:
{32134:34234:32234:34324} = anystring _________________ Tekl |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|