0

If I use the code down below to redirect standardinput and standardoutput to a textbox, everything is working, except for lines which require interactive input from the user. For instance, if you execute the command dir /p c:\windows, the whole content of the directory is displayed. The /p is not being honored. Same thing if you execute a script which requires user input. Here is a small example:

@echo off
set /p "id=Enter  ID: "
Echo The user ID entered is: %id%

When you execute this in a normal cmd window, the output is like this:

Enter  ID: MyUser
The user ID entered is: MyUser

But when I execute the same script through my form with redirected StandardInput and StandardOutput, the result looks like this:

Enter  ID: The user ID entered is: 

So here, the /p to prompt for input is also ignored. Is there any way to make this work the same way as in a standard cmd.exe windows? Thanks for any help in advance!

Kind Regards, Eric

Public Class Form1
    Dim WithEvents P As New Process
    Dim SW As System.IO.StreamWriter
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        P.EnableRaisingEvents = True
        Me.Text = "My title"
        AddHandler P.OutputDataReceived, AddressOf DisplayOutput
        P.StartInfo.CreateNoWindow() = True
        P.StartInfo.UseShellExecute = False
        P.StartInfo.RedirectStandardInput = True
        P.StartInfo.RedirectStandardOutput = True
        P.StartInfo.FileName = "cmd.exe"
        P.StartInfo.Arguments = ""
        P.Start()
        P.SynchronizingObject = Me
        P.BeginOutputReadLine()
        SW = P.StandardInput
        SW.WriteLine()
    End Sub
    Private Sub DisplayOutput(ByVal sendingProcess As Object, ByVal output As DataReceivedEventArgs)
        TextBox1.AppendText(output.Data() & vbCrLf)
    End Sub
    Private Sub Textbox2_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox2.KeyPress
        If e.KeyChar = Chr(Keys.Return) Then
            SW.WriteLine(TextBox2.Text)
        End If
    End Sub
    Private Sub myProcess_Exited(ByVal sender As Object, ByVal e As System.EventArgs) Handles P.Exited
        Me.Close()
    End Sub End Class
Eric van Loon
  • 103
  • 1
  • 9
  • `echo MyUser|Small_example.bat` works, so your batch script works as desired. `ExternalApp.exe` might work complete different though. Try `echo testinput|ExternalApp.exe` to verify the app actually takes STDIN. – Stephan Nov 16 '22 at 09:38
  • Hi @Stephan Sorry, my code was reporting the wrong executable: ExternalApp.exe should be cmd.exe. I updated the code in my question accordingly. If you execute a simple command like `dir /p c:\windows`, the /p is not working. Same for the `set /p` command. Kind regards, Eric – Eric van Loon Nov 16 '22 at 09:47
  • `/p` isn't a "global switch" to be used with any random command. Each command has its own switches, they might look the same but do something completely different. For `set`, `/p` means "ask for user input", in `dir`, it means "show page by page", for `cmd` it means "deactivate autorun", etc. Read the output of `set /?`, `dir /?`, etc. – Stephan Nov 16 '22 at 09:56
  • Hi @Stephan I know that /p for set differs from the /p for the dir command, but neither one is working. In the end I would like to use a different (non-GUI) application which, by default, displays one page of information and than shows the line `more... ( to continue, 'C' to cancel)` Like the /p for a dir, for this application it's also not working anymore when I redirect input and output. Kind regards, Eric – Eric van Loon Nov 16 '22 at 10:04
  • 1
    Whenever someone tries to redirect console in-/output in a Windows UI - obviously trying to launch another (console) application, I wonder what the actual goal is, i.e. what does that console application do? Often there are better ways to achieve the same result. – Hel O'Ween Nov 16 '22 at 10:23
  • Hi @HelO'Ween The application is an administrative command line interface for a backup application. I'm running multiple copies of this application to manage different backup servers. I now have a VB application which simply uses the shell function to start the application and then changes the window title. This Title change however does not work permanently: as soon as you select some text in the started application, the title changes back to the original name. So that's why I'm trying to start the application within my form, so I can permanently change the title. Kind regards, Eric – Eric van Loon Nov 16 '22 at 10:33
  • 1
    I assume the point was you're invoking a relatively low level scripting mechanism from a high level programming language, which should never be necessary. It seems that you're wasting precious time trying to do that, instead of coding it directly in the higher level language. You're also deliberately not divulging the real task, which prevents others from assisting you with the actual one. – Compo Nov 16 '22 at 12:33
  • Hi @Compo I'm just trying to find a way around the fact that I can't persistently change the title of a process started through the Shell function. I tried starting the application and move the window into a panel, which basically works, but gives all kind of [other issues](https://stackoverflow.com/questions/74404425/hook-working-for-notepad-exe-but-not-for-cmd-exe) and redirecting StandardInput and Output also breaks the application's basic functionality, like displaying one page of output at a time. I can't think of any other way... – Eric van Loon Nov 16 '22 at 13:28
  • Well, when you give input to STDIN, it gets processed. You can't choose which part of the script/code should take or ignore it. By doing it manually, you can time the input (respond to prompts). If you want to emulate that, you need to read STDOUT and write code to react to it (like the system "eye/brain/fingers" would). Taking input from STDIN will give input whenever the program would take it (i.e. showing the next "page" before you are able to read the previous) – Stephan Nov 17 '22 at 09:09

0 Answers0