Jump to content
Sign in to follow this  

Run() command fails with certain commands

Recommended Posts

I have a function that runs a DOS command and returns the output of the command, and it returns the correct data for some commands, bu tnot for others.  I've narrowed it down to this:
"HELP FIND" returns nothing
"HELP DIR" returns several strings of help info.

    Here's my test code:

#include <Constants.au3>

Func test()
    Local $sSTDOUT, $cmd

    $cmd = "C:\Windows\System32\help.exe find"
    ;$cmd = "C:\Windows\System32\help.exe dir"
    $sSTDOUT = _RunDosCmd($cmd)

    ConsoleWrite("+++: $sSTDOUT ==>" & $sSTDOUT & "<==" & @CRLF)
    MsgBox(0, "INFO", "$sSTDOUT ==>" & $sSTDOUT & "<==")
EndFunc   ;==>test

Func _RunDosCmd($sDosCmd)
    Local $cmd, $iPID, $sSTDOUT, $ar, $err

    $cmd = @ComSpec & ' /C ' & $sDosCmd

    ConsoleWrite("+++: $cmd = " & $cmd & @CRLF)

    ; Run the command, capturing the STDOUT data
    $iPID = Run($cmd, "", @SW_HIDE, $STDERR_MERGED)
 ; <== merge STDOUT and STDERR 
    ; Success: the PID of the process that was launched.
    ; Failure: 0 and sets the @error flag to non-zero.
    $err = @error
    ConsoleWrite("+++: $err  = " & $err & " after call to Run()" & @CRLF)
    ConsoleWrite("+++: $iPID = " & $iPID & " after call to Run()" & @CRLF)
    If ($err) Then
        ConsoleWrite("+++: Error returned by Run()" & @CRLF)
        Return ("")

    ; Wait until the process has closed using the PID returned by Run.
    ; Success: 1 and sets @extended to the exit code of the process.
    ; Failure: 0 if the wait timed out. On invalid PID the @error flag
    ; is set to non-zero and @extended is set to 0xCCCCCCCC.
    $err = @error
    ConsoleWrite("+++: @error = " & $err & " after call to ProcessWaitClose()" & @CRLF)

    ; Read the merged STDOUT/STDERR stream of the PID returned by Run.
    $sSTDOUT = ""
    While (1)
        $sSTDOUT &= StdoutRead($iPID)
        $err = @error
        If ($err) Then ExitLoop

    Return ($sSTDOUT)
EndFunc   ;==>_RunDosCmd


Share this post

Link to post
Share on other sites

Hi, AndyS19. Can you please explain the need to mix languages? Just curious if you're just teaching yourself (which is great, welcome!) or if you have some requirement that you use shell commands.

   If you want to find string in a file or files like help find, there are functions in AutoIt to do that: take a look at the File functions in the help file.

   And you can use _FileListToArray or _FileListToArrayRec as a replacement for help dir.

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Share this post

Link to post
Share on other sites
$iPID = run('cmd /c echo | help find' , "" , @SW_HIDE , 0x8)

$sOutput = ""

 While 1
        $sOutput &= StdoutRead($iPID)
        If @error Then

msgbox(0, '' , $sOutput)


Edited by boththose

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Share this post

Link to post
Share on other sites

The reason is speed.  I've written an AutoIT cross reference script.  The script works, but does not take into consideration the #include files.  I'm trying to update the script to do that.

The _FileListToArray or _FileListToArrayRec functions read the Names of a list of files.  Not what I want. I want to fill an array with the lines in the matching files that contain a pattern ("#include").  To use the _fFileList... functions, for each file in the returned array, I would have to read its lines into an array, then use something like _ArrayFindAll() to extract an array of indicies of matching lines, then parse that array to extract each line and add it to another array.

Instead, 1 call to the dos 'FIND "#include" C:\Temp\*.au3' does it in 1 step.

I assume that it's also faster to go the DOS way, unless there's a better way.

Share this post

Link to post
Share on other sites


Regarding your little script, I tried that and it worked.  However, I've been involved with MSDOS for years and I cannot figure out why "ECHO | some-DOS-command" solves the problem.   ECHO by itself just says whether ECHO is on or off (ECHO is on.).  Do you know the reason it works?

Share this post

Link to post
Share on other sites

It doesnt matter what command you use first, echo is just quick everytime.  My guess was that there is something boned with the stream, and that behavior did not exist when piped through a command that opens the stream as expected, but that guess is wrong as evidenced by:

$iPID = run('cmd /c help find | help find' , "" , @SW_HIDE , 0x8)


and the fun palndromic

$iPID = run('cmd /c find help|help find' , "" , @SW_HIDE , 0x8)


Edited by boththose

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

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
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Fortitude
      I have made a program, that opens a folder, and then store the path ("C:\programFiles\etc") in a variable.
      Then i need to open the command panel as administrator, and write  in the stored path, and some other text.

      Can i somehow instantly copypaste the text i needed, instead of writing in the command panel with the Send commands?
      #RequireAdmin #include <MsgBoxConstants.au3> Global Const $sMessage = "Select a folder" ; Display an open dialog to select a file. Global $sFileSelectFolder = FileSelectFolder($sMessage, "") If @error Then MsgBox($MB_SYSTEMMODAL, "", "Nem választottál ki mappát!") Exit EndIf Global $Tiff_path = $sFileSelectFolder & "\TiffChecker_2_32" FileCopy( "C:\TiffChecker_2_32.exe" , $sFileSelectFolder) $CMD = $Tiff_path & " " & $sFileSelectFolder & " /s/d" Run("C:\WINDOWS\system32\cmd.exe") WinWaitActive("C:\WINDOWS\system32\cmd.exe") Send($CMD) Sleep(1000) Send("{ENTER}") sleep(1000) MsgBox(0,"Press OK", "Press OK to continue") FileCopy("C:\Tiffchecker.txt", $sFileSelectFolder) Also, how do i close the command panel, when the program is finished? (usually its under 1 second, so after the send i just put a Sleep function there)
    • By nacerbaaziz
      Hello my friends
      I have an inquiry after your permission
      I found a function to get the special line commands for any operation
      It requires the name of the process to be searched
      I want to use it to know the process
      Is this possible with this function
      Here is the code
      Func commandLineGet($proc, $strComputer=".")
      dim $array[1]
      local $ArrayNumber
      local $oWMI = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strComputer & "\root\cimv2")
      local $oProcessColl = $oWMI.ExecQuery("Select * from Win32_Process where Name= " & '"'& $Proc & '"')
      local $Process
      For $Process In $oProcessColl
      $Process = $Process.Commandline
          ReDim $Array[UBound($Array)+1]
      $ArrayNumber = UBound($Array)-1
      $array[$ArrayNumber] = $Process
      $ArrayNumber = UBound($Array)-1
      $array[0] = $ArrayNumber
      return $array
    • By BlazerV60
      Hello all,
      I've written the code below which launches chrome in incognito mode and then proceeds to go to the autoit website.
      From my understanding, the Run() command is also supposed to output the PID number related to the application that got launched from the Run command.
      However when I run the below lines, it outputs a PID number that is different from the newly launched chrome browser's PID number, does anyone know why and possibly explain how I could retrieve the accurate PID number associated with the newly launched browser?
      Global $iPid = Run(@ComSpec & ' /c start chrome.exe https://www.autoitscript.com/forum/ -incognito' ,"", "") msgbox(0,"",$iPid) Thank you,
    • By mihaijulien
      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  
    • By Baboo85
      Hi all,
      I need to start a script that include:
      - admin privileges
      - multiple cmd commands
      - no bat, no exe, no tmp files created anywhere (especially in the user temp folder)
      In a bat file it would be simple, but users shouldn't see what commands I'm sending.
      Example of the script:
      echo off cls echo. echo I AM A TOOL echo. echo NOTE: echo - note 1 echo - note 2 echo - etc set USER1=0 set COMPUTER1=0 if /i %username% equ user.user ( set USER1=1 set COMPUTER1=1 ) if /i %username% equ another.user set USER1=1 if /i %computername% equ notebook set COMPUTER1=1 if %USER1% EQU 1 ( if %COMPUTER1% EQU 1 ( reg delete "HKLM\SOFTWARE\blablabla" /f ) else ( echo Computer not authorized. Contact assistance.) ) else ( echo User not authorized. Contact assistance.) echo. pause exit With the send("") is a disaster.
      I'm a noob here, so what can I do?
      EDIT: OR ELSE I explain the situation and what I need, so if there is a simple solution I can use that.
      SITUATION: our domain users have Users rights on the machine. Some of them need administrator rights.
      We create a local user with administrator rights, so that the users must insert username and password when asked to run something with administrator rights.
      We have an internal domain group policy that blocks EXE, BAT, COM, TMP files from the user local temp directory, for a security reason (malware). That also blocks most software installation.
      But some users are often out of office, away from workplace and in another country, they need a complete control on their computers.
      WHAT I NEED: I need to check the username and the computer name. If the username is the one with local administrator rights and the computer name is a computer that is qualified to temporary remove the policy, then I need to execute a REG DELETE command with administrator rights.
      I hope I explained myself.
      Thank you very much.
  • Create New...