ahha Posted December 23, 2018 Share Posted December 23, 2018 I have a really basic question. I'm trying to tap into $STDIN_CHILD for cmd.exe and the simple script below is not working. I'm getting the cmd.exe prompt in the SciTE console and no dir listing in the cmd.exe window. I've tried variations and am stuck. What am I doing wrong? #include <AutoItConstants.au3> #include <MsgBoxConstants.au3> $iPID = Run("C:\Windows\system32\cmd.exe", @SystemDir, @SW_MAXIMIZE, $STDIN_CHILD) MsgBox($MB_TOPMOST, "Debug", "$iPID = '" & $iPID & "'" & @CRLF & _ "Look at console window in SciTE - why does it have cmd.exe output? I only tapped STDIN, not STDOUT.") StdinWrite($iPID, "dir{ENTER}") If @error Then Exit MsgBox(0, "ERROR", "Error using StdWrite.") ;why is the directory listing not going to the cmd.exe window? Where is it going? MsgBox($MB_TOPMOST, "Paused", "Click OK to exit program.") Exit Link to comment Share on other sites More sharing options...
Trong Posted December 23, 2018 Share Posted December 23, 2018 (edited) try this Function for CMD: expandcollapse popup;~ #RequireAdmin #include <File.au3> If @OSArch = "X64" And Not @AutoItX64 Then _Wow64FsRedirection(0) Local $output= _RunCmd_GetOutput("dir") MsgBox(0, "", $output) Local $output=_StreamCMD("ping 8.8.8.8") MsgBox(0, "", $output) Func _RunCmd_GetOutput($sCommand) ConsoleWrite("+Execute: " & $sCommand & @CRLF) Local $sOutput = '', $iPID = Run('"' & @ComSpec & '" /c ' & $sCommand, '', @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) Do $sOutput &= StdoutRead($iPID) Until @error Do $sOutput &= StderrRead($iPID) Until @error ConsoleWrite($sOutput&@CRLF) Return $sOutput EndFunc ;==>_RunCmd Func _StreamCMD($sCMD, $sCallBackFunction = Default, $WorkingDir = Default, $iStreamType = Default, $iShowFlag = Default, $iDelay = Default) If StringStripWS($sCMD, 8) = "" Then Return "" If $sCallBackFunction = Default Then $sCallBackFunction = "ConsoleWrite" ;~ If $WorkingDir = Default Then $WorkingDir = @SystemDir ;@WindowsDir & '\System32' If $WorkingDir = Default Then $WorkingDir = @WindowsDir & '\System32' If $iStreamType = Default Then $iStreamType = $STDERR_CHILD + $STDOUT_CHILD If $iShowFlag = Default Then $iShowFlag = False If $iDelay = Default Then $iDelay = 250 ConsoleWrite("! Execute: " & $sCMD & @CRLF) Local $sTMP = '', $sSTD = '', $sCOM = '"' & @WindowsDir & '\System32\cmd.exe"' & ' /c ' & $sCMD ;~ Local $sTMP = '', $sSTD = '', $sCOM = @ComSpec & ' /c ' & $sCMD Local $iWin = $iShowFlag ? @SW_SHOW : @SW_HIDE Local $iPID = Run($sCOM, $WorkingDir, $iWin, $iStreamType) While 1 $sTMP = StdoutRead($iPID, False, False) If @error Then ExitLoop If $sTMP <> "" Then $sTMP = StringReplace($sTMP, @CR & @CR, '') $sSTD &= $sTMP Call($sCallBackFunction,$sTMP) ;~ ConsoleWrite($sTMP) Sleep($iDelay) EndIf WEnd While 1 $sTMP = StderrRead($iPID, False, False) If @error Then ExitLoop If $sTMP <> "" Then $sTMP = StringReplace($sTMP, @CR & @CR, '') $sSTD &= $sTMP Call($sCallBackFunction,$sTMP) ;~ ConsoleWrite($sTMP) Sleep($iDelay) EndIf WEnd ;~ If $sSTD <> "" Then ConsoleWrite(@CRLF) Return SetError(@error, @extended, $sSTD) EndFunc ;==>_StreamCMD ; * -----:| Dao Van Trong - TRONG.WIN Func _Wow64FsRedirection($state) If @OSArch = "X64" Then If $state Then ;DllCall("kernel32.dll", "int", "Wow64EnableWow64FsRedirection", "int", 1) DllCall("kernel32.dll", "int", "Wow64RevertWow64FsRedirection", "int", 0) Else ;DllCall('kernel32.dll', 'boolean', 'Wow64EnableWow64FsRedirection', 'boolean', False) DllCall("kernel32.dll", "int", "Wow64DisableWow64FsRedirection", "int", 0) EndIf If @error Then Return SetError(1, 0, 0) Return 1 EndIf EndFunc ;==>_Wow64FsRedirection Edited December 23, 2018 by VIP Regards, Link to comment Share on other sites More sharing options...
ahha Posted December 23, 2018 Author Share Posted December 23, 2018 VIP, I understand most of your code but it looks like it's mainly capturing the STDOUT. I do not see a single STDIN. I'm trying to open cmd.exe and send it commands via STDIN. DIr was just an example to show that the output is not going to the cmd.exe window when I only tapped into STDIN. I do not understand why my simple code is not working. ahha Link to comment Share on other sites More sharing options...
Nine Posted December 23, 2018 Share Posted December 23, 2018 (edited) 55 minutes ago, ahha said: StdinWrite($iPID, "dir{ENTER}") First this statement is wrongly formulated. Does not work like a send function, so you should do StdinWrite($iPID, "dir" & chr(13)) Second I believe cmd.exe doesn't do ConsoleRead for security reasons. Edited December 23, 2018 by Nine “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
FrancescoDiMuro Posted December 23, 2018 Share Posted December 23, 2018 @ahha Regardless your question, if you are trying to list directories from a path, use _FileListToArray(Rec) Click here to see my signature: Spoiler ALWAYS GOOD TO READ: Forum Rules Forum Etiquette Link to comment Share on other sites More sharing options...
ahha Posted December 23, 2018 Author Share Posted December 23, 2018 Nine - thanks for that information. I clipped it just to "dir" to see if it would show in the cmd.exe window and no it does not. So it looks like cmd.exe does not accept STDIN. FrancescoDiMuro - my example of Dir has misdirected some answers - I should have used the example "help". I'm simply trying to get cmd.exe to take STDIN. It appears from Nine that cmd.exe may not accept STDIN. Can anyone confirm that cmd.exe does not accept STDIN? Link to comment Share on other sites More sharing options...
Subz Posted December 23, 2018 Share Posted December 23, 2018 You could just write your commands during execution, for example: #include <AutoItConstants.au3> ;~ Concatenating Commands ;~ & Execute command ;~ && Execute only if previous command in the string was successful ;~ Display Output Run(@ComSpec & ' /k Echo Directory List for: "' & @ProgramFilesDir & '"&Echo.&C:&&Cd\&&Cd "' & @ProgramFilesDir & '"&&Dir') ;~ Run Hidden and Write Output to Scite Local $iCmdPid = Run(@ComSpec & ' /c Echo Directory List for: "' & @WindowsDir & '"&Echo.&C:&&Cd\&&Cd "' & @WindowsDir & '"&&Dir', @WindowsDir & "\System32", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) Local $sOutput = "" While 1 $sOutput &= StdoutRead($iCmdPid) If @error Then ExitLoop WEnd While 1 $sOutput &= StderrRead($iCmdPid) If @error Then ExitLoop WEnd ConsoleWrite($sOutput & @CRLF) Link to comment Share on other sites More sharing options...
ahha Posted December 24, 2018 Author Share Posted December 24, 2018 Subz, Thanks for the alternative Dir approach. If I simply wanted to send "1234" to the cmd.exe window using STDIN - is that possible? ahha Link to comment Share on other sites More sharing options...
TheXman Posted December 24, 2018 Share Posted December 24, 2018 40 minutes ago, ahha said: If I simply wanted to send "1234" to the cmd.exe window using STDIN - is that possible? @ahha Yes. Here's a very simple example. If you run it in SCITE, you will see the output in the output pane. #include <Constants.au3> example() Func example() Local $iPid = Run(@ComSpec, "", Default, $STDIN_CHILD) StdinWrite($iPid, "CD \" & @CRLF) StdinWrite($iPid, "Dir" & @CRLF) StdinWrite($iPid, "1234" & @CRLF) EndFunc CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
ahha Posted December 24, 2018 Author Share Posted December 24, 2018 TheXman, It looks like there is no way to keep the cmd.exe window open and show the STDIN. I changed it to this. I'd prefer to see the output in the cmd.exe window since I did not tap into STDOUT. Any way to keep the cmd.exe window open and show the STDIN or STDOUT in the cmd.exe window? ahha #AutoIt3Wrapper_run_debug_mode=Y #include <Constants.au3> example() MsgBox($MB_SYSTEMMODAL, "Info", "Paused.") Func example() Local $iPid = Run(@ComSpec, "", @SW_MAXIMIZE, $STDIN_CHILD) StdinWrite($iPid, "1234") EndFunc Link to comment Share on other sites More sharing options...
TheXman Posted December 24, 2018 Share Posted December 24, 2018 (edited) 1 hour ago, ahha said: It looks like there is no way to keep the cmd.exe window open and show the STDIN. @ahha I guess it depends on what you are trying to accomplish. If you just want to see the commands getting executed then you could do something like what's below. If you actually need to capture the output, then there are better ways to do it. Opt('WinTitleMatchMode', -2) example() Func example() Const $WINTITLE = "Test Window" Local $hWnd ;Launch CMD and get handle to window Run(@ComSpec & ' /c start "' & $WINTITLE & '" cmd.exe') $hWnd = WinWait($WINTITLE, "", 5) If Not $hWnd Then Exit -1 ;Send commands WinActivate($hWnd) Sleep(1000) Send("CD \{ENTER}") Sleep(1000) Send("1234{ENTER}") EndFunc Edited December 24, 2018 by TheXman CryptoNG UDF: Cryptography API: Next Gen jq UDF: Powerful and Flexible JSON Processor | jqPlayground: An Interactive JSON Processor Xml2Json UDF: Transform XML to JSON | HttpApi UDF: HTTP Server API | Roku Remote: Example Script About Me How To Ask Good Questions On Technical And Scientific Forums (Detailed) | How to Ask Good Technical Questions (Brief) "Any fool can know. The point is to understand." -Albert Einstein "If you think you're a big fish, it's probably because you only swim in small ponds." ~TheXman Link to comment Share on other sites More sharing options...
ahha Posted December 24, 2018 Author Share Posted December 24, 2018 TheXman, I was trying to understand how STDIN worked. I actually want to issue commands via STDIN and read the output via STDOUT for diskpart.exe. However, since diskpart.exe can really mess up your system I was trying to learn it on cmd.exe. I'm stuck at trying to read the "DISKPART>" prompt in the program below. I don't seem to get it via STDOUT. I can copy the window to the clipboard and find it, but that's really a kludge. ahha expandcollapse popup#AutoIt3Wrapper_run_debug_mode=Y ;use this to debug in console window <--- LOOK #include <AutoItConstants.au3> #include <MsgBoxConstants.au3> Opt("WinTitleMatchMode", 2) ;1=start, 2=subStr, 3=exact, 4=advanced, -1 to -4=Nocase $sWinTitle = "diskpart.exe" $sProgram = "diskpart.exe" $iPID = Run(@ComSpec & " /c " & $sProgram, @SystemDir, @SW_HIDE, BitOR($STDERR_CHILD, $STDOUT_CHILD)) If $iPID = 0 Then MsgBox(0, "ERROR", "Failed to start: '" & $sProgram & "'") Exit Else MsgBox(0, "Info", "$iPID = '" & $iPID & "'" & @CRLF & _ "Click on User Account Control (UAC) to allow program to run - it may be winking in the taskbar. Click on OK in this window, then Yes on the UAC.") EndIf WinWait($sWinTitle) WinActivate($sWinTitle) ;need to wait for DISKPART> prompt - which can take some time as disks spin up ;will need to look at stdout $sOutput = "" While 1 $sOutput &= StdoutRead($iPID) If @error Then ; Exit the loop if the process closes or StdoutRead returns an error. MsgBox($MB_SYSTEMMODAL, "ERROR", "StdoutRead returned an EOF. We will exit loop.") ExitLoop EndIf MsgBox($MB_SYSTEMMODAL, "Stdout Read:", "$sOutput = '" & $sOutput & "'") WEnd MsgBox($MB_SYSTEMMODAL, "Exit", "About to exit program.") Exit Link to comment Share on other sites More sharing options...
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