# VBForums CodeBank > CodeBank - Visual Basic .NET >  Automate Command Prompt Window (CMD), Redirect Output to Application [2003/2005]

## gigemboy

The following code is a sample of how you can automate the command prompt window. It creates a new process in a thread with "cmd" as the filename (which starts a new command prompt window). A thread was used (although not required) as a preventative measure just in case the CMD window would hang for some reason. If it hangs and it is not started on a thread, then your application would hang as well until the cmd window was closed or killed.

The Process.StartInfo property contains a .RedirectStandardInput and .RedirectStandardOutput property that allows you to redirect the input and output associated with the process. The StandardOutput and StandardInput properties of the Process class are streamreaders and streamwriters, respectively, which you can set in order to send and receive the data. 

The code below simply runs a command that is listed in a textbox, and outputs the results into a textbox. The entire project file is included below in the attachments.

*EDIT - The original example below has a problem in the threading. See the 2005 example code in post 10 that corrects this issue*

VB Code:
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
        Dim CMDThread As New Threading.Thread(AddressOf CMDAutomate)
        CMDThread.Start()
End Sub
Private Sub CMDAutomate()
        Dim myprocess As New Process
        Dim StartInfo As New System.Diagnostics.ProcessStartInfo
        StartInfo.FileName = "cmd" 'starts cmd window
        StartInfo.RedirectStandardInput = True
        StartInfo.RedirectStandardOutput = True
        StartInfo.UseShellExecute = False 'required to redirect
        myprocess.StartInfo = StartInfo
        myprocess.Start()
        Dim SR As System.IO.StreamReader = myprocess.StandardOutput
        Dim SW As System.IO.StreamWriter = myprocess.StandardInput
        SW.WriteLine(txtCommand.Text) 'the command you wish to run.....
        SW.WriteLine("exit") 'exits command prompt window
        txtResults.Text = SR.ReadToEnd 'returns results of the command window
        SW.Close()
        SR.Close()
End Sub

----------


## RobDog888

Very nice example Gigemboy!  :Thumb:

----------


## nbmprivat

I get an "InvalidOperationException"...

----------


## gigemboy

The below code adds one line, with the "CreateNoWindow" property of the StartInfo object set to "True", this way the command window doesnt open up at all... (Thanks to jmcilhinney)

VB Code:
Dim myprocess As New Process
        Dim StartInfo As New System.Diagnostics.ProcessStartInfo
        StartInfo.FileName = "cmd" 'starts cmd window
        StartInfo.RedirectStandardInput = True
        StartInfo.RedirectStandardOutput = True
        StartInfo.UseShellExecute = False 'required to redirect
        StartInfo.CreateNoWindow = True '<---- creates no window, obviously
        myprocess.StartInfo = StartInfo
        myprocess.Start()
        Dim SR As System.IO.StreamReader = myprocess.StandardOutput
        Dim SW As System.IO.StreamWriter = myprocess.StandardInput
        SW.WriteLine(txtCommand.Text) 'the command you wish to run.....
        SW.WriteLine("exit") 'exits command prompt window
        txtResults.Text = SR.ReadToEnd 'returns results of the command window
        SW.Close()
        SR.Close()

----------


## Jan1503

Hi!

Is there a way to execute this on a remote computer, like PSExec from SysInternals?

I need to execute a "CMD" on a remote machine and redirect the input/output to my console.

I know PSExec can do that but I want it my way  :Smilie: 

Thanks.

----------


## gigemboy

I know its been a while since this post, but I will go ahead and reply with "I do not know of a way to do that" (which probably was assumed since no replies). This code just shows how to automate the prompt on your local machine.

----------


## sonitin

Hello,

Can you please help me understand how can I take output without exiting the process. It seems this sample (posted on many sites ) returns the input to the input stream only when the process exits. Is there anyway we can make a communication.

I need to do the following for using a public library:

Send in one command to command prompt based exe.
Read its output from the command prompt.
Without terminating i have to send another command based on previous output and read output again.
I have to do this iteratively.

Will be glad if you can help out.
Regards,

----------


## nbrege

I downloaded the project files (CmdRedirect.zip) in your original post & ran it in VB2005 Express & I get the following error:

_Cross-thread operation not valid: Control 'txtResults' accessed from a thread other than the thread it was created on._

What do I need to do to fix this?  Thanks...

----------


## gigemboy

Yeah I noticed that a long time ago, just haven't updated the code. Its because in that code it is trying to update a control directly from within the thread, which is a no-no. In 2003 you can get away with it sometimes, but in 2005 you can't. You can try running the code without using a thread, it should still work, but the form will hang until the process is complete. It would need to be changed to do "correct" threading, either using a background worker or manually by invoking a delegate in the thread to update the text. I'll post the updated code when I get around to it  :Smilie:

----------


## gigemboy

Here is the updated code, with a delegate used to update the text. Tested in 2005 and the code worked fine. There is an attachment of the new 2005 project example at the end of the post as well.

VB Code:
'Form code from sample project
     Private Results As String
    Private Delegate Sub delUpdate()
    Private Finished As New delUpdate(AddressOf UpdateText)
     Private Sub UpdateText()
        txtResults.Text = Results
    End Sub
     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim CMDThread As New Threading.Thread(AddressOf CMDAutomate)
        CMDThread.Start()
    End Sub
     Private Sub CMDAutomate()
        Dim myprocess As New Process
        Dim StartInfo As New System.Diagnostics.ProcessStartInfo
        StartInfo.FileName = "cmd" 'starts cmd window
        StartInfo.RedirectStandardInput = True
        StartInfo.RedirectStandardOutput = True
        StartInfo.UseShellExecute = False 'required to redirect
        StartInfo.CreateNoWindow = True 'creates no cmd window
        myprocess.StartInfo = StartInfo
        myprocess.Start()
        Dim SR As System.IO.StreamReader = myprocess.StandardOutput
        Dim SW As System.IO.StreamWriter = myprocess.StandardInput
        SW.WriteLine(txtCommand.Text) 'the command you wish to run.....
        SW.WriteLine("exit") 'exits command prompt window
        Results = SR.ReadToEnd 'returns results of the command window
        SW.Close()
        SR.Close()
        'invokes Finished delegate, which updates textbox with the results text
        Invoke(Finished)
    End Sub

----------


## uniquegodwin

Hi bud,
I made some more changes or updates..
I made it synchronous to the commands running on the command prompt so theres no delay for it to come on the rich text box.
The command prompt doesnt exit everytime now..
Thats all..
Hope it helps
Take a look..Ive attached it.
Thanks

----------


## gigemboy

After typing a few commands, your "edited" example doesn't work anymore... it hangs up and no results are shown in the box...

----------


## w8taminute

How would I get the command prompt to open in my parent form?

----------


## TTn

I changed this a bit, but the main thing wrong was the "results of the command window". 




```
   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim CMDThread As New Threading.Thread(AddressOf CMDAutomateThread)
        CMDThread.Start()
    End Sub
    Private Sub CMDAutomateThread()
        TextBox1.Text = CMDAutomate("date", "12/31/2099") 'Set textbox to string return
    End Sub

    Private Function CMDAutomate(ByVal cmdString As String, ByVal cmdString2 As String) As String
        Dim myprocess As New Process
        Dim StartInfo As New System.Diagnostics.ProcessStartInfo
        Dim s As String = ""
        StartInfo.FileName = "cmd" 'starts cmd window        
        StartInfo.RedirectStandardInput = True
        StartInfo.RedirectStandardOutput = True
        StartInfo.UseShellExecute = False 'required to redirect    
        ' StartInfo.CreateNoWindow = True 'creates no cmd window         
        myprocess.StartInfo = StartInfo
        myprocess.Start()
        Dim SR As System.IO.StreamReader = myprocess.StandardOutput
        Dim SW As System.IO.StreamWriter = myprocess.StandardInput
        SW.WriteLine(cmdString) 'the commands you wish to run.....      
        SW.WriteLine(cmdString2)
        s = SR.ReadToEnd 'returns results of the command window  before exit
        SW.WriteLine("exit") 'exits command prompt window      
        SW.Close()
        SR.Close()
        Return s
    End Function
```

Thanks for the example!

----------


## SlumberMachine

> I changed this a bit, but the main thing wrong was the "results of the command window". 
> 
> 
> 
> 
> ```
>    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
>         Dim CMDThread As New Threading.Thread(AddressOf CMDAutomateThread)
>         CMDThread.Start()
> ...


DO NOT TRY THIS CODE! It will change your system date. Yeah, maybe I'm an idiot for not knowing that "date 12/31/2099" is the command to set your system to the year 2099, but still, just warning people out there.

----------


## TTn

SlumberMachine, 

Yeah maybe you are.
Usually everyone would look at the code to see what it means, and so yeah it's a no-brainer.  There are comments throughout it.
I don't appreciate you posting things like:
"DONT TRY TTN'S MALICIOUS CODE".

By all means, everyone can try my/gigemboy's code, with the command you want, in the window.  
Duh.

----------


## SlumberMachine

> SlumberMachine, 
> 
> Yeah maybe you are.
> Usually everyone would look at the code to see what it means, and so yeah it's a no-brainer.  There are comments throughout it.
> I don't appreciate you posting things like:
> "DONT TRY TTN'S MALICIOUS CODE".
> 
> By all means, everyone can try my/gigemboy's code, with the command you want, in the window.  
> Duh.


Look, I didn't mean to hurt your feelings,  but what you posted was not only wrong, but malicious, and you know it. And I'm just trying to do what is right and warn people, like myself that are trying to learn.  You didn't comment that line of the code. If you didn't intend for it to be malicious then  why not do a "dir c:" instead? I've never heard or ever had to use a date command in dos and just figured it would return something interesting like the number of days until that date or something. Don't get defensive, just do what is right for others and admit the mistake and accept the punishment (which is someone else warning others not to use a bit of code).

No need to take it all personal or anything, and if you want to think that I'm an ignorant idiot, that doesn't know crap about dos commands or vb that is fine with me. It sounds like you have an awesome wealth of knowledge in this area and I'm sure you are way better then me. but.. the fact is: 

you posted dangerous code, which did screw up someones system, and others should be warned to not make the same mistake when trying it out.

----------


## TTn

You could have, and should have simply stated that the command, will adjust your clock.  
If anyone intends to use the command window, then they'd be putting in their own command.  Your point is completely mute, because everyone knows that.

I did comment that piece in fact.
"'the commands you wish to run.....  "

That's not malicious, because you could enter any command you like.
I can't think of one thing that can be maliciously affected, by changing the time anyway.  It didn't happen, you can just change the time back.  Woopie.  No systems were screwed up, as you implied, and lied about.

I hate liars, that try to make a point by testifying false data.
I really wish the moderators would ban counter-productive members like you. :wave:   :Smilie:

----------


## SlumberMachine

These are the facts:

It did screw up someones computer (mine) and took a few hours, after setting the date back to the correct time to repair the damage which included:

Outlook Calender - had to have all appointments reset since they all expired.
VB Express 2005 - All projects would not compile and would use the last compile since the date change.
Trend Micro Client server security agent failed to run until I reinstalled.

As for lying, this code here:



```
  Private Sub CMDAutomateThread()
        TextBox1.Text = CMDAutomate("date", "12/31/2099") 'Set textbox to string return
    End Sub
```

Does not have any comment that states what those commands do.

If you weren't so set on judging your self worth by your reputation on an internet forum you could save a lot of counter production here. It's funny how you get so defensive over this whole thing. You just need to chill and stop caring so much about what others think of you and your knowledge of computers.

I'm not going to check this thread anymore, best of luck to you.

----------


## TTn

That line sets the textbox contents, to the return value of the function.
It seems you don't know what a function is, otherwise you would have realized where to find this comment within it:




> "'the commands you wish to run..... "


Since you didn't wish to run my date command example, then it was your mistake.  Almost all examples have a spot, where you put the custom parameter that you want.  The place to put this customization was clearly marked, but you probably glanced over it without thinking or understanding.

----------


## Galdhrim

> Here is the updated code, with a delegate used to update the text. Tested in 2005 and the code worked fine. There is an attachment of the new 2005 project example at the end of the post as well.
> 
> VB Code:
> 'Form code from sample project
>      Private Results As String
>     Private Delegate Sub delUpdate()
>     Private Finished As New delUpdate(AddressOf UpdateText)
>      Private Sub UpdateText()
>         txtResults.Text = Results
> ...


  I executed the code provided, with the following command:
gpg --verify  "C:\Documents and Settings\Javier\Escritorio\UDP2006\Semestre5\Negocios en Internet\Catalogo de la tienda\comando correcto.txt.asc"

I get the following output in the textbox:



> Microsoft Windows XP [Versi¢n 5.1.2600]
> (C) Copyright 1985-2001 Microsoft Corp.
> 
> C:\Documents and Settings\Javier\Escritorio\UDP2006\Semestre5\Negocios en Internet\2005CMDExample\2005CMDExample\2005CMDExample\bin\Release>gpg --verify  "C:\Documents and Settings\Javier\Escritorio\UDP2006\Semestre5\Negocios en Internet\Catalogo de la tienda\comando correcto.txt.asc"
> 
> C:\Documents and Settings\Javier\Escritorio\UDP2006\Semestre5\Negocios en Internet\2005CMDExample\2005CMDExample\2005CMDExample\bin\Release>exit


 But if I enter the same string, manually, at the cmd console, I get the following (and desired) output:




> Microsoft Windows XP [Versión 5.1.2600]
> (C) Copyright 1985-2001 Microsoft Corp.
> 
> C:\Documents and Settings\Javier>gpg --verify  "C:\Documents and Settings\Javier
> \Escritorio\UDP2006\Semestre5\Negocios en Internet\Catalogo de la tienda\comando
>  correcto.txt.asc"
> gpg: Firmado el 07/08/08 22:24:37
> gpg:                usando RSA clave 0xE89F63D4
> gpg: Firma correcta de "Faramir_cl <faramir0cl@gmail.com>"
> ...


  This last output (the one I get if I enter the command manually) is what I need... how can I get VB to let me do that?

  I need to make this work... and I am running out of time...  :Sick:

----------


## Rock_Vacirca

This is one of the most useful pieces of code I have come across in the Codebank.

A quick question: The code in post #10 always clears the TextBox first, then updates it with the results of the next command. How could this 'clear first' be inhibited, so the TextBox shows continuous output, as a normal cmd would do?

----------


## TTn

> This is one of the most useful pieces of code I have come across in the Codebank.
> 
> A quick question: The code in post #10 always clears the TextBox first, then updates it with the results of the next command. How could this 'clear first' be inhibited, so the TextBox shows continuous output, as a normal cmd would do?


Post #10 has an error, because it exits prematurely, before reading the content.  Take a quick look at post #14, but run your own command.

Do you want the window not to exit?  You don't have to command the exit.
How many commands do you wish to run?

You could append the textbox after each command, by doing something like this:


```
SW.WriteLine("A command here")
TextBox1.Text &= SR.ReadToEnd
SW.WriteLine("Another command here")
TextBox1.Text &= SR.ReadToEnd
```

----------


## Rock_Vacirca

I solved the clear first problem by changing:



```
Private Sub CMDAutomateThread()
        txtResults.Text = Results
    End Sub
```

to 



```
Private Sub UpdateText()
        txtResults.AppendText(Results)
        txtResults.SelectionStart = txtResults.Text.Length ' this line and the next
        txtResults.ScrollToCaret() 'sets the scrollbar to the bottom
    End Sub
```

I also wanted to see the latest data in the textbox, and scroll back to see older data, hence the other two lines of code.

I do not want the cmd window to close, I want it, and 5 others, to stay open. I am adapting this code to open 6 server windows (cmd-like) as part of a GUI for a Virtual World (here is the work-in-progress)

My textboxes should act in the same way as these server (cmd console) windows, i.e. I can see all status messages, and I can enter commands and see the results.

While testing, I will send commands in the way the code in this thread uses, but later I will change it to specific commands behind button clicks, or Menu options.

I am currently working on a way to set a rolling buffer size for the TextBox, so it does not get too big. 

Your alternative code in post #14 looks very interesting indeed. I will have a play with that tomorrow.

Rock

----------


## Rock_Vacirca

I am a little bit confused about the purpose of the following line in the code:

SW.Writeline("exit")

What is this line for? The comment says 'exits command prompt window, but does this mean that the cmd window is now closed, or what?

What I need is for the cmd window to remain open at all times, displaying its messages in my TextBox, accepting and executing commands, and displaying the results, until I close the application. 

What do I need to do to the code to achieve this?

TIA

Rock

----------


## Cyb3rH4Xter

@Rock Vacirca
Remove that line to have the cmd window open.

I want to use this code to make a better console for my cs server.
The cs server can't be run with the DEP (Data Execution Protection), so i have disabled the dep for the file. When i run it from my shortcut on the desktop the server runs fine, starts a cmd-like window. But when i run it via your code, it runs with DEP, can i disable DEP in the .StartInfo or?
But when i change the .filename to the path to the file (hlds.exe)

----------


## SoulCollector

is this to control cmd ??

----------


## HighOnTek

> @Rock Vacirca
> Remove that line to have the cmd window open.
> 
> I want to use this code to make a better console for my cs server.
> The cs server can't be run with the DEP (Data Execution Protection), so i have disabled the dep for the file. When i run it from my shortcut on the desktop the server runs fine, starts a cmd-like window. But when i run it via your code, it runs with DEP, can i disable DEP in the .StartInfo or?
> But when i change the .filename to the path to the file (hlds.exe)


To disable DEP, you can use this command in the cmd prompt... or enter in this app and it will load just the same.



```
bcdedit.exe /set {current} nx AlwaysOff
```

You should only need to disable DEP once... so no need to disable every time you load app.... therefor no need to input this into source.  :Wink: 

Reboot PC once you've run the above code... your done.

By the way, this is a great thread... nice code, will make good use of it one day.  :Smilie: 

HTK

----------


## wild_bill

My application freezes everytime I try to read the output, any ideas?



```
Private Function GetChannelStatus(ByVal channelName As String) As String

    Dim StartInfo As New System.Diagnostics.ProcessStartInfo("C:\Program Files\IBM\WebSphere MQ\bin\runmqsc.exe")

    StartInfo.RedirectStandardInput = True
    StartInfo.RedirectStandardOutput = True
    StartInfo.UseShellExecute = False 'required to redirect
    StartInfo.CreateNoWindow = True 'creates no cmd window

    Dim myprocess = Process.Start(StartInfo)

    Dim results = ""

    Dim SR As System.IO.StreamReader = myprocess.StandardOutput
    Dim SW As System.IO.StreamWriter = myprocess.StandardInput
    SW.WriteLine(String.Format("DISPLAY CHSTATUS({0})", channelName))
    System.Windows.Forms.MessageBox.Show("here1")
    results = SR.ReadToEnd 'returns results of the command window
    System.Windows.Forms.MessageBox.Show("here2")
    SW.WriteLine("end")
    SW.Close()
    SR.Close()

    Dim statusExpression As New Regex("(?<=STATUS\()\w+(?=\))")
    Return statusExpression.Match(results).Value

End Function
```

----------


## hellas07

Hey, thank you very much for the code but i am having a problem.
I want to send a CTRL-C event to the DOS app, since it's the only way to
interrupt it. 
I tried to send a CTRL-C event using the "ConsoleCtrlEvent" API, with no
success. I tried both :

****    Const CTRL_C_EVENT As Integer = 0
    Const CTRL_BREAK_EVENT As Integer = 1

    <DllImport("kernel32.dll")> _
    Private Shared Function GenerateConsoleCtrlEvent(ByVal dwCtrlEvent As Integer, ByVal dwProcessGroupId As Integer) As Boolean
    End Function  ****

GenerateConsoleCtrlEvent(ConsoleCtrlEvent.CTRL_C, 0)
and
GenerateConsoleCtrlEvent(ConsoleCtrlEvent.CTRL_C, myprocess.id)
But none of them seems to work.

So if someone can help me, I'd be very grateful.
Thank you in advance !

----------


## vb2008

Old thread however I love the code except for the fact that one part is just not working for me.  When I execute this the cmd window sticks and nothing happens till I close the cmd window then it continues.  For the life of me I can not figure out how to get past this.



```
Private Sub NDS_Start_SIT_Logic()
        Dim NDS_Start_SIT_Putty_Command_Value As String = "C:\plink.exe " + Unix_User_Name + "@spongeshrimp.grhq.XXX.com -pw " + Unix_User_Password
        Dim myprocess As New Process
        Dim StartInfo As New System.Diagnostics.ProcessStartInfo()
        StartInfo.FileName = "cmd.exe"
        StartInfo.RedirectStandardInput = True
        StartInfo.RedirectStandardOutput = True
        StartInfo.UseShellExecute = False
        StartInfo.CreateNoWindow = False 'creates no cmd window
        myprocess.StartInfo = StartInfo
        myprocess.Start()
        Dim SR As System.IO.StreamReader = myprocess.StandardOutput
        Dim SW As System.IO.StreamWriter = myprocess.StandardInput
        SW.WriteLine(NDS_Start_SIT_Putty_Command_Value)
        SW.WriteLine("ps -ef | grep nds")
        SW.WriteLine("exit")
        Results = SR.ReadToEnd
        SW.Close()
        SR.Close()
        Invoke(NDS_Start_SIT_Updater)
    End Sub
```


The line that it sticks on is the SR.ReadToEnd.


```
Results = SR.ReadToEnd
```

Again like I said the code works but it can not seem to get past the ReadToEnd till you X out of the cmd window.

Does anyone know how to correct this?  Thanks!

----------


## tekatsu

ok im running vb 10 i tried using the code and it still doesnt work for me it just comes up as blank on the results am i doing something wronge?

----------


## jrgme

> ok im running vb 10 i tried using the code and it still doesnt work for me it just comes up as blank on the results am i doing something wronge?


I am interested in this as well. Is there updates to the code to work in VB10?

----------


## Nightwalker83

> ok im running vb 10 i tried using the code and it still doesnt work for me it just comes up as blank on the results am i doing something wronge?





> I am interested in this as well. Is there updates to the code to work in VB10?


Try this attachment!

----------


## jrgme

Thanks man! I am really new to this stuff (although like many some background in coding). I want to run two commands through the command line. I need to first set the directory to a folder such as c:\HTDP and then call a program and file in that directory so htdp < c:\ngs\htdp\sample.txt. The file will later be set as a variable but this process will remain the same so I would like to hard code it into the background. Any suggestions?

I am later going to write code that manipulates the text file before to a specific format from variables and after to another specific format.

----------


## bvrider1

I tried this and I don't get any results in the textbox? 

Any Ideas why? 

I tried the original one and it quickly displays the dos screen and goes away. 

I'm more concern withe the version 10 not working. 

Thanks for the help. 




> Try this attachment!

----------


## Nightwalker83

If it displays incorrectly on your computer not matter which version of the project you are using you are most likely doing something wrong.

Which version of VS are you using? Have you modified any of the code from either of the above projects before you attempt to run them? If so which parts of the code do you modify?

----------


## bvrider1

That is the thing, I have not modified anything yet. I compiled it to see how it works and just test it out. 

All I did was extract the zip files and launch it in VS 2010.  No errors but when I run it nothing happens. 






> If it displays incorrectly on your computer not matter which version of the project you are using you are most likely doing something wrong.
> 
> Which version of VS are you using? Have you modified any of the code from either of the above projects before you attempt to run them? If so which parts of the code do you modify?

----------


## Nightwalker83

This is the output I get when upgrading uniquegodwin's code to VS2010:




> Microsoft Windows [Version 6.1.7601]
> Copyright (c) 2009 Microsoft Corporation.  All rights reserved.
> 
> 20/04/2012  08:16 PM    <DIR>          .
> 20/04/2012  08:16 PM    <DIR>          ..
> 20/04/2012  08:16 PM            23,552 2010CMDExample.exe
> 20/04/2012  08:16 PM            46,592 2010CMDExample.pdb
> 20/04/2012  08:17 PM            11,600 2010CMDExample.vshost.exe
> 20/04/2012  08:16 PM               691 2010CMDExample.xml
> ...


Did you follow the example in post #1? That is, type "Dir" to the "txtCommand" textbox and click the "Send" button.

----------


## bvrider1

Working now. I didn't do anything different  :Ehh: 

My mind was already in weekend mode. Thanks though




> This is the output I get when upgrading uniquegodwin's code to VS2010:
> 
> 
> 
> Did you follow the example in post #1? That is, type "Dir" to the "txtCommand" textbox and click the "Send" button.

----------


## wbollen

I needed to do some cmd stuff today and found this *thread*  :Wink:  useful. I ended up embedding the example in this post into a class which makes it easy to use. At least I think so...



```
Class CMDThread
    Public Param As String
    Public isFinished As Boolean = False
    Private tr As Thread = Nothing
    Private results As String = ""
    Private myprocess As New Process
    Private StartInfo As New System.Diagnostics.ProcessStartInfo
    Public Function Start() As Thread
        StartInfo.FileName = "cmd" 'starts cmd window
        StartInfo.RedirectStandardInput = True
        StartInfo.RedirectStandardOutput = True
        StartInfo.UseShellExecute = False 'required to redirect
        StartInfo.CreateNoWindow = True 'creates no cmd window
        myprocess.StartInfo = StartInfo
        myprocess.Start()
        tr = New Thread(AddressOf Me.work)
        tr.Start()
        Return tr
    End Function
    Public Sub Join()
        tr.Join()
    End Sub
    Public Function GetOutput() As String
        GetOutput = results
        results = "" 'Not sure if this is safe while thread is executing... seem to work
    End Function
    Private Sub work()
        myprocess.StandardInput.WriteLine(Param & vbCrLf & "exit") 'the command you wish to run, with an exit at the end to terminate process after run
        While myprocess.StandardOutput.EndOfStream = False
            results += myprocess.StandardOutput.ReadLine() & vbCrLf
        End While
        isFinished = True
    End Sub
End Class
```

To launch a couple of threads and use join to wait for the last one:



```
       
        Dim threadA, threadB As New CMDThread
        Dim res As String = ""
        threadA.Param = "ping -n 2 127.0.0.1"
        threadB.Param = "tracert -h 10 -d -w 30 vbforums.com"
        threadA.Start()
        threadB.Start()

        While Not threadA.isFinished
            res = threadA.GetOutput
        ...do stuff...
        End While
'A is finished
        If Not threadB.isFinished Then
            threadB.Join() 'wait until B is finished
        End If
        res = threadB.GetOutput
```

Cheers!

----------


## Brodacious

Hello,

This thread has been a huge help to me. I wanted to do something very simple with the CMD prompt that would save me a ton of time. I busted out my 10 year old VB book and felt a bit overwhelmed about how much I had forgotten.

Thanks for the code, it rules. I am having one small snytax issue which I'm sure you guys could knock out of the park.

I am trying to use the txt box to define a variable, then run some commands using that variable. This will be used to check SRV records for SIP domains.
So "nslookup -quertype=srv _h323ls._udp.SIPDOMAIN" Where SIPDOMAIN is pulled from the txtcommand box.



```
 Private Sub CMDAutomate()
        Dim sipdomain As TextBox = txtCommand
        Dim myprocess As New Process
        Dim StartInfo As New System.Diagnostics.ProcessStartInfo
        StartInfo.FileName = "cmd" 'starts cmd window
        StartInfo.RedirectStandardInput = True
        StartInfo.RedirectStandardOutput = True
        StartInfo.UseShellExecute = False 'required to redirect
        StartInfo.CreateNoWindow = True 'creates no cmd window
        myprocess.StartInfo = StartInfo
        myprocess.Start()
        Dim SR As System.IO.StreamReader = myprocess.StandardOutput
        Dim SW As System.IO.StreamWriter = myprocess.StandardInput
         SW.WriteLine("nslookup -querytype=srv _h323ls._udp.", &sipdomain) 'the command you wish to run.....
        SW.WriteLine("nslookup -querytype=srv _h323cs._tcp.", sipdomain) 'the command you wish to run.....
        SW.WriteLine("nslookup -querytype=srv _sip._tcp.", sipdomain) 'the command you wish to run.....
        SW.WriteLine("nslookup -querytype=srv _sip._udp.", sipdomain) 'the command you wish to run.....
        SW.WriteLine("nslookup -querytype=srv _sips._tcp.", sipdomain) 'the command you wish to run.....

        SW.WriteLine("exit") 'exits command prompt window
        Results = SR.ReadToEnd 'returns results of the command window
        SW.Close()
        SR.Close()
        'invokes Finished delegate, which updates textbox with the results text
        Invoke(Finished)
    End Sub
```

Also it seems that it hangs after one run and I have to restart to run a 2nd command each time. 

Thanks for your time!

----------


## Brodacious

ok Fixed my issue with the help of Teycho0 on #VB on DALnet, thanks bud.



vb Code:
Private Sub CMDAutomate()        'Dim sipdomain As TextBox = txtCommand        Dim myprocess As New Process        Dim StartInfo As New System.Diagnostics.ProcessStartInfo        StartInfo.FileName = "cmd" 'starts cmd window        StartInfo.RedirectStandardInput = True        StartInfo.RedirectStandardOutput = True        StartInfo.UseShellExecute = False 'required to redirect        StartInfo.CreateNoWindow = True 'creates no cmd window        myprocess.StartInfo = StartInfo        myprocess.Start()        Dim SR As System.IO.StreamReader = myprocess.StandardOutput        Dim SW As System.IO.StreamWriter = myprocess.StandardInput        SW.WriteLine("nslookup -querytype=srv _h323ls._udp." & txtCommand.Text) 'Checks the H323ls SRV record        SW.WriteLine("nslookup -querytype=srv _h323cs._tcp." & txtCommand.Text) 'Checks the H323cs SRV record        SW.WriteLine("nslookup -querytype=srv _sip._tcp." & txtCommand.Text) 'Checks the sip.tcp SRV record        SW.WriteLine("nslookup -querytype=srv _sip._udp." & txtCommand.Text) 'Checks the sip.udp SRV record        SW.WriteLine("nslookup -querytype=srv _sips._tcp." & txtCommand.Text) 'Checks the sips.tcp SRV record        SW.WriteLine("exit") 'exits command prompt window        Results = SR.ReadToEnd 'returns results of the command window        SW.Close()        SR.Close()        'invokes Finished delegate, which updates textbox with the results text        Invoke(Finished)    End Sub

----------


## sentinel0

Thank you for the great little piece of code I have a project that currently pops the cmd and bugs the crap out of me. I took the code for VS10 and created a new project for VS11 for what ever reason the VS10 example would not open the solution or project  :Ehh:  I tested it with dir, netdom, and a couple others all seem to work as the code was written for. It should be attached to this post.

----------


## sanjeev467

> The below code adds one line, with the "CreateNoWindow" property of the StartInfo object set to "True", this way the command window doesnt open up at all... (Thanks to jmcilhinney)
> 
> VB Code:
> Dim myprocess As New Process
        Dim StartInfo As New System.Diagnostics.ProcessStartInfo
        StartInfo.FileName = "cmd" 'starts cmd window
        StartInfo.RedirectStandardInput = True
        StartInfo.RedirectStandardOutput = True
        StartInfo.UseShellExecute = False 'required to redirect
        StartInfo.CreateNoWindow = True '<---- creates no window, obviously
        myprocess.StartInfo = StartInfo
        myprocess.Start()
        Dim SR As System.IO.StreamReader = myprocess.StandardOutput
        Dim SW As System.IO.StreamWriter = myprocess.StandardInput
        SW.WriteLine(txtCommand.Text) 'the command you wish to run.....
        SW.WriteLine("exit") 'exits command prompt window
        txtResults.Text = SR.ReadToEnd 'returns results of the command window
        SW.Close()
        SR.Close()


i'm nt able to get the result of the command window on my form

----------


## sanjeev467

> i'm nt able to get the result of the command window on my form


Plz someone answer it

----------


## sanjeev467

i'm nt able to get the output of command window to my form plz sm1 help

----------


## RobDog888

You may want to create your own thread and reference this one. Also may want to actually describe your problem vs staating "it doesnt work"  :Wink:

----------


## sanjeev467

> You may want to create your own thread and reference this one. Also may want to actually describe your problem vs stating "it doesnt work"


yes it doesn't work, i've tried many times

----------


## sanjeev467

i have tried the following code:
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click

        path = "javac " + TextBox1.Text + ".java"
        runpath = "java " + TextBox1.Text
        TextBox2.Text = "C:\Users\sanjeev\Desktop\sanju\SEM-VII\Cloud\javacodes\" + TextBox1.Text

        Dim sf As New System.IO.StreamWriter(TextBox2.Text & ".java")
        sf.Write(RichTextBox1.Text)
        sf.Close()


        Dim CMDThread As New Threading.Thread(AddressOf CMDAutomate)
        CheckForIllegalCrossThreadCalls = False
        CMDThread.Start()
    End Sub
    Private Sub CMDAutomate()
        Dim myprocess As New Process
        Dim StartInfo As New System.Diagnostics.ProcessStartInfo
        StartInfo.FileName = "cmd" 'starts cmd window
        StartInfo.RedirectStandardInput = True
        StartInfo.RedirectStandardOutput = True
        StartInfo.UseShellExecute = False 'required to redirect
        StartInfo.CreateNoWindow = True
        myprocess.StartInfo = StartInfo
        myprocess.Start()
        Dim SR As System.IO.StreamReader = myprocess.StandardOutput
        Dim SW As System.IO.StreamWriter = myprocess.StandardInput
        SW.WriteLine("set path=C:\Program Files\Java\jdk1.7.0\bin") 'the command you wish to run.....
        SW.WriteLine("cd C:\Users\sanjeev\Desktop\sanju\SEM-VII\Cloud\javacodes\") 'the command you wish to run.....
        SW.WriteLine(path) 'the command you wish to run.....
        MsgBox(path)


        StartInfo.FileName = "cmd" 'starts cmd window
        SW.WriteLine(runpath)
        'RichTextBox2.Text = SR.ReadToEnd 'returns results of the command window
        SW.WriteLine("exit")
        RichTextBox2.Text = SR.ReadToEnd 'returns results of the command window
        SW.Close()
        SR.Close()
    End Sub

while debugging i wrote a java code and saved it and have run it
and i got the following output:

Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\Users\sanjeev\Documents\Visual Studio 2010\Projects\WindowsApplication2\WindowsApplication2\bin\Debug>set path=C:\Program Files\Java\jdk1.7.0\bin

C:\Users\sanjeev\Documents\Visual Studio 2010\Projects\WindowsApplication2\WindowsApplication2\bin\Debug>cd C:\Users\sanjeev\Desktop\sanju\SEM-VII\Cloud\javacodes\

C:\Users\sanjeev\Desktop\sanju\SEM-VII\Cloud\javacodes>javac H.java

C:\Users\sanjeev\Desktop\sanju\SEM-VII\Cloud\javacodes>java H
Hello to all

C:\Users\sanjeev\Desktop\sanju\SEM-VII\Cloud\javacodes>exit


but i want only "Hello to all" as the output and nothing else so wat shall i do

----------


## RichardG

Hey, I am having the same issue as bvrider1 and Sanjeev467. 

No matter what I do, even when I just download the zip files and run them without changing them at all. I can enter commands into the box and press the button, but nothing happens at all. The text box remains blank.

I have another thread here, where I referenced my issue with slightly more clarity: 
http://www.vbforums.com/showthread.p...79#post4240679


I run VB10 on VS10. All I want to do is gather information from a cmd window without using a text file. But when I try the above approaches, it seems like the readtoend fails or something... My variable remains blank. 

Does anyone have any idea?

----------


## bvrider1

Hello, I got your PM. I hope this code helps.

    Private Sub CMDAutomate()


        Dim myprocess As New Process
        Dim StartInfo As New System.Diagnostics.ProcessStartInfo
        ' Dim mycmd As String = "net use \\172.x.x.x /user:mynetwork\"
        Dim mycmd As String = "net use \\172.x.x.x\IPC$ /user:mynetwork\"
        StartInfo.FileName = "cmd" 'starts cmd window
        StartInfo.RedirectStandardInput = True
        StartInfo.RedirectStandardOutput = True
        StartInfo.UseShellExecute = False 'used for redirect 
        StartInfo.CreateNoWindow = True 'hides cmd window
        myprocess.StartInfo = StartInfo
        myprocess.Start()
        Dim SR As System.IO.StreamReader = myprocess.StandardOutput
        Dim SW As System.IO.StreamWriter = myprocess.StandardInput

        ' SW.WriteLine(txtInputBox.Text + " " + txtPWbox.Text) 'the command you wish to run.....
        SW.WriteLine(mycmd + txtInputBox.Text + " " + txtPWbox.Text)
        SW.WriteLine("Hello - Your drive is now mapped")
        SW.WriteLine(txtPWbox)
        Results = SR.ReadToEnd

        SW.Close()
        SR.Close()

        Invoke(Finished)


    End Sub

----------


## bvrider1

I was using net use to map a drive.  I had the user enter data in textbox1 and textbox2 and using the redirects finished the command line portion of it.

----------


## RichardG

Hey,

I still have the same issues with your code. =(

Basically, the variable is blank no matter what. What does Invoke(Finished) do? That's the only part of your code I haven't used. I just let the sub end at SR.Close()... I wonder if that's the issue... If not, I have no idea what I am doing wrong.

It appears that my variable, after going through any of the above code will be set to blank. I get the feeling that my CMD window is just blank at the start and blank during and after I give it commands. Anyone know why?

----------


## RichardG

> Hey,
> 
> I still have the same issues with your code. =(
> 
> Basically, the variable is blank no matter what. What does Invoke(Finished) do? That's the only part of your code I haven't used. I just let the sub end at SR.Close()... I wonder if that's the issue... If not, I have no idea what I am doing wrong.
> 
> It appears that my variable, after going through any of the above code will be set to blank. I get the feeling that my CMD window is just blank at the start and blank during and after I give it commands. Anyone know why?


It's been a few months now and I have fixed my issue. Basically, I was programming in a weird enterprise environment and I didn't have enough permissions to do what I wanted to. So here's my fix: to get the code to work correctly, first, I build the project. Then, I go to my project's bin/debug folder and copy the .exe of my project. I paste that .exe into my C:\temp folder. THEN from my desktop I right click run as admin a .bat file that I created. This .bat file contains nothing but "start C:\temp\filename.exe"

When I call the program like that, I am able to circumvent the administrative difficulties that I was experiencing. I hope writing this saves some other newbie days of fiddling.

----------


## alpweb

since this is gr8 code and i am using same thread to ask my Question. 

how it can work with pstools commands ?

----------


## ruwan84

could i hide the command line that i insert.. because there is a password in the command line and it should hide.. thanks.!!!

----------


## gabryk

Hi thanks, for this code, is exactly what I was looking for! I know it's been a while since last message, but I need some help here:
my intent is to execute an external script that runs some commands, this code is working fine when it as to invoke the external script and the script do its stuff just fine, only problem is I don't receive the updated output from the cmd. I'd like that the textbox shows each step in wich external script is.
Right now what the external script is doing is showed only at the end of its run, but I need realtime updates. Is this doable?
Thanks a lot, I hope it's clear enough

----------


## kshadow22

This was great, thank you

----------

