Jump to content

Recommended Posts

Posted

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

Posted (edited)

You could check the $oUser.profilePath attribute.

:idea:

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 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
Posted

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

Posted (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

:idea:

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 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
Posted

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

Posted (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?

:idea:

Edited 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
Posted

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?

:idea:

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

Posted

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

:idea:

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
Posted (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

:idea:

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 by trancexx

♡♡♡

.

eMyvnE

Posted

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
Posted (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.

:idea:

Edited 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
Posted

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

  • 5 weeks later...
Posted

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!

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...