1

Alright, I've spent a few hours bumming around forums and google trying to write this script but I think I'm too much of a noob or doing something too abnormal to Frankenstein my code.

I'm trying to run and executable that scans other files and gives me feedback and prompts. Manually you run this in the command prompt, it does an initial scan, asks what you want to do, you run a repair (could take 5+ min) and then it prompts to run again or close.

Pseudo Code should be:

  • Run EXE ArchiveFile ConfigFile
  • Wait for "Enter a command>"
  • Type 1
  • Wait for "Enter a command>"
  • Type 7
  • Wait for "Enter the print destination>"
  • Type 2
  • Wait for "Enter a command>"
  • Type 9
  • Done

Here is my actual code

'Cycle through each iha file in the chosen folder
for each objFile in objFSO.GetFolder(archiveFolder).files
If LCase(objFSO.GetExtensionName(objFile.Name)) = "iha" Then
    'run the iharchiveInfo.exe with the chosen config and the current archive
        msgbox(chr(34) & exeFile & chr(34) & " " & chr(34) & objfile.path & chr(34) & " " & chr(34) & ArchiveConfig & chr(34) )
        set oExec = Shell.exec("cmd.exe /k "& chr(34) & exeFile & " " & chr(34) & objfile.path & chr(34) & " " & chr(34) & ArchiveConfig)
        do while Not oExec.StdOut.AtEndOfStream
            MsgBox oExec.stdout.Readline
        Loop
        Msgbox("second line")
        oExec.stdin.write chr(34) & exeFile & " " & chr(34) & objfile.path & chr(34) & " " & chr(34) & ArchiveConfig
        Do While oExec.Status = 0
            WScript.Sleep 100
            WScript.StdOut.Write(oExec.StdOut.ReadAll())
            WScript.StdErr.Write(oExec.StdErr.ReadAll())
        Loop
        msgbox ("write")
        oExec.stdin.write 1
        do while Not oExec.StdOut.AtEndOfStream
            MsgBox oExec.stdOut.Readline
        Loop
        oExec.stdin.write 7
exit for
end if
next

It opens cmd prompt but I never get a msgbox with the Readline. Instead, when I close the cmd prompt I then get msgbox Write.

Furbs
  • 49
  • 5
  • In a command prompt you use cscript.exe to run vbscripts as opposed to the non command prompt wscript.exe. Wscript is the default program for vbs scripts. So you need to specify what you want `cscript //nologo "c:\script.vbs"`. See `cscript /?` for help. –  Apr 07 '16 at 23:04
  • I'm using wscript atm. I'm a bit confused by the differences and have been debating with myself which one is appropriate. More confused by msdn site that uses wscript in the example and then says it only works with cscript and wscript will give you an error. https://msdn.microsoft.com/en-us/library/skwz6sz4(v=vs.84).aspx – Furbs Apr 15 '16 at 15:17
  • Cscript is a console program. Wscript is a GUI program. Console programs automatically get a console. –  Apr 15 '16 at 23:43
  • I really just need to know how to get the cmd to show text! Its completely blank but for a while I had it showing text and responses but I dont know why! I added `\k < con` but I cant find any documentation on what `< con` means/does. Now I'm not using the `\k` anymore, so I guess the `< con` doesnt work? IDK. thats the main thing stopping my debugging and making me rely on this forum... – Furbs Apr 16 '16 at 00:15
  • See my list here of punctuation at the console http://stackoverflow.com/questions/31820569/trouble-with-renaming-folders-and-sub-folders-using-batch. In short *you need to run your program with cscript.exe.* –  Apr 16 '16 at 03:27
  • Thanks Noodles. I'm trying to change to cscript but couldnt see any documentation on how to run in vbs and set objects and all so I can add the writeline and readline type commands. Not sure how the link helps though. Could you explain in more detail? – Furbs Apr 16 '16 at 16:06
  • No I can't It really simple. Use CScript to access std in or out. –  Apr 16 '16 at 22:11
  • @Noodles [`WshScriptExec`](https://msdn.microsoft.com/en-us/library/2f38xsxe%28v=vs.84%29.aspx) objects have `StdIn` and `StdOut` regardless of whether the script is run with `cscript.exe` or `wscript.exe`. Only `WScript.StdOut.Write` would require running the script with `cscript.exe`, but it can easily be replaced with `WScript.Echo`, which is interpreter agnostic. – Ansgar Wiechers Apr 16 '16 at 22:15
  • Does anyone have some actual answers? My code works for the first one but just hangs on the line due to the program writing a changing output line. i.e. [89% Done] Is there a different read that can handle this? Even a single character read hangs up. Please help! It's really bugging me. – Furbs May 17 '16 at 05:16

1 Answers1

0

The first thing you do after starting the command is read the output line-by-line until the end of the stream is reached:

Do While Not oExec.StdOut.AtEndOfStream
    MsgBox oExec.stdout.Readline
Loop

However, that only happens when cmd terminates, which it won't, because you started it with the parameter /k. Thus you created a deadlock. The same goes for ReadAll in the next loop.

Depending on what the actual output is use either ReadLine if you can read entire lines

Do
    line = oExec.StdOut.ReadLine
Loop Until line = "something"

or Read single characters until the condition is met where you want to stop reading, e.g.:

str = ""
Do
    str = str & oExec.StdOut.Read(1)
Loop Until str = "something"

Also, at the point where oExec.Status <> 0 the process has already terminated, so writing to StdIn won't work anymore. You need to put the write operation someplace where the descriptor is still open (i.e. oExec.Status = 0).

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
  • Thanks for the info. If I'm not supposed to use /k what can I use instead? also, shouldnt the line `message = readoutput(oExec)` accomplish what you described and show me all the readline's until I see the string "Enter a command"? Is it because I'm using wscript instead of cscript? I do notice that once I close the command window, wscript CPU usage goes to max but I never see any feedback. – Furbs Apr 15 '16 at 15:23
  • Use `/c` or drop the parameter entirely. And there is no function `readoutput()` in VBScript, so no. Using `cscript` instead of `wscript` won't change that. – Ansgar Wiechers Apr 15 '16 at 15:33
  • I mean ReadOutput, as in the sub function I have on there. `Function ReadOutput(p) dim text text = "" Do Until Right(text, Len("Enter a command>")) = "Enter a command>" text = text & p.StdOut.Readline Loop ReadOutput = text End Function` If I drop the parameter entirely, then I just use stdin.write to issue the commands right? Is there a way to see what is happening instead of a blank cmd prompt? Last week, it seemed that adding the parameter `> con` allowed me to see the messages, but today it doesnt seem to work anymore. Edit: Trying to get the script to show as a script – Furbs Apr 15 '16 at 15:53
  • That will only work if `Enter a command>` can be read as a complete line (which I doubt), otherwise the `ReadLine` will block and wait for the current line to be finished. Deadlock. Use `Read` as described in my answer to avoid this. – Ansgar Wiechers Apr 15 '16 at 16:05
  • `set oExec = Shell.exec("cmd.exe ") do while Not oExec.StdOut.AtEndOfStream message = oExec.stdOut.Readline msgbox message & len(message) if len(message) = 0 then oExec.stdIn.Write exeFile & " " & objfile.path & " " & ArchiveConfig elseif message = "Enter a command>" then msgbox "Enter a command!" end if Loop` This doesnt seem to do anything after the blank in the readline. I confirmed that the len(message) = 0 but then it just sits there. Again, how can I make it show text on the actual command line so I can see what is happening instead of relying on msgbox? – Furbs Apr 15 '16 at 16:35
  • Changed to a `oExec.StdIn.WriteLine` and now I'm one step closer. I get a messagebox with my command now, but only silence afterward. – Furbs Apr 15 '16 at 17:08
  • I'm running up against my deadline where I might have to abandon this entirely and run it by hand. Can you still help me? Maybe in PM? If I could just see what the program is doing in the command prompt I'd have some hope. – Furbs Apr 19 '16 at 00:45
  • Sorry Ansgar, I am trying to follow your instructions. I posted that second bit of code trying to verify if I understood everything. I see now that you wanted me to use a `Read` instead of a `Readline`, but even with that modification, I dont get any response after I issue a `writeline`. I dont know what is happening to the command after the `writeline`. I know what happens when I do it manually is that I get a bunch of blanks and them some text ending with a separate line of "Enter a command>" but no messageboxes at all. So the For loop must pause for some reason. – Furbs Apr 19 '16 at 16:25
  • I've confirmed the for For loop pauses. For some reason, I have to have a WriteLine for it to keep going. Currently, after the first command, I have a `oExec.StdIn.Writeline "1"` running every loop, if I move that into an If statement, the whole thing pauses. Also, how does `Read` work when the cmd prompt changes the words? Ex [0% Done], the percentage changes without new characters. `elseif bool1stCmd then if InStr(1,message,"Enter a command>")>0 then msgbox "Enter a command!" end if oExec.stdIn.writeline "1" end if` I get the MsgBox fine, but if I move writeline to it it breaks all – Furbs Apr 19 '16 at 17:44