mec02 Posted April 29, 2010 Posted April 29, 2010 Hi how can i detect the type of the logged on userprofile (local or roaming)? I need a solution for registry or file/folder so i can do it within an autoit-script. Thanks a lot. MEC
PsaltyDS Posted April 29, 2010 Posted April 29, 2010 (edited) You could check the $oUser.profilePath attribute. Edit: Even better, UserEnv.dll with GetProfileType function: Global Const $PT_LOCAL = 0 Global Const $PT_TEMPORARY = 1 Global Const $PT_ROAMING = 2 Global Const $PT_MANDATORY = 4 $iProfileType = 0 $aRET = DllCall("UserEnv.dll", "int", "GetProfileType", "DWORD*", $iProfileType) Switch $iProfileType Case $PT_LOCAL $sProfileType = "Local" Case $PT_TEMPORARY $sProfileType = "Temporary" Case $PT_ROAMING $sProfileType = "Roaming" Case $PT_MANDATORY $sProfileType = "Mandatory" EndSwitch ConsoleWrite("Your profile type is: " & $sProfileType & " (" & $iProfileType & ")" & @LF) Edited April 29, 2010 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
mec02 Posted April 30, 2010 Author Posted April 30, 2010 Hi it seems there is anything wrong. I get on local and roaming profiles the result "Roaming" because the variable $aRET is empty after dll-call. $iProfileType is always the same as set, it was not changed by the dll-call. I'm a rookie in calling dlls, can you help me? Should i check the $oUser.profilePath attribute? How can i do it? Thanks MEC
PsaltyDS Posted April 30, 2010 Posted April 30, 2010 (edited) Hmm, can't test because I don't have a roaming profile available here. Looks like the ByRef "DWORD*" didn't work. Try it this way, using a regular struct "ptr" and with some extra error handling added: Global Const $PT_LOCAL = 0 Global Const $PT_TEMPORARY = 1 Global Const $PT_ROAMING = 2 Global Const $PT_MANDATORY = 4 $tProfileType = DllStructCreate("dword ProfileType") DllStructSetData($tProfileType, "ProfileType", 0xFF) ; To verify it changes $pProfileType = DllStructGetPtr($tProfileType) $aRET = DllCall("UserEnv.dll", "int", "GetProfileType", "ptr", $pProfileType) If (@error = 0) And $aRET[0] Then $iProfileType = DllStructGetData($tProfileType, "ProfileType") Switch $iProfileType Case $PT_LOCAL $sProfileType = "Local" Case $PT_TEMPORARY $sProfileType = "Temporary" Case $PT_ROAMING $sProfileType = "Roaming" Case $PT_MANDATORY $sProfileType = "Mandatory" Case Else $sProfileType = "<INVALID>" EndSwitch ConsoleWrite("Your profile type is: " & $sProfileType & " (" & $iProfileType & ")" & @LF) Else ConsoleWrite("Error: @error = " & @error & "; $aRET[0] = " & $aRET[0] & @LF) EndIf Edit: Note $aRET is an array. DllCall() always returns an array. If you look into the DllCall() being made, you see return type is "int" but that "int" is stored in the $aRet array. So the error checking tests $aRet[0] to see what the return value was. Edited April 30, 2010 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
mec02 Posted May 3, 2010 Author Posted May 3, 2010 Hi PsaltyDS now it runs properly. Thank you very much. MEC
trancexx Posted May 3, 2010 Posted May 3, 2010 Hmm, can't test because I don't have a roaming profile available here. Looks like the ByRef "DWORD*" didn't work.It worked. Like this:$aRET = DllCall("userenv.dll", "bool", "GetProfileType", "dword*", 0) ;If @error Or Not $aRET[0] Then Return SetError(1, 0, "") $iProfileType = $aRET[1] ;<- this! ;... ♡♡♡ . eMyvnE
PsaltyDS Posted May 3, 2010 Posted May 3, 2010 (edited) It worked. Like this: $aRET = DllCall("userenv.dll", "bool", "GetProfileType", "dword*", 0) ;If @error Or Not $aRET[0] Then Return SetError(1, 0, "") $iProfileType = $aRET[1] ;<- this! ;... Hmm... That's cool if it works, but how do you arrive at that from the definition of the function? Quoting MSDN on GetProfileType: Parameters pdwFlags [out] DWORD Pointer to a variable that receives the profile type. If the function succeeds, it sets one or more of the following values: Making a value type ByRef in DllCall() doesn't usually mean it shows up in the returned array, does it? Edited May 3, 2010 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
trancexx Posted May 3, 2010 Posted May 3, 2010 Hmm... That's cool if it works, but how do you arrive at that from the definition of the function?Quoting MSDN on GetProfileType: Making a value type ByRef in DllCall() doesn't usually mean it shows up in the returned array, does it? Because if you read DllCall() function description (byref related):* - Add * to the end of another type to pass it by reference. For example "int*" passes a pointer to an "int" type.And then:Otherwise an array is returned that contains the function return value and a copy of all the parameters (including parameters that the function may have modified when passed by reference).You will see that's what's really wanted by the GetProfileType function. ♡♡♡ . eMyvnE
PsaltyDS Posted May 3, 2010 Posted May 3, 2010 And then: You will see that's what's really wanted by the GetProfileType function. Aha! I had the first part, but missed the connection to the second part. Thanks. Global Const $PT_LOCAL = 0 Global Const $PT_TEMPORARY = 1 Global Const $PT_ROAMING = 2 Global Const $PT_MANDATORY = 4 $aRET = DllCall("UserEnv.dll", "int", "GetProfileType", "DWORD*", -1) If (@error = 0) And $aRET[0] Then $iProfileType = $aRET[1] ; [1] = first parameter (modified ByRef) Switch $iProfileType Case $PT_LOCAL $sProfileType = "Local" Case $PT_TEMPORARY $sProfileType = "Temporary" Case $PT_ROAMING $sProfileType = "Roaming" Case $PT_MANDATORY $sProfileType = "Mandatory" Case Else $sProfileType = "<INVALID>" EndSwitch ConsoleWrite("Your profile type is: " & $sProfileType & " (" & $iProfileType & ")" & @LF) Else ConsoleWrite("Error: @error = " & @error & "; $aRET[0] = " & $aRET[0] & @LF) EndIf Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
trancexx Posted May 3, 2010 Posted May 3, 2010 (edited) Aha! I had the first part, but missed the connection to the second part. Thanks. Global Const $PT_LOCAL = 0 Global Const $PT_TEMPORARY = 1 Global Const $PT_ROAMING = 2 Global Const $PT_MANDATORY = 4 $aRET = DllCall("UserEnv.dll", "int", "GetProfileType", "DWORD*", -1) If (@error = 0) And $aRET[0] Then $iProfileType = $aRET[1] ; [1] = first parameter (modified ByRef) Switch $iProfileType Case $PT_LOCAL $sProfileType = "Local" Case $PT_TEMPORARY $sProfileType = "Temporary" Case $PT_ROAMING $sProfileType = "Roaming" Case $PT_MANDATORY $sProfileType = "Mandatory" Case Else $sProfileType = "<INVALID>" EndSwitch ConsoleWrite("Your profile type is: " & $sProfileType & " (" & $iProfileType & ")" & @LF) Else ConsoleWrite("Error: @error = " & @error & "; $aRET[0] = " & $aRET[0] & @LF) EndIf Yes, except you are not checking error properly. If error do occur with DllCall() you will exit unexpectedly because you are trying to access non-existing array. (edit: will try to access) Edited May 3, 2010 by trancexx ♡♡♡ . eMyvnE
mec02 Posted May 4, 2010 Author Posted May 4, 2010 Hi why have i to declare the constants? Can i do it on this way: $aRET = DllCall("UserEnv.dll", "int", "GetProfileType", "DWORD*", -1) If (@error = 0) And $aRET[0] Then $iProfileType = $aRET[1] ; [1] = first parameter (modified ByRef) Switch $iProfileType Case 0 $sProfileType = "Local" Case 1 $sProfileType = "Temporary" Case 2 $sProfileType = "Roaming" Case 3 $sProfileType = "Mandatory" Case Else $sProfileType = "<INVALID>" EndSwitch ConsoleWrite("Your profile type is: " & $sProfileType & " (" & $iProfileType & ")" & @LF) Else ConsoleWrite("Error: @error = " & @error & "; $aRET[0] = " & $aRET[0] & @LF) EndIf
PsaltyDS Posted May 4, 2010 Posted May 4, 2010 (edited) Yes, except you are not checking error properly. If error do occur with DllCall() you will exit unexpectedly because you are trying to access non-existing array. (edit: will try to access)No, the 'AND' makes it safe because it only tests $aRET[0] if @error = 0. If @error = 0 then DllCall() always returns an array. If @error <> 0 then $aRET[0] is not attempted because AND is already not satisfied. Demo: $aRET = 0 SetError(1) If (@error = 0) AND $aRET[0] Then ConsoleWrite("OK" & @LF) Else ConsoleWrite("FAIL" & @LF) EndIf why have i to declare the constants? Can i do it on this way:No need to declare the constants unless you might re-use the function, where it would make things simpler (like in a UDF file). They were included for future reference. Edited May 4, 2010 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
trancexx Posted May 4, 2010 Posted May 4, 2010 No, the 'AND' makes it safe because it only tests $aRET[0] if @error = 0. If @error = 0 then DllCall() always returns an array. If @error <> 0 then $aRET[0] is not attempted because AND is already not satisfied. Demo: $aRET = 0 SetError(1) If (@error = 0) AND $aRET[0] Then ConsoleWrite("OK" & @LF) Else ConsoleWrite("FAIL" & @LF) EndIf You had this: $aRET = 0 SetError(1) If (@error = 0) And $aRET[0] Then ;... ;ConsoleWrite("Your profile type is: " & $sProfileType & " (" & $iProfileType & ")" & @LF) Else ConsoleWrite("Error: @error = " & @error & "; $aRET[0] = " & $aRET[0] & @LF) EndIf Right? ♡♡♡ . eMyvnE
PsaltyDS Posted May 4, 2010 Posted May 4, 2010 (edited) You're right. I was only looking at the 'IF' line, but it will fail in the 'Else' because of the console write with $aRET[0]. Doh! Edited May 4, 2010 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
jterwelp Posted June 4, 2010 Posted June 4, 2010 Is there a way to modify this solution to work with older versions of AutoIt? Specifically 3.2.4.9, which does not support appending "*" to the type in order to pass by reference. Thanks!
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now