Jump to content

Problem with StdOutRead/StringSplit under 3.2.12


Recommended Posts

This script works perfectly under 3.2.10 but not so with 3.2.12. I have indentified some of the issues such as RunAs instead of RunAsSet but can't seem to get my head around the StdErrRead. What the script does is run a DOS command called "getsid.exe". This outputs some text to the console, which is read in to the variable $getsidoutput. Stringsplit breaks this up and StringTrimRight lops off the last two carriage returns, leaving you with the SID of the currently logged in user. Script is below:

If Not IsAdmin() Then
    RunAsSet ( "USER", @Computername, "Password" )
    Run ('"' & @AutoItExe & '"' & ' "' & @ScriptFullPath & '"', @WorkingDir )
    Exit
EndIf

#include <Constants.au3>

FileInstall ( "getsid.exe", "D:\System\getsid.exe", 1 )
$getsid = Run ( "D:\System\getsid.exe \\" & @ComputerName & " " & @UserName & " \\" & @ComputerName & " " & @UserName, "", "", $STDERR_CHILD + $STDOUT_CHILD )
$getsidoutput = StdoutRead($getsid)
$SIDsplit = StringSplit ( $getsidoutput, "is ", 1 )
$SIDtrimmed = StringTrimRight ( $SIDsplit[3], 2 )
RegDelete ( "HKEY_USERS\" & $SIDtrimmed & "\Software\Microsoft\Windows\CurrentVersion\Internet Settings", "AutoConfigURL" )
ProcessWaitClose ( "getsid.exe" )
FileDelete ( "D:\System\getsid.exe" )
Exit

The getsid.exe can be obtained here.

I understand that the StdOutRead needs to be within a loop but after building some test scripts I cannot get it to work as it did. With the command within a While...Wend loop, $SIDSplit returns as having zero elements so the StringTrimRight command fails as there isn't a third element. Any help would be most appreciated.

Edited by Memnoch
Link to comment
Share on other sites

Hmm, works:

$getsid = Run ( "getsid.exe \\" & @ComputerName & " " & @UserName & " \\" & @ComputerName & " " & @UserName, "", "", $STDERR_CHILD + $STDOUT_CHILD )
$getsidoutput = ""
Do
$getsidoutput &= StdoutRead($getsid)
Until @error
$SIDsplit = StringSplit ( $getsidoutput, "is ", 1 )
$SIDtrimmed = StringTrimRight ( $SIDsplit[3], 2 )
MsgBox(0, '', $SIDtrimmed)

Yu have to put StdOut Read in a Loop, which adds the Output to the end of a String Variable. The Lopp should end, when an Error occurs, what means, that The GetSid.exe has colsed.

Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

Hi, yes that works well thanks. I tried using While...Wend as well, as described in the help file and that works too. The bits I had missed was declaring the variable first, and using &= rather than =. Presumably because the loop is reading the output in a character at a time.

Link to comment
Share on other sites

ProgAndy is correct, there is no guarantee that a single call to StdoutRead (either old or new versions) will retrieve all the output that the child process has forthcoming; you were (un)fortunate that it worked as you expected using the previous release of AutoIt3.

I see another few possible gotchas with your script as it is:

From the RunAs command line it looks like you're running an uncompiled script, so your RunAs credentials are readable in the AU3 file.

The rerun-as-admin test is clever, but it has a chance of infinitely respawning and looping if the RunAs user exists but is not an administrator on the machine. I've tried to avoid this in the past by adding a bogus command line argument for the re-run, e.g. @ScriptFullPath & " blah" and adding a test that exits before rerunning if $CMDLINE[0] is greater than zero.

@UserName is the user name at the time the script is run, so if you've had to re-run as an administrator, this will resolve to that administrator's user name. You could pass your original user's name along on the re-run AutoIt3 command line and use $CMDLINE[1] rather than @UserName in the getsid.exe command line.

Yes yes yes, there it was. Youth must go, ah yes. But youth is only being in a way like it might be an animal. No, it is not just being an animal so much as being like one of these malenky toys you viddy being sold in the streets, like little chellovecks made out of tin and with a spring inside and then a winding handle on the outside and you wind it up grrr grrr grrr and off it itties, like walking, O my brothers. But it itties in a straight line and bangs straight into things bang bang and it cannot help what it is doing. Being young is like being like one of these malenky machines.

Link to comment
Share on other sites

I can't take credit for the re-run bit. I found that on these forums. Good suggestions there regarding the username. I hadn't actually tried it yet on a machine logged in with a non-admin user. Thanks again to you both!

Link to comment
Share on other sites

I can't take credit for the re-run bit. I found that on these forums.

This may help your restart to ensure it only happens once as DaveF mentions about.

If Not IsAdmin() And Not $CMDLINE[0] Then
    RunAsSet ( "USER", @Computername, "Password" )
    Run ('"' & @AutoItExe & '" /AutoIt3ExecuteScript "' & @ScriptFullPath & '" /admin', @WorkingDir )
    Exit
EndIf

Passing a parameter on restart means the code above should not be executed again. The /AutoIt3ExecuteScript switch allows it to run compiled or uncompiled.

:)

Link to comment
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
 Share

  • Recently Browsing   0 members

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