# DOS Commands In Visual Basic



## PVTCaboose1337 (Jan 21, 2010)

How would I go about executing DOS commands in Visual Basic?  My plan is to have an input field in VB, and then when the user pushes a button it will input this input into the DOS command and execute it.


----------



## PVTCaboose1337 (Jan 21, 2010)

Ok, update:  

I have found that


```
Dim sCommand As String
        sCommand = "DOSCOMMAND HERE"
        Shell("cmd.exe /c" & sCommand)
```

will execute a dos command, but lets say I want to echo from a text box inside VB?  How would I go about that?  


```
Dim sCommand As String
        sCommand = "echo SOMETHINGFROMVB"
        Shell("cmd.exe /c" & sCommand)
```


----------



## Kreij (Jan 21, 2010)

I think that sCommand could be a filename with all the commands you want to execute in it.
Our do you want to be able to talk to the cmd process from individual lines of VB code?


----------



## PVTCaboose1337 (Jan 21, 2010)

I figured it out just now.  Was very simple.  Stuff box is a textbox btw.  


```
Dim stuff As String

        stuff = stuffbox.Text

        Dim sCommand As String
        sCommand = "echo" & " " & stuff
        Shell("cmd.exe /c" & sCommand)
```


----------



## Kreij (Jan 22, 2010)

Thanks for letting us know how you got it working ! 
I use this section as a programming reference quite often.


----------



## FordGT90Concept (Jan 22, 2010)

You should get in the habit of using System.Diagnostics.Process.Start() rather than Shell.  Using that method, you can redirect StandardOutput, and StandardError.  In your app, create a while loop to write the contents of each of those streams to a window in the application:


```
While p.StandardOutput.Peek() <> -1
  txt.Text +=p.StandardOutput.ReadLine()
End While
```
Repeat for StandardError.


----------



## PVTCaboose1337 (Jan 22, 2010)

Ok guys, here is where the work went to.  A fun program to screw around with on the school network.  Nobody knew what I meant when I said "use the command prompt to send messages," so I made my own program so people can talk over the network.  Will improve later, want to add some more options, but for a quick time, this is good enough!

I took advantage of this original batch file written in about 30 seconds:


```
@echo off
color 1f
:begin
cls
set /p n=User: 
set /p m=Message: 
msg %n% %m%
pause
Goto begin
```

It only worked with Windows 7 / Vista, so in the VB code I added a condition to change between different versions of Windows.  Anyway...  

Enjoy!

Edit:  For all those against opening strange .exe files they find on tech forums, this is for you:







http://www.virustotal.com/analisis/...ace159ac1db582d43e66605655427286e1-1264127325


----------



## A Cheese Danish (Jan 22, 2010)

That's a fun little program you got there.
This reminds me, I need to keep teaching myself how to code more in depth with VB.


----------



## PVTCaboose1337 (Jan 22, 2010)

It has been about 4 year since I touched VB!  I forgot how much fun it was to write little programs like that!

ALSO:  For those who care, the full code:


```
Public Class Form1

    Private Sub send_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles send.Click
        'Define and store user and message into strings
        Dim user As String
        Dim msg As String

        user = userbox.Text
        msg = msgbox.Text

        'Send all suicide mode!
        If checkall.Checked Then
            user = "*"
            userbox.ReadOnly = True

        End If

        'Main Code

        If radionew.Checked Then

            'Windows Vista / 7 Code
            'Calls the user and msg strings and inputs them into the DOS code to execute

            Dim sCommand As String
            sCommand = "msg" & " " & user & " " & msg
            Shell("cmd.exe /c" & sCommand)


        ElseIf radioold.Checked Then

            'Windows 2000 / XP Code
            'Calls the user and msg strings and inputs them into the DOS code to execute

            Dim sCommand As String
            sCommand = "net send" & " " & user & " " & msg
            Shell("cmd.exe /c" & sCommand)

        End If

    End Sub

    Private Sub clear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles clear.Click
        'Clears the message box
        msgbox.Text = ""
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    End Sub
End Class
```

Simple no?

If anyone is using Windows XP or 2000, please test the code for me!  I have only 7 and Vista!  Just make sure to check the correct box!

Download is here:  http://forums.techpowerup.com/attachment.php?attachmentid=32339&d=1264124659


----------



## FordGT90Concept (Jan 22, 2010)

You can use Environment.OSVersion to figure out what version of Windows the application is being run on is.


```
If Environment.OSVersion.MajorVersion >= 6
 ' Vista/7/Server 2008
Else
 ' XP/Server 2003/2000/NT
```


It does not work on Server 2003 most likely because "net send" is a Windows 2000 and older command.  "msg" works fine:


```
msg Administrator test
```

I'll check XP but I'm pretty sure it will be the same result.


Edit: XP is the same as Server 2003 (use "msg").


If you change it over to use Process.Start, the command window, and most likely response, will appear in your application (or not at all) rather than separate windows.


----------



## PVTCaboose1337 (Jan 22, 2010)

FordGT90Concept said:


> You can use Environment.OSVersion to figure out what version of Windows the application is being run on is.
> 
> 
> ```
> ...



So I need to change it so XP uses the msg command as well?  Last time I checked, the net send command also worked on XP.  

Also, the auto environment detector, GENIUS!  I will use that!

EDIT:  Hmm...  trying to figure out how to "capture" the return text, is it possible to grab it and have that other window never open?


----------



## FordGT90Concept (Jan 22, 2010)

"net send Administrator test" does not work on Server 2003.  It says "the message alias could not be found on the network."


Come to think of it, the response Window will pop up even if you redirect output because the application recieveing the message most likely isn't the computer running the app.  You can get rid of console windows though:


```
Imports System.Diagnostics

...

Dim psi As New ProcessStartInfo()
With psi
  .Arguments = user & " " & msg
  .CreateNoWindow = True
  .FileName = Environment.GetEnvironmentVariable("SYSTEMROOT") & "\system32\msg.exe"
  .UseShellExecute = False
  .ErrorDialog = False
  .RedirectStandardOutput = True
  .RedirectStandardError = True
  .WorkingDirectory = Environment.GetEnvironmentVariable("SYSTEMROOT") & "\system32"
End With

Dim p As New Process()
With p
  .StartInfo = psi;
  .Start();
  .WaitForExit();
End With
```

After that last End With is where you would put the While loop to handle the streams.  I really see no need to in this case, however.


I don't have Visual Studio installed at this time so the code above is untested (converted to VB from C#).


----------



## PVTCaboose1337 (Jan 22, 2010)

New version...  Really minor changes, removed an unneeded line of code, updated the icon, picture, etc.  Added 90% transparency, and most of all, fixed the XP error.  Next up is to make a "test" button that sends the local user a test message to make sure everything is correctly configured.

Edit:  Please give suggestions for features if you think this small app needs improvement.


----------



## FordGT90Concept (Jan 22, 2010)

By the way, all the version numbers are on here:
http://en.wikipedia.org/wiki/History_of_Microsoft_Windows#Product_progression

I don't know if Windows 2000 has msg.exe or not.  Doing some Googling, it appears that Windows 2000 has msg.exe but some distros of Windows Vista does not (Home Basic and Home Premium).

In any case, you should add a check for the file before attempting to execute it:

```
If System.IO.File.Exists(Environment.GetEnvironmenVariable("SYSTEMROOT") & "\system32\msg.exe")) Then
  ' run it
Else
  MessageBox.Show("msg.exe" could not be found") ' or attempt net send but I still don't see how to run it
End If
```


Edit:
Another suggestion is to catch the KeyPress event for Message and invoke the Send button.  Something like:

```
Private Sub txtMessage_KeyPress(sender As Object, e As KeyPressEventArgs)
  If e.KeyChar = Convert.ToChar(13) Then
    send_Click(Me, New EventArgs())
    e.Handled = True
  End If
End Sub
```


----------



## PVTCaboose1337 (Jan 22, 2010)

FordGT90Concept said:


> By the way, all the version numbers are on here:
> http://en.wikipedia.org/wiki/History_of_Microsoft_Windows#Product_progression
> 
> I don't know if Windows 2000 has msg.exe or not.  Doing some Googling, it appears that Windows 2000 has msg.exe but some distros of Windows Vista does not (Home Basic and Home Premium).
> ...



I am having issues with 


```
Environment.GetEnvironmentalVariable
```
  Seems not to work...


----------



## FordGT90Concept (Jan 22, 2010)

Environment.GetEnvironmentVariable()


It works on Server 2003 but I had Windows 7/Vista checked.


----------



## PVTCaboose1337 (Jan 22, 2010)




----------



## FordGT90Concept (Jan 22, 2010)

It is Environment, not Environmental (my brain fart, I got right a post or two before that ).  I fixed the code you quoted of mine.


----------



## PVTCaboose1337 (Jan 22, 2010)

Great!  You forgot the "then" as well...  Works now, also, I need someone to test it with the new code in it who DOES NOT HAVE MSG.exe!!!  Also, for the test button...  I was planning on having it send a message back to the user...  I tried saying the user was "127.0.0.1" but no luck!  Any ideas?

Edit:  Ok we kinda are dumb ...  what happens if the user is using Windows 2000 which does not have MSG.exe, but still uses the net send command?  I will fix...   those radio buttons are lifesavers!

Edit2:  Problem solved:


----------



## FordGT90Concept (Jan 22, 2010)

You shouldn't need the radio buttons...

```
If Environment.OSVersion.Platform <> PlatformID.Win32NT Then
  ' Windows 9x or other, not suported
Else
  If System.IO.File.Exists(Environment.GetEnvironmentalVariable("SYSTEMROOT") & "\system32\msg.exe") Then
    ' Use msg
  Else
    If System.IO.File.Exists(Environment.GetEnvironmentalVariable("SYSTEMROOT") & "\system32\net.exe") And Environment.OSVersion.MajorVersion < 6 Then
      ' Use net send
    Else
      ' Not supported
    End If
  End If
End If
```

You should really make the path to msg and the path to net readonly variables:

```
Private ReadOnly PATH_MSG As String = Environment.GetEnvironmentalVariable("SYSTEMROOT") & "\system32\msg.exe") 
Private ReadOnly PATH_NET As String = Environment.GetEnvironmentalVariable("SYSTEMROOT") & "\system32\net.exe")
```
Instead of typing that whole lot, you'd only have to type PATH_MSG or PATH_NET.


Edit: I updated both code areas in this post...


----------



## PVTCaboose1337 (Jan 25, 2010)

FordGT90Concept said:


> You shouldn't need the radio buttons...
> 
> ```
> If Environment.OSVersion.Platform <> PlatformID.Win32NT Then
> ...



Ok great!  I fixed most of the code to automate choosing the Windows version.


----------



## PVTCaboose1337 (Jan 25, 2010)

Having trouble calling a media file from resources.  How would I accomplish this?


```
AxWindowsMediaPlayer1.URL = "My.Resources.music.mid"
```

The above code does not work.


----------



## FordGT90Concept (Jan 25, 2010)

MIDI is going to be trouble.  Can you convert it to a .wav?  In wave format, you can use System.Media.SoundPlayer.


----------



## PVTCaboose1337 (Jan 25, 2010)

FordGT90Concept said:


> MIDI is going to be trouble.  Can you convert it to a .wav?  In wave format, you can use System.Media.SoundPlayer.



I actually got it to play, but the music / midi file has to be in the same folder.  Simply need to know how to call from resources.  


```
AxWindowsMediaPlayer1.URL = "music.mid"
```


----------



## FordGT90Concept (Jan 25, 2010)

Oh, embeded in your executable?  Usually it is:

AssemblyName.Properties.Reserouces.name_of_resource


----------



## PVTCaboose1337 (Jan 25, 2010)

Here is what I get:


----------



## FordGT90Concept (Jan 25, 2010)

You might be able to just do:
Properties.Resources.name_of_resource


----------



## PVTCaboose1337 (Jan 25, 2010)

hmm...


----------



## FordGT90Concept (Jan 25, 2010)

Doh, looked at C# when I thought I was looking at VB.  This should work (finally):
My.Resources.resource_name


----------



## PVTCaboose1337 (Jan 25, 2010)

Hmm...






But the file is clearly a member of resources...  very strange.


----------



## FordGT90Concept (Jan 26, 2010)

Go into Project Properties, Resources, and click on the resource.  Make sure the name is correct there and also Persistence should be "Embedded in .resx"


----------



## PVTCaboose1337 (Jan 27, 2010)

FordGT90Concept said:


> Go into Project Properties, Resources, and click on the resource.  Make sure the name is correct there and also Persistence should be "Embedded in .resx"



That helped, the resource says it was added, but it was not.  Glad that is sorted out now...  Now another issue in the same area...


----------



## FordGT90Concept (Jan 27, 2010)

Your mediaplayer needs be given a byte array instead of an URL to the file.  I don't know what mediaplayer is declared as so I can't be of much assistance there.


----------



## PVTCaboose1337 (Jan 28, 2010)

FordGT90Concept said:


> Your mediaplayer needs be given a byte array instead of an URL to the file.  I don't know what mediaplayer is declared as so I can't be of much assistance there.



Fair enough!  Thanks for your help!  I will figure out another time how to play embedded midi files...  Final Version is attached!

In other news, started a new program, and it is done, but a small issue has been encountered.  


```
Public Class rarfinder

    Dim fdlg1 As OpenFileDialog = New OpenFileDialog()

    Private Sub btnchoose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnchoose.Click
        'File browser
        Dim fdlg1 As OpenFileDialog = New OpenFileDialog()
        fdlg1.Title = "Choose a File"
        fdlg1.InitialDirectory = "c:\"
        fdlg1.Filter = "All files (*.*)|*.*|All files (*.*)|*.*"
        fdlg1.FilterIndex = 2
        fdlg1.RestoreDirectory = True
        If fdlg1.ShowDialog() = DialogResult.OK Then
            txtfile.Text = fdlg1.FileName
            safetxtfile.Text = fdlg1.SafeFileName
        End If
        My.Computer.FileSystem.CopyFile(txtfile.Text, txtfile.Text & "_cpt")
        My.Computer.FileSystem.RenameFile(txtfile.Text & "_cpt", safetxtfile.Text & ".txt")
        btnscan.Enabled = 1
        btnchoose.Enabled = 0
    End Sub

    Private Sub btnscan_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnscan.Click

        Me.txtdump.Multiline = True
        txtdump.Text = My.Computer.FileSystem.ReadAllText(txtfile.Text & ".txt")
        My.Computer.FileSystem.DeleteFile(txtfile.Text & ".txt")


        If txtdump.Text.Contains("rar") Then

            MsgBox("Rar Detected!")

        Else

            MsgBox("No Rar Found!")

        End If
        'Me.txtdump.Clear()
        btnchoose.Enabled = 1
        btnscan.Enabled = 0
    End Sub

    Private Sub cpfinder_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        btnscan.Enabled = 0
    End Sub
End Class
```

Long story short, the code works.  Till it gets to the part where it looks in the text file.  So the message box apparently does not store weird characters:  






As you can see, the textbox is incorrectly copying the data from the text file.  Any ways to solve this so the data stays in a "raw" form?


----------



## PVTCaboose1337 (Jan 28, 2010)

Here is the proof my program works, and that I need to figure out a way to get the raw data read.


----------



## PVTCaboose1337 (Jan 28, 2010)

And getting closer...  The first 4 characters are the same as in the text file, but the whole file did not show up...  hmm...


----------



## FordGT90Concept (Jan 28, 2010)

You need to use a BinaryReader/BinaryWriter, not a TextReader/TextWriter.  Text is meant for for ASCII.  ReadAll... is meant for small files.  Binary is meant for binary files (RAR and JPG formats are binary).


What are you trying to achieve with this app?  Detect RAR? lowercase or uppercase?


----------



## PVTCaboose1337 (Jan 28, 2010)

FordGT90Concept said:


> You need to use a BinaryReader/BinaryWriter, not a TextReader/TextWriter.  Text is meant for for ASCII.  ReadAll... is meant for small files.  Binary is meant for binary files (RAR and JPG formats are binary).
> 
> 
> What are you trying to achieve with this app?  Detect RAR? lowercase or uppercase?



The app pretty much finds hidden RAR files.  You know how you can combine a JPG and a RAR and it looks like an image still?  Yeah well this will be able to tell you when a file is actually a hidden rar.


----------



## FordGT90Concept (Jan 28, 2010)

In that case, the attached file will help greatly.  Add it to the project then do:


```
Dim results() As Integer = Search.Find("Rar", pathtofile, 4096, 1)
If results.Length > 0 Then
  // RAR found
Else
  // RAR not found
End If
```

It should be much faster than the way you are doing it now.


If it is a RAR file, "Rar" should be the first three bytes or 82, 92, 114.


----------



## PVTCaboose1337 (Jan 28, 2010)

Hmm...  I might try that later, but here is what I want to know now...  If I can convert the text file I made to say, UTF-8 encoding, then I can read it in the text box.  Is there any way I can do that with VB?


----------



## FordGT90Concept (Jan 28, 2010)

There's no point.  JPG and RAR files offer very little legible text.  They are binaries meant to be processed by machines, not man. XD


This would display it all (sort of) but I still wouldn't recommend it:

```
txtdump.Text = My.Computer.FileSystem.ReadAllText(txtfile.Text & ".txt", Encoding.UTF8)
```

Textboxes are not designed for more than 32 KiB of text.


----------



## PVTCaboose1337 (Jan 29, 2010)

FordGT90Concept said:


> There's no point.  JPG and RAR files offer very little legible text.  They are binaries meant to be processed by machines, not man. XD
> 
> 
> This would display it all (sort of) but I still wouldn't recommend it:
> ...



In rars, the phrase "rar" always appears, and that is my way of detecting them.  So I have tried it your way above, no dice.  But can I re-encode a .txt file in VB?


----------



## FordGT90Concept (Jan 29, 2010)

PVTCaboose1337 said:


> In rars, the phrase "rar" always appears, and that is my way of detecting them.  So I have tried it your way above, no dice.  But can I re-encode a .txt file in VB?


Remember, my code is case sensitive.  If "rar" appears, it must be "rar," not "Rar." XD

The easiest way to handle text is via a StreamReader or StreamWriter.

Text files (*.txt) are ASCII.  If you want to encode it, you'll need a heavier file format like RTF, DOC, or something else.


----------



## PVTCaboose1337 (Jan 31, 2010)

Regarding the "rar" vs "RAR" issue, well I have coded for that...  or functions!  

I am really trying to figure out how to re-encode a file in UTF-8 from Visual Basic.  Is there any easy way to do that?  I know they are ASCII, but VB seems not to like those...  probably because I am using non-ASCII characters in the file.


----------



## FordGT90Concept (Feb 1, 2010)

Dim sr As New StreamReader("path to file", System.Text.Encoding.UTF-8)


Again, RAR files are binaries, not text.  Less than 1% of the file is text and it is completely out of context when not processing all the encompassing binary data.


----------

