luckyluke

Dllcall - console attach to read output from CMD error

14 posts in this topic

#1 ·  Posted

Hello,

Im trying to read the output from CMD using Dllcall, here is my code:

#include <WinAPI.au3>
#include <array.au3>
Global Const $STD_OUTPUT_HANDLE = -11
Global Const $_CONSOLE_SCREEN_BUFFER_INFO = _
             "struct;int dwSizeX;" & _
             "short dwSizeY;" & _
             "short dwCursorPositionX;" & _
             "short dwCursorPositionY;" & _
             "short wAttributes;" & _
             "short Left;" & _
             "short Top;" & _
             "short Right;" & _
             "short Bottom;" & _
             "short dwMaximumWindowSizeX;" & _
             "short dwMaximumWindowSizeY;endstruct"

$pCmd = Run( "cmd.exe" )
Sleep(1000)
$hCmd = WinGetHandle("")
ConsoleWrite('handle:' & $hCmd & @CRLF)

$aRet = DllCall("kernel32.dll", "int", "AttachConsole", "dword", $pCmd)
;_ArrayDisplay($aRet)
If $aRet[0] <> 0 Then
    $vHandle_data=''
    $vHandle=''

    $vHandle_data = DllStructCreate($_CONSOLE_SCREEN_BUFFER_INFO) ; Screen Buffer structure

    $aRet1 = DllCall("kernel32.dll", "hwnd", "GetStdHandle", "dword", $STD_OUTPUT_HANDLE)
    if not @error Then $vHandle =  $aRet1[0]

    $aRet = DllCall("kernel32.dll", "int", "GetConsoleScreenBufferInfo", "hwnd", $vHandle, _
        "ptr", $vHandle_data)

    MsgBox(0, '1',DllStructGetData($vHandle_data, 'dwSizeX') & _WinAPI_GetLastErrorMessage())
EndIf

It did not work, i got the message 'The handle is invalid'. Please help?

Thank you in advance!

Share this post


Link to post
Share on other sites



#3 ·  Posted

Or you can also give Process UDF a try, you can get the output with a single line of code.


AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Spoiler

My contributions to the AutoIt Community

Some messages & Apologizes:

If I hurt you, Please accept my apologies, I never (regardless of the situation) mean to hurt anybody!!!

Also, I am very busy with my project so I will appear in the last row of the online list, if you want to contact me: Email@TheDcoder.xyz

Or you can have a nice chat with me in freenode, I use the same nick on freenode too!

3fHNZJ.gif

PLEASE JOIN ##AutoIt AND HELP THE IRC AUTOIT COMMUNITY!

Share this post


Link to post
Share on other sites

#4 ·  Posted

8 hours ago, Jos said:

Why not simply use the standard supported StdoutRead() & StderrRead() in combination with Run()?

Jos 

Yes, that is the common way, i tried it, but it does not capture all output from the cmd. That why i want to try with console attach

 

7 hours ago, TheDcoder said:

Or you can also give Process UDF a try, you can get the output with a single line of code.

Your code is using the Stdreadout, i tried it before but it did not work. 

Share this post


Link to post
Share on other sites

#5 ·  Posted

Are you trying to read output directly from cmd.exe?


AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Spoiler

My contributions to the AutoIt Community

Some messages & Apologizes:

If I hurt you, Please accept my apologies, I never (regardless of the situation) mean to hurt anybody!!!

Also, I am very busy with my project so I will appear in the last row of the online list, if you want to contact me: Email@TheDcoder.xyz

Or you can have a nice chat with me in freenode, I use the same nick on freenode too!

3fHNZJ.gif

PLEASE JOIN ##AutoIt AND HELP THE IRC AUTOIT COMMUNITY!

Share this post


Link to post
Share on other sites

#6 ·  Posted

49 minutes ago, TheDcoder said:

Are you trying to read output directly from cmd.exe?

Do you mean read from cmd.exe using StdoutRead, yes it can read output from cmd but not all things. I have an other program run using CMD, it will out the result to CMD, then i used StdoutRead to read from cmd, but can not get all result from there.

 

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

1 hour ago, luckyluke said:

it can read output from cmd but not all things

I suspect that the program which outputs to the CMD is also using StdErr stream. You should try using the $STDERR_MERGED flag, the _Process_RunCommand function from Process UDF automatically does that for you by default :)

Edited by TheDcoder

AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Spoiler

My contributions to the AutoIt Community

Some messages & Apologizes:

If I hurt you, Please accept my apologies, I never (regardless of the situation) mean to hurt anybody!!!

Also, I am very busy with my project so I will appear in the last row of the online list, if you want to contact me: Email@TheDcoder.xyz

Or you can have a nice chat with me in freenode, I use the same nick on freenode too!

3fHNZJ.gif

PLEASE JOIN ##AutoIt AND HELP THE IRC AUTOIT COMMUNITY!

Share this post


Link to post
Share on other sites

#8 ·  Posted

6 minutes ago, TheDcoder said:

I suspect that the program which outputs to the CMD is also using StdErr stream. You should try using the $STDERR_MERGED flag, the _Process_RunCommand function from Process UDF automatically does that for you by default :)

yes, i tried, but not work. I see that if i close the program then it will show the message in the output. but if i run it from cmd, the message appears even when program is running.

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

7 minutes ago, luckyluke said:

but if i run it from cmd, the message appears even when program is running.

If that is the case, then you can try calling the program from instead of directly calling it. You can do it like this in my UDF:

$sOutput = _Process_RunCommand($PROCESS_RUNWAIT, $PROCESS_COMMAND & 'path_to_your_program.exe') ; This will execute cmd.exe which will run your program

This way, cmd.exe acts like a proxy between the AutoIt script and the program. You should be able to read all output given to cmd.exe if you use the above code snippet

Edited by TheDcoder
Add $sOutput to the code snippet

AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Spoiler

My contributions to the AutoIt Community

Some messages & Apologizes:

If I hurt you, Please accept my apologies, I never (regardless of the situation) mean to hurt anybody!!!

Also, I am very busy with my project so I will appear in the last row of the online list, if you want to contact me: Email@TheDcoder.xyz

Or you can have a nice chat with me in freenode, I use the same nick on freenode too!

3fHNZJ.gif

PLEASE JOIN ##AutoIt AND HELP THE IRC AUTOIT COMMUNITY!

Share this post


Link to post
Share on other sites

#10 ·  Posted

I have a look at Process UDF, the code seems complicated.

Try this simple one:

Local $iCommand = "ping google.com"

_RunCmd($iCommand)
_RunCmd_GetStdOut($iCommand)


Func _RunCmd($sCommand)
    ConsoleWrite("+ Execute: " & $sCommand & @CRLF)
    Local $sOutput = '', $iPID = Run('"' & @ComSpec & '" /c ' & '"' & $sCommand & '"', '', @SW_HIDE, 0x6)
    If Not $iPID Then Return SetError(1, 0, '')
    Do
        $sOutput &= StdoutRead($iPID)
    Until @error
    Do
        $sOutput &= StderrRead($iPID)
    Until @error
    ConsoleWrite("" & $sOutput & @CRLF)
    ConsoleWrite("- -------------------------------------------------------------" & @CRLF)
    Return $sOutput
EndFunc   ;==>_RunCmd

Func _RunCmd_GetStdOut($sCommand, $sDir = '', $iType = 0x6, $bShow = False, $iDelay = 50)
    ConsoleWrite("+ Execute: " & $sCommand & @CRLF)
    Local $sTMP = '', $sOutput = ''
    Local $iPID = Run('"' & @ComSpec & '" /c ' & '"' & $sCommand & '"', $sDir, $bShow ? @SW_SHOW : @SW_HIDE, $iType)
    If Not $iPID Then Return SetError(1, 0, '')
    While 1
        $sTMP = StdoutRead($iPID, False, False)
        If @error Then ExitLoop 1
        If $sTMP <> "" Then
            $sTMP = StringReplace($sTMP, @CR & @CR, '')
            $sOutput &= $sTMP
            ConsoleWrite($sTMP)
            Sleep($iDelay)
        EndIf
    WEnd
    While 1
        $sTMP = StderrRead($iPID, 0, 0)
        If @error Then ExitLoop
        If $sTMP <> "" Then
            $sTMP = StringReplace($sTMP, @CR & @CR, '')
            $sOutput &= $sTMP
            ConsoleWrite($sTMP)
            Sleep($iDelay)
        EndIf
    WEnd
    ConsoleWrite("- -------------------------------------------------------------" & @CRLF)
    Return $sOutput
EndFunc   ;==>_RunCmd_GetStdOut

 

1 person likes this

Regards,
 

Share this post


Link to post
Share on other sites

#11 ·  Posted

4 hours ago, luckyluke said:

yes, i tried, but not work. I see that if i close the program then it will show the message in the output. but if i run it from cmd, the message appears even when program is running.

Show your code and info on the program running so we can see what might be the issue.

Jos


Visit the SciTE4AutoIt3 Download page for the latest versions  - Beta files                                How to post scriptsource        Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#12 ·  Posted

7 hours ago, TheDcoder said:

If that is the case, then you can try calling the program from instead of directly calling it. You can do it like this in my UDF:

$sOutput = _Process_RunCommand($PROCESS_RUNWAIT, $PROCESS_COMMAND & 'path_to_your_program.exe') ; This will execute cmd.exe which will run your program

This way, cmd.exe acts like a proxy between the AutoIt script and the program. You should be able to read all output given to cmd.exe if you use the above code snippet

This code will get the output when the program ends. But i want to get the status when the program is running.

 

3 hours ago, VIP said:

I have a look at Process UDF, the code seems complicated.

Try this simple one:

 

Yes, i found it and tried it before. But the code actually get the output after the program exit. I want to get the console while the program is running.

this is my code:

the code will open the CMD and run "python ui.py" then get the output from console.

#include 'array.au3'
;#include "UIAWrappers.au3"

Global $DOS, $timer, $whd

$live_file = IniRead(@ScriptDir & '\config.ini', 'py_run', 'live_file', '')
$prediction_file = IniRead(@ScriptDir & '\config.ini', 'py_run', 'prediction_file', '')
$training_file = IniRead(@ScriptDir & '\config.ini', 'py_run', 'training_file', '')
$wait_time = IniRead(@ScriptDir & '\config.ini', 'py_run', 'wait_time', 6)
FileDelete(@ScriptDir & '\pyConsole.txt')

startPY()
Sleep(1000)
$checker = 1
$i = 1
While 1
    $tmp = ControlGetText('python.exe', '', 'Button1')
    if StringInStr($tmp, 'check online for a solution') Then
        WinClose('python.exe')
        Sleep(3000)
        startPY()
    EndIf

;~  Sleep(50) ;; no need to go at full speed here.
;~  $sOutput=''
;~  While 1
;~         $sOutput &= StdoutRead($DOS, False, False)
;~         If @error Then
;~             ExitLoop
;~         EndIf
;~         Sleep(10)
;~      ConsoleWrite($sOutput)
;~     WEnd

    $Message = StdoutRead($DOS) ;; ditched peek parameter + changed "=" to "&=" ... No more endless loop.
    if @error Then
        restartPY()
        startPY()
    EndIf

    ;$sOutput = StderrRead($DOS)
    ;ConsoleWrite($i & ':' & $sOutput & ',' & StringLen($sOutput) & @CRLF)
    ConsoleWrite($i & ':' & $Message & ',' & StringLen($Message) & @CRLF)
    $i=$i+1
    if StringLen($Message)>2 and StringInStr($Message, @CRLF) Then
        ConsoleWrite('i:' & $i & ',' & $Message & @CRLF)
        ;$i=$i+1
        if StringInStr($Message, ',') Then
            $tmp = StringSplit($Message, @CRLF)
            ;_ArrayDisplay($tmp)
            if not @error Then
                for $j = 1 to UBound($tmp)-1
                    if StringInStr($tmp[$j], ',') Then
                        $file = FileOpen(@ScriptDir & '\pyConsole.txt', 1)
                        FileWrite($file, $tmp[$j] & @CRLF)
                        FileClose($file)
                    EndIf
                Next
            EndIf
        EndIf
        $checker=1
    Else
        $checker = $checker+1
        ;ConsoleWrite('checker:' & $checker & @CRLF)
        if $checker=10 Then
            $timer = TimerInit()
        EndIf
    EndIf

    if $checker>=10000 Then
        $atime = TimerDiff($timer)/1000
        if not @error Then
            if $atime>Number($wait_time) Then
                restartPY()
                startPY()
            EndIf
        EndIf
    EndIf
    if @error then exitloop
WEnd

Func restartPY()
    Do
        if WinExists('C:\Windows\system32\cmd.exe') then
            WinClose('C:\Windows\system32\cmd.exe')
        Else
            ExitLoop
        EndIf
    Until WinExists('C:\Windows\system32\cmd.exe')=0

    WinActivate('Predictive model 1.0')
    Sleep(500)
    WinClose('Predictive model 1.0')
    WinWait('Confirm Exit', '', 3)
    WinActivate('Confirm Exit')
    WinMove('Confirm Exit', '', 0, 0)
    Sleep(500)
    if WinExists('Confirm Exit') then MouseClick('left', 109,94)
    Sleep(4000)
EndFunc

Func startPY()

    $CMD = 'cd ' & @DesktopDir & '\Predictive_model && ' & _
        'python ui.py'
    $DOS = Run(@ComSpec & ' /C ' & $CMD, @ScriptDir, @SW_SHOW, $STDOUT_CHILD+$RUN_CREATE_NEW_CONSOLE)
    ;$DOS = Run(@ComSpec & ' /C ' & $CMD, @ScriptDir, @SW_SHOW, $STDIN_CHILD + $STDERR_MERGED)
    ConsoleWrite($DOS & @CRLF)

    $mtitle = 'Predictive model 1.0'
    WinWait($mtitle, '', 5000)
    ;Sleep(5000)


    WinMove($mtitle, '', 0, 0)
    Sleep(1000)

    ;=====================================set value to GUI=================================================
    ;live file
    ;_UIA_Action("Title:=;controltype:=UIA_EditControlTypeId;class:=","setfocus")
    ;_UIA_Action("Title:=;controltype:=UIA_EditControlTypeId;class:=","setValue using keys", "C:\Users\Administrator\Desktop\Sabrina Betting\LV1.txt")
    WinActivate($mtitle)
    Sleep(1000)
    MouseClick('left', 345,87)
    Send("^a")
    Sleep(500)
    Send($live_file  & '11')

    ;prediction file
    WinActivate($mtitle)
    Sleep(1000)
    MouseClick('left', 345,200)
    Send("^a")
    Sleep(500)
    Send($prediction_file)
    ;use control click
    WinActivate($mtitle)
    Sleep(1000)
    MouseClick('left', 345,234)
    Send("^a")
    Sleep(500)
    Send($training_file)

    ;click start button
;~  Local $oP1=_UIA_getObjectByFindAll($UIA_oDesktop, "Title:=Predictive model 1.0;controltype:=UIA_WindowControlTypeId;class:=QWidget", $treescope_children)
;~  Local $oP0=_UIA_getObjectByFindAll($oP1, "Title:=;controltype:=UIA_CustomControlTypeId;class:=", $treescope_children)
;~  Local $oUIElement=_UIA_getObjectByFindAll($oP0, "title:=Start;ControlType:=UIA_ButtonControlTypeId", $treescope_subtree)
;~  _UIA_action($oUIElement,"focus")
;~  _UIA_action($oUIElement,"click")
    WinActivate($mtitle)
    Sleep(1000)
    MouseClick('left', 593,301)
    Sleep(3000)
EndFunc

 

Share this post


Link to post
Share on other sites

#13 ·  Posted

1 minute ago, luckyluke said:

This code will get the output when the program ends. But i want to get the status when the program is running.

In that case you can use $PROCESS_RUN instead of $PROCESS_RUNWAIT. Refer to the Example.au3 script for more details :)

1 person likes this

AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Spoiler

My contributions to the AutoIt Community

Some messages & Apologizes:

If I hurt you, Please accept my apologies, I never (regardless of the situation) mean to hurt anybody!!!

Also, I am very busy with my project so I will appear in the last row of the online list, if you want to contact me: Email@TheDcoder.xyz

Or you can have a nice chat with me in freenode, I use the same nick on freenode too!

3fHNZJ.gif

PLEASE JOIN ##AutoIt AND HELP THE IRC AUTOIT COMMUNITY!

Share this post


Link to post
Share on other sites

#14 ·  Posted

4 hours ago, TheDcoder said:

In that case you can use $PROCESS_RUN instead of $PROCESS_RUNWAIT. Refer to the Example.au3 script for more details :)

ok, i will check it. thank you

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

  • Similar Content

    • BigDaddyO
      By BigDaddyO
      I've been working with the Windows Credentials store to store credentials for lots of RDP connections.  I'm also using this code in other scripts to store and retrieve "legacy" credentials for my scripts that have a Save Password checkbox.
      All goes well, until someone requests a button to display a list of all saved credentials.  I found the CredEnumerate call and it looks like it's working but the Target and UserName field that I want is stored inside an array of pointers and I can't figure out how to get data from inside that.  I found a post from 2009 that talks about this, but there was never a solution.
       
      Below are my functions put into an example script.  the _Credentials_Enumerate() is where i'm having problems.   Anybody have some ideas?
      Thanks,
      Mike
       
      ;Credentials Manager #include <array.au3> #include <WinAPI.au3> ;Needed for the _WinAPI_GetLastError() ;------------------------------------------------------------------------ ;----- Add items into the Credentials Store ---------------------------- ;------------------------------------------------------------------------ ;~ _Cred_Add("MyCredStored", "ItsMe", "Secret1", "", 1) ;Add a Local Credentials so we can test the retrieval of a password ;~ $aAddCred = _Cred_Add("MyServer", "Domain\adminAccount", "MyS3cr3+P@ssw0rd") ;Add domain Credentials that can only be used with RDP and other such items ;~ _ArrayDisplay($aAddCred, "AddCred") ;------------------------------------------------------------------------ ;------------------------------------------------------------------------ ;----- Retrieve Credentials from the Credentials Store ----------------- ;------------------------------------------------------------------------ ;~ $aCreds = _Cred_Get("MyServer", 2) ;Retrieve Domain Cred's, won't have password in it ;~ _ArrayDisplay($aCreds, "Credentials") $aCreds = _Credentials_Enumerate() ;Get a list of all credentials currently stored on the system **(DOES NOT WORK)** ;------------------------------------------------------------------------ ;------------------------------------------------------------------------ ;----- Delete a Credential from the Credentials Store ------------------ ;------------------------------------------------------------------------ ;~ _Cred_Delete("MyServer") ;Delete the specified item from the Credential Store ;~ For $d = 1 to UBound($aCreds) - 1 ;~ _Cred_Delete($aCreds[$d][0]) ;Loop to delete all items found. **(DOES NOT WORK)** ;~ Next ;------------------------------------------------------------------------ ;================================================================================================ ;===== Add a Credential into the Credentials Store ============================================= ;================================================================================================ Func _Cred_Add($sTarget, $sUser, $sPassword, $sComm = "", $iType = 2) ;Type: 2=Domain, 1=Local Local $structTarget = DllStructCreate("wchar[100]") ; Create a structure to hold the Target object name DllStructSetData($structTarget, 1, $sTarget) ; Insert the target name into that Structure Local $structUser = DllStructCreate("wchar[100]") ; Create a structure to hold the UserName to use DllStructSetData($structUser, 1, $sUser) ; Insert the user name into the structure Local $structPwd = DllStructCreate("wchar[100]") ; Create a structure to hole the password to use DllStructSetData($structPwd, 1, $sPassword) ; Insert the password into the structure Local $structComment = DllStructCreate("wchar[100]") ; I don't see where this is used, but was in all the examples DllStructSetData($structComment, 1, $sComm) Local $structCREDENTIAL= "" & _ "DWORD Flags;" & _ "DWORD Type;" & _ "Ptr TargetName;" & _ "Ptr Comment;" & _ "UINT64 LastWritten;" & _ "DWORD CredintialBlobSize;" & _ "Ptr CredentialBlob;" & _ "DWORD Persist;" & _ "DWORD AttributeCount;" & _ "ptr Attributes;" & _ "Ptr TargetAlias;" & _ "Ptr Username" Local $NewCred = DllStructCreate($structCREDENTIAL) If @error Then MsgBox(0, "NewCred", "Error in DllStructCreate " & @error); Exit EndIf DllStructSetData($NewCred,"Flags",0) DllStructSetData($NewCred,"Type",$iType) ;2 = Domain, 1 = Generic DllStructSetData($NewCred,"TargetName",DllStructGetPtr($structTarget)) DllStructSetData($NewCred,"Persist",3) DllStructSetData($NewCred,"AttributeCount",0) DllStructSetData($NewCred,"UserName",DllStructGetPtr($structUser)) DllStructSetData($NewCred,"CredentialBlob",DllStructGetPtr($structPwd)) DllStructSetData($NewCred,"CredintialBlobSize",StringLen($sPassword)*2) DllStructSetData($NewCred,"Comment",DllStructGetPtr($structComment)) Local $hAdvapi32 = DllOpen("Advapi32.dll") If $hAdvapi32 = -1 Then Msgbox(0, "Error", "Failed to connect to the Credentials Store") Exit Endif $Ret = DllCall($hAdvapi32, 'bool', 'CredWriteW', 'ptr', DllStructGetPtr($NewCred), 'dword', 0) $NewCred = 0 If IsArray($Ret) Then Return $Ret Else Return SetError(1) EndIf EndFunc ;_Cred_Add ;================================================================================================ ;===== Retrieve the Credentials for the specified item ========================================= ;================================================================================================ Func _Cred_Get($sTarget, $iType = 1) ;Type: 2=Domain, 1=Local. CAN'T RETURN DOMAIN PASSWORDS!!! Local $FuncRet[3] Local $structTarget = DllStructCreate("wchar[100]") DllStructSetData($structTarget,1,$sTarget) Local $hAdvapi32 = DllOpen("Advapi32.dll") If $hAdvapi32 = -1 Then Msgbox(0, "Error", "Failed to connect to the Credentials Store") Exit Endif Local $Ret = DllCall($hAdvapi32, 'bool', 'CredReadW', 'ptr', DllStructGetPtr($structTarget), 'dword', $iType, 'dword', 0, 'ptr*', 0) if $ret[0]=0 then Return SetError(1,0,$FuncRet) Local $structCREDENTIAL= "" & _ "DWORD Flags;" & _ "DWORD Type;" & _ "Ptr TargetName;" & _ "Ptr Comment;" & _ "UINT64 LastWritten;" & _ "DWORD CredintialBlobSize;" & _ "Ptr CredentialBlob;" & _ "DWORD Persist;" & _ "DWORD AttributeCount;" & _ "Ptr Attributes;" & _ "Ptr TargetAlias;" & _ "Ptr Username" Local $tdata=DllStructCreate($structCREDENTIAL, $Ret[4]) Local $userName = DllStructCreate("wchar[100]", DllStructGetData($tdata, 'Username')) Local $User = DllStructGetData($userName, 1) Local $CredentialBlobSize = DllStructGetData($tdata, 'CredintialBlobSize') Local $credentialBlob = DllStructCreate("wchar[100]", DllStructGetData($tdata, 'CredentialBlob')) Local $Password = StringLeft(DllStructGetData($credentialBlob, 1), $CredentialBlobSize/2) Local $Comment = DllStructCreate("wchar[100]", DllStructGetData($tdata, 'Comment')) Local $Comm = DllStructGetData($Comment, 1) Dim $FuncRet[] = [$User, $Password, $Comm] Return $FuncRet EndFunc ;_Cred_Get ;================================================================================================ ;===== Delete a specified item from the Credentials Store ====================================== ;================================================================================================ Func _Cred_Delete($sTarget, $iType = 2) ;Type: 2=Domain, 1=Local Local $structTarget = DllStructCreate("wchar[100]") ;Create a structure to hold the object name we want to delete DllStructSetData($structTarget, 1, $sTarget) ;Insert the Object Name into the Structure Local $hAdvapi32 = DllOpen("Advapi32.dll") If $hAdvapi32 = -1 Then Msgbox(0, "Error", "Failed to connect to the Credentials Store") Exit Endif ;Now send all the info into the DLL to delete the item $Ret = DllCall($hAdvapi32, 'bool', 'CredDeleteW', 'ptr', DllStructGetPtr($structTarget), 'dword', $iType, 'dword', 0) ;$iType 2 = Domain, 1 = Local EndFunc ;_Cred_Delete ;================================================================================================ ;===== Return a 2D array with the Target, UserName, Password for every item ==================== ;===== in the Credentials Store ==================== ;================================================================================================ Func _Credentials_Enumerate() ;https://msdn.microsoft.com/en-us/library/windows/desktop/aa374794(v=vs.85).aspx ;https://www.autoitscript.com/forum/topic/99705-credenumerate-function-call/?do=findComment&comment=715159 Local $aResult Local $structCREDENTIAL = "DWORD Flags;" & _ "DWORD Type;" & _ "Ptr TargetName;" & _ "Ptr Comment;" & _ "UINT64 LastWritten;" & _ "DWORD CredintialBlobSize;" & _ "Ptr CredentialBlob;" & _ "DWORD Persist;" & _ "DWORD AttributeCount;" & _ "Ptr Attributes;" & _ "Ptr TargetAlias;" & _ "Ptr Username" $aResult = DllCall('advapi32.dll', 'int', 'CredEnumerateW', _ ;Call the Unicode version of CredEnumerate 'wstr', Null, _ ;Don't use any filter since I want everything returned 'uint', 1, _ ;1 = CRED_ENUMERATE_ALL_CREDENTIALS 'uint*', '', _ ;Return the Count of all stored credentials 'ptr*', '') ;Returns a pointer to an Array of pointers? If @error Or ($aResult[0] = 0) Then ConsoleWrite('Error: ' & @error & @TAB & 'Extended: ' & @extended & @CRLF) ConsoleWrite(_WinAPI_GetLastError() & @CRLF) ;1168 = Nothing matches the filter, 1312 = no credential set for this user, 1004 = Flag/Filter options are wrong Return SetError(1) EndIf ConsoleWrite("DllCall Returned = " & $aResult[0] & @CRLF & "Credential Count = " & $aResult[3] & @CRLF & "Pointer to Creds Array = " & $aResult[4] & @CRLF) For $c = 2 to $aResult[3] ;Create enough struct for each item in each credential found $structCREDENTIAL &= "DWORD Flags;" & _ "DWORD Type;" & _ "Ptr TargetName;" & _ "Ptr Comment;" & _ "UINT64 LastWritten;" & _ "DWORD CredintialBlobSize;" & _ "Ptr CredentialBlob;" & _ "DWORD Persist;" & _ "DWORD AttributeCount;" & _ "Ptr Attributes;" & _ "Ptr TargetAlias;" & _ "Ptr Username" Next Local $tdata = DllStructCreate($structCREDENTIAL, $aResult[4]) ;Insert all the data from the array of pointers into this struct Local $FullTarget = DllStructCreate("wchar[100]", DllStructGetData($tdata, 'TargetName')) ;Create and Get the array storing TargetName Local $userName = DllStructCreate("wchar[100]", DllStructGetData($tdata, 'Username')) ;Create and Get the array storing Username Local $CredentialBlobSize = DllStructGetData($tdata, 'CredintialBlobSize') ;Get the password blob Local $credentialBlob = DllStructCreate("wchar[100]", DllStructGetData($tdata, 'CredentialBlob')) ;Create and get the password text Local $Comment = DllStructCreate("wchar[100]", DllStructGetData($tdata, 'Comment')) ;Don't see a need for comments ;Retrieve the data For $c = 1 to $aResult[3] Local $Target = DllStructGetData($FullTarget, $c) ;Retrieve the Target Name from the item # Local $User = DllStructGetData($userName, $c) ;Retrieve the User Name from the item # Local $Password = StringLeft(DllStructGetData($credentialBlob, $c), $CredentialBlobSize/2) ;Retrieve the password, Only works for 1, legacy. domain creds will not return passwords Local $Comm = DllStructGetData($Comment, $c) ;Don't need comments but getting it since it's in all the examples ConsoleWrite("Loop = " & $c & ": Target = " & $Target & ": UserName = " & $User & ": Comment = " & $Comm & @CRLF) Next If $aResult[3] > 0 Then $aCreds = DllCall('advapi32.dll', 'none', 'CredFree', 'ptr', $aResult[4]) ;This is just used to release the pointer. Call when done EndIf EndFunc ;_Credentials_Enumerate  
    • TheAutomator
      By TheAutomator
      A fullscreen console with custom commands!

      Introduction:
      Hi everyone!
      This funny project started as a question in the help section:
      https://www.autoitscript.com/forum/topic/174404-edit-detect-key-before-updating-content/
      I'd like to share this script with everyone that is interested. 
       
      Why would I want it?
      You like the old style fullscreen console (like in the old day's), You can add custom commands, You can customize the font a lot more compared to cmd.exe, You can share ideas or add tweaks to the script.  
      What's next?
      I'm planning to add my own programming language to it!
      Its going to be implemented with an ActiveX COM dll.
      The syntax is going to be a bit like Lua I guess, any ideas are welcome!
       
      Todo:
      Add sounds. Make an icon / logo. Design a better grammar ( Backus-Naur-vorm: https://nl.wikipedia.org/wiki/Backus-Naur-vorm ). Make test "Console-Scripts" for it. Add a file type for script files ( like batch scripts ). Clean up and modify Console.Au3 content. Add an option to have to type a login password (maybe). Call neo   
      Thanks to:
      xxaviarxx: debugging, some ideas. jguinch: debugging, adding a bunch of tweaks and ideas. kylomas: debugging, new ideas.  
      Edits and updates:
      Added tab key Main edit has focus now on startup Made a pdf that explains the upcoming programming language (need feedback about it!)  
      Until the dll is ready you can have fun with what I already have, hope you like it!
      UDF can be downloaded from the attachments.
      Regards
       
      [The programming language part is been postponed]
      [It's been a while, made a custom recursive descent parser in AutoIt, language and updates will be uploaded soon!]
       
      TheAutomator
       
      Console.au3
      ConsoleScript.pdf
    • hcI
      By hcI
      Hello I would like to know if there is a way to return a sentence in cmd when I launch from it (because I add arguments).
      For example, diskpart.exe which help to manage the key and hdd connected, when you launch it with the parameter "/f" the app return a sentence saying that it don't recognize the parameter "/f" and it return the sentence in the cmd where i started the application, not a new one.
      That's what I want to do but I couldn't find anything that would solve my problem on internet and on AutoIt like ConsoleWrite / ConsoleWriteError (don't work).
       
      Thanks
    • Duck
      By Duck
      I'm attempting to capture the output from the command line tool PSEXEC. I'm using AutoIT to run an instance of PSEXEC against a remote PC to audit Local Admins in my environment using net.exe (C:\Windows\System32> net localgroup administrators). However the usual trick I use to capture command line output does not appear to work well with PSEXEC, as the bottom portion of the output is missing from the return. Any ideas or recommendations are greatly appreciated.  
       
      Here is what I'm working with: 
      ;This script will read from a list of hosts and report who has local admin privileges on the machine #RequireAdmin Global $fileName = @ScriptDir & '\test.txt' ;hostlist, one host per line readHostList() ;Read list of hosts Func readHostList() Local $file = FileOpen($fileName, 0) While 1 $line = FileReadLine($file) If @error = -1 Then ExitLoop ConsoleWrite($line & @CRLF) ;MsgBox(0,0,$line) getLocalAdmins($line) WEnd FileClose($file) EndFunc ;run PSEXEC to list local admins Func getLocalAdmins($remotePC) Local $testFile = @ScriptDir &'\test234.txt' FileOpen($testFile, 1) Local $psexec = 'psexec \\' & $remotePC & ' net localgroup administrators' FileWriteLine($testFile, _RunCmd($psexec) ) FileClose($testFile) EndFunc ;Used to return CLI output Func _RunCmd($sCommand) Local $nPid = Run(@Comspec & " /c" & $sCommand, @SystemDir, @SW_Hide, 8), $sRet = "" If @Error then Return "ERROR:" & @ERROR ProcessWait($nPid) While 1 $sRet &= StdoutRead($nPID) If @error Or (Not ProcessExists ($nPid)) Then ExitLoop WEnd Return $sRet EndFunc  
      ## If i manually run the command on the remote PC via PSEXEC I will get the following output: 
      PsExec v2.11 - Execute processes remotely
      Copyright (C) 2001-2014 Mark Russinovich
      Sysinternals - www.sysinternals.com
      Starting net on PCNAME... on PCNAME...
      net exited on PCNAME with error code 0.
      -------------------------------------------------------------------------------
      admin
      Administrator
      Alias name     administrators
      Domain\Domain Admins
      Comment        Administrators have complete and unrestricted access to the computer/domain
      Members
      The command completed successfully.
       
      ## The returned output from running the above script is as follows:
      PsExec v2.11 - Execute processes remotely
      Copyright (C) 2001-2014 Mark Russinovich
      Sysinternals - www.sysinternals.com
      Alias name     administrators
      Connecting to PCNAME...
      Starting PSEXESVC service on PCNAME...
      Connecting with PsExec service on PCName...
      Starting net on PCNAME..
      net exited on PCNAME with error code 0.
       
      **Note to test this script PSEXEC must be in the system dir or the path in the script changed 
      PSEXEC tool: https://docs.microsoft.com/en-us/sysinternals/downloads/psexec
    • mihaijulien
      By mihaijulien
      Hello,
      I compiled a script I made that takes a command line parameter (the version of a .msi installer) when launched. The script was compiled with the /console option. The script (.au3) works fine but the executable returns  the following error:  
      Error: array variable has incorrect number of subscripts or subscript dimension range exceeded