DOS comands in VB?

Is there a way of executing DOS comands in vb? Such as copy ect. (copy is just an example). I have used batch file but i find them annoying to a user. Thanks in advance,
David
«1

Comments

  • : Is there a way of executing DOS comands in vb? Such as copy ect. (copy is just an example). I have used batch file but i find them annoying to a user. Thanks in advance,
    : David
    :

    In order for DOS commands or DOS apps to execute, a copy of the command interpreter must be opened. This results in a window showing. I believe you can use the createprocess API and specify that the window not be shown but you're better off using VB's commands for the same operations:

    [code]Del - Kill
    Copy - FileCopy
    Move - Name (if on same drive) or
    FileCopy and Kill (on same drive or not)
    Ren - Name
    rd - RmDir
    md - MkDir
    cd - ChDir (to change folders)
    - CurDir$ (to return current folder)
    [/code]

    Other commands are typically apps that use a combination of the above along with (sometimes recursive) loops to retrieve all the files.

    What commands are you after?
  • : : Is there a way of executing DOS comands in vb? Such as copy ect. (copy is just an example). I have used batch file but i find them annoying to a user. Thanks in advance,
    : : David
    : :
    :
    : In order for DOS commands or DOS apps to execute, a copy of the command interpreter must be opened. This results in a window showing. I believe you can use the createprocess API and specify that the window not be shown but you're better off using VB's commands for the same operations:
    :
    : [code]Del - Kill
    : Copy - FileCopy
    : Move - Name (if on same drive) or
    : FileCopy and Kill (on same drive or not)
    : Ren - Name
    : rd - RmDir
    : md - MkDir
    : cd - ChDir (to change folders)
    : - CurDir$ (to return current folder)
    : [/code]
    :
    : Other commands are typically apps that use a combination of the above along with (sometimes recursive) loops to retrieve all the files.
    :
    : What commands are you after?
    :
    What I should have said is: Is there a way of putting a DOS comand line on a form?
  • [b][red]This message was edited by Cory at 2004-1-6 9:22:24[/red][/b][hr]
    : : : Is there a way of executing DOS comands in vb? Such as copy ect. (copy is just an example). I have used batch file but i find them annoying to a user. Thanks in advance,
    : : : David
    : : :
    : :
    : : In order for DOS commands or DOS apps to execute, a copy of the command interpreter must be opened. This results in a window showing. I believe you can use the createprocess API and specify that the window not be shown but you're better off using VB's commands for the same operations:
    : :
    : : [code]Del - Kill
    : : Copy - FileCopy
    : : Move - Name (if on same drive) or
    : : FileCopy and Kill (on same drive or not)
    : : Ren - Name
    : : rd - RmDir
    : : md - MkDir
    : : cd - ChDir (to change folders)
    : : - CurDir$ (to return current folder)
    : : [/code]
    : :
    : : Other commands are typically apps that use a combination of the above along with (sometimes recursive) loops to retrieve all the files.
    : :
    : : What commands are you after?
    : :
    : What I should have said is: Is there a way of putting a DOS comand line on a form?


    You Could Try This

    Put A Text Box And A Button On Your Form.........
    Then.....In The Onclick Of The Button, Put This


    dim dR as Double

    dr = shell("cmd.exe /c " & Text1.text)


    replace cmd.exe with command.com on Win9x machines.
    replace /c with /k if you want the Dos window left open. )

    I've Tested This And It Works.

    Let Me Know,

    Cory


  • [b][red]This message was edited by rhnet at 2004-1-6 14:40:56[/red][/b][hr]
    : [b][red]This message was edited by Cory at 2004-1-6 9:22:24[/red][/b][hr]
    : : : : Is there a way of executing DOS comands in vb? Such as copy ect. (copy is just an example). I have used batch file but i find them annoying to a user. Thanks in advance,
    : : : : David
    : : : :
    : : :
    : : : In order for DOS commands or DOS apps to execute, a copy of the command interpreter must be opened. This results in a window showing. I believe you can use the createprocess API and specify that the window not be shown but you're better off using VB's commands for the same operations:
    : : :
    : : : [code]Del - Kill
    : : : Copy - FileCopy
    : : : Move - Name (if on same drive) or
    : : : FileCopy and Kill (on same drive or not)
    : : : Ren - Name
    : : : rd - RmDir
    : : : md - MkDir
    : : : cd - ChDir (to change folders)
    : : : - CurDir$ (to return current folder)
    : : : [/code]
    : : :
    : : : Other commands are typically apps that use a combination of the above along with (sometimes recursive) loops to retrieve all the files.
    : : :
    : : : What commands are you after?
    : : :
    : : What I should have said is: Is there a way of putting a DOS comand line on a form?
    :
    :
    : You Could Try This
    :
    : Put A Text Box And A Button On Your Form.........
    : Then.....In The Onclick Of The Button, Put This
    :
    :
    : dim dR as Double
    :
    : dr = shell("cmd.exe /c " & Text1.text)
    :
    :
    : replace cmd.exe with command.com on Win9x machines.
    : replace /c with /k if you want the Dos window left open. )
    :
    : I've Tested This And It Works.
    :
    : Let Me Know,
    :
    : Cory
    :
    :
    :
    It works, but, is there a way getting a result such as if you ping a computer can you get that result on the form? Thanks for your help.
    David


  • : [b][red]This message was edited by rhnet at 2004-1-6 14:40:56[/red][/b][hr]
    : : [b][red]This message was edited by Cory at 2004-1-6 9:22:24[/red][/b][hr]
    : : : : : Is there a way of executing DOS comands in vb? Such as copy ect. (copy is just an example). I have used batch file but i find them annoying to a user. Thanks in advance,
    : : : : : David
    : : : : :
    : : : :
    : : : : In order for DOS commands or DOS apps to execute, a copy of the command interpreter must be opened. This results in a window showing. I believe you can use the createprocess API and specify that the window not be shown but you're better off using VB's commands for the same operations:
    : : : :
    : : : : [code]Del - Kill
    : : : : Copy - FileCopy
    : : : : Move - Name (if on same drive) or
    : : : : FileCopy and Kill (on same drive or not)
    : : : : Ren - Name
    : : : : rd - RmDir
    : : : : md - MkDir
    : : : : cd - ChDir (to change folders)
    : : : : - CurDir$ (to return current folder)
    : : : : [/code]
    : : : :
    : : : : Other commands are typically apps that use a combination of the above along with (sometimes recursive) loops to retrieve all the files.
    : : : :
    : : : : What commands are you after?
    : : : :
    : : : What I should have said is: Is there a way of putting a DOS comand line on a form?
    : :
    : :
    : : You Could Try This
    : :
    : : Put A Text Box And A Button On Your Form.........
    : : Then.....In The Onclick Of The Button, Put This
    : :
    : :
    : : dim dR as Double
    : :
    : : dr = shell("cmd.exe /c " & Text1.text)
    : :
    : :
    : : replace cmd.exe with command.com on Win9x machines.
    : : replace /c with /k if you want the Dos window left open. )
    : :
    : : I've Tested This And It Works.
    : :
    : : Let Me Know,
    : :
    : : Cory
    : :
    : :
    : :
    : It works, but, is there a way getting a result such as if you ping a computer can you get that result on the form? Thanks for your help.
    : David

    My suggestion:-

    Use the CreatePipe API to create two pipes. One for data going from your program to the command line, one for data coming from the command line to your program. This function creates two handles, one for the read end of the pipe and one for the write end.

    Use the CreateProccess API to spawn cmd.exe or whatever command line interpreter you wish to use. You have to fill out a few structures for this. In the StartupInfo structure, you should set hStdOutput and hStdError to the write handle of one pipe. You will read from this pipe to get info from the command line. Set hStdInput to the read end of the other pipe you created. You will write to this end of the pipe to send stuff to the command line.

    After the call to CreateProccess, use CloseHandle and close the handles to the ends of the pipes you gave to the command line program.

    Now you can use the WriteFile API to send data, writing to the write handle that is attached to the stdin of the console app. You can use ReadFile to read data from the read handle of the pipe attached to the console app's stdout and stderr.

    There is another issue. If you want to do things like:-

    cd C:music
    dir
    cd trance

    Then you've got a lot to handle if you spawn a new console session each time. So it's not idea for anything other than individual one-off commands.

    The solution here is to keep the handles. Problem is how do you know if data is there to be read? Your biggest problem you may run into is that ReadPipe will block. You need to use PeekNamedPipe to take a look if there is any data to be read. You can use a timer and do this regularly. It tells you how much data there is available for reading too.

    If I get time (yeah, right) I may have a hack at this myself, just out of curiosity. On the other hand, I have a lot of other things I want to hack at (couple of open source projects, work, college work...) so I may not. :-)

    Somebody may be able to tell you another way to do this by ripping the titlebar, frame etc off a console window and placing it on your form.

    Jonathan

    ###
    for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");

  • : : [b][red]This message was edited by rhnet at 2004-1-6 14:40:56[/red][/b][hr]
    : : : [b][red]This message was edited by Cory at 2004-1-6 9:22:24[/red][/b][hr]
    : : : : : : Is there a way of executing DOS comands in vb? Such as copy ect. (copy is just an example). I have used batch file but i find them annoying to a user. Thanks in advance,
    : : : : : : David
    : : : : : :
    : : : : :
    : : : : : In order for DOS commands or DOS apps to execute, a copy of the command interpreter must be opened. This results in a window showing. I believe you can use the createprocess API and specify that the window not be shown but you're better off using VB's commands for the same operations:
    : : : : :
    : : : : : [code]Del - Kill
    : : : : : Copy - FileCopy
    : : : : : Move - Name (if on same drive) or
    : : : : : FileCopy and Kill (on same drive or not)
    : : : : : Ren - Name
    : : : : : rd - RmDir
    : : : : : md - MkDir
    : : : : : cd - ChDir (to change folders)
    : : : : : - CurDir$ (to return current folder)
    : : : : : [/code]
    : : : : :
    : : : : : Other commands are typically apps that use a combination of the above along with (sometimes recursive) loops to retrieve all the files.
    : : : : :
    : : : : : What commands are you after?
    : : : : :
    : : : : What I should have said is: Is there a way of putting a DOS comand line on a form?
    : : :
    : : :
    : : : You Could Try This
    : : :
    : : : Put A Text Box And A Button On Your Form.........
    : : : Then.....In The Onclick Of The Button, Put This
    : : :
    : : :
    : : : dim dR as Double
    : : :
    : : : dr = shell("cmd.exe /c " & Text1.text)
    : : :
    : : :
    : : : replace cmd.exe with command.com on Win9x machines.
    : : : replace /c with /k if you want the Dos window left open. )
    : : :
    : : : I've Tested This And It Works.
    : : :
    : : : Let Me Know,
    : : :
    : : : Cory
    : : :
    : : :
    : : :
    : : It works, but, is there a way getting a result such as if you ping a computer can you get that result on the form? Thanks for your help.
    : : David
    :
    : My suggestion:-
    :
    : Use the CreatePipe API to create two pipes. One for data going from your program to the command line, one for data coming from the command line to your program. This function creates two handles, one for the read end of the pipe and one for the write end.
    :
    : Use the CreateProccess API to spawn cmd.exe or whatever command line interpreter you wish to use. You have to fill out a few structures for this. In the StartupInfo structure, you should set hStdOutput and hStdError to the write handle of one pipe. You will read from this pipe to get info from the command line. Set hStdInput to the read end of the other pipe you created. You will write to this end of the pipe to send stuff to the command line.
    :
    : After the call to CreateProccess, use CloseHandle and close the handles to the ends of the pipes you gave to the command line program.
    :
    : Now you can use the WriteFile API to send data, writing to the write handle that is attached to the stdin of the console app. You can use ReadFile to read data from the read handle of the pipe attached to the console app's stdout and stderr.
    :
    : There is another issue. If you want to do things like:-
    :
    : cd C:music
    : dir
    : cd trance
    :
    : Then you've got a lot to handle if you spawn a new console session each time. So it's not idea for anything other than individual one-off commands.
    :
    : The solution here is to keep the handles. Problem is how do you know if data is there to be read? Your biggest problem you may run into is that ReadPipe will block. You need to use PeekNamedPipe to take a look if there is any data to be read. You can use a timer and do this regularly. It tells you how much data there is available for reading too.
    :
    : If I get time (yeah, right) I may have a hack at this myself, just out of curiosity. On the other hand, I have a lot of other things I want to hack at (couple of open source projects, work, college work...) so I may not. :-)
    :
    : Somebody may be able to tell you another way to do this by ripping the titlebar, frame etc off a console window and placing it on your form.
    :
    : Jonathan
    :
    : ###
    : for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    : (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    : /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");
    :
    :
    Thnx very much. Although I am not very filmiliar with API's, I am going to reseach them. If any boddy knows some good sites about API's please let me know.
    Thanks again,
    David
  • : Thnx very much. Although I am not very filmiliar with API's, I am
    : going to reseach them.
    MSDN has pretty decent info on them.

    : If any boddy knows some good sites about API's please let me know.
    I do have code for some of this hanging around in a VB .bas module for an open source project I work on. It's tied up in a few other things specific to that project, and not all complete, but you're welcome to it if you want it. Message me with your email address and I'll send it over.

    Jonathan


    ###
    for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");

  • : It works, but, is there a way getting a result such as if you ping a computer can you get that result on the form? Thanks for your help.
    : David


    OK, so is the question really "How can I ping a computer from VB?"

    If so, there're far easier, and more direct, ways of doing this than using DOS windows, piping outputs, etc.

    How about, "What exactly are you trying to do?"

    :)




    [purple]Melissa[/purple]

  • : : It works, but, is there a way getting a result such as if you ping a computer can you get that result on the form? Thanks for your help.
    : : David
    :
    :
    : OK, so is the question really "How can I ping a computer from VB?"
    :
    : If so, there're far easier, and more direct, ways of doing this than using DOS windows, piping outputs, etc.
    :
    : How about, "What exactly are you trying to do?"
    :
    : :)
    :
    :
    :
    :
    : [purple]Melissa[/purple]
    :
    :
    You are right. I should have been more explanitive. My question really is: Is there a way of having the command line in a text box? In a way that the user can type in comands and see them in the text box. Like a MS-DOS command window except on the form.
    Thanks for your help.
    David
  • : You are right. I should have been more explanitive. My question really is: Is there a way of having the command line in a text box? In a way that the user can type in comands and see them in the text box. Like a MS-DOS command window except on the form.
    :

    Yes. No. You can grab the window that the prompt shows up in and place it in your form but that could cause problems with Alt-Tab (two different apps "linked") and Alt-Enter. I don't know how you'd adjust it's look though to make it look more like a textbox. Do you need full DOS? You could try creating your own interpreter if you only need partial DOS.

    Use CreateProcess to spawn a hidden DOS prompt and use the read and write pipe handles to talk to the window and receive it's output. I'd give you some code but I've never gone farther than theory with this.
  • : Yes. No. You can grab the window that the prompt shows up in and place it in your form but that could cause problems with Alt-Tab (two different apps "linked") and Alt-Enter. I don't know how you'd adjust it's look though to make it look more like a textbox. Do you need full DOS? You could try creating your own interpreter if you only need partial DOS.
    :
    Yeah, maybe then it wouldn't suck so hard...

    : Use CreateProcess to spawn a hidden DOS prompt and use the read and write pipe handles to talk to the window and receive it's output. I'd give you some code but I've never gone farther than theory with this.
    :
    KDL, see my post... ;-)

    Jonathan

    ###
    for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");

  • : : You are right. I should have been more explanitive. My question really is: Is there a way of having the command line in a text box? In a way that the user can type in comands and see them in the text box. Like a MS-DOS command window except on the form.
    : :
    :
    : Yes. No. You can grab the window that the prompt shows up in and place it in your form but that could cause problems with Alt-Tab (two different apps "linked") and Alt-Enter. I don't know how you'd adjust it's look though to make it look more like a textbox. Do you need full DOS? You could try creating your own interpreter if you only need partial DOS.
    :
    : Use CreateProcess to spawn a hidden DOS prompt and use the read and write pipe handles to talk to the window and receive it's output. I'd give you some code but I've never gone farther than theory with this.
    :
    I need to be able to run DOS programs on the form. Is that possible?
    (I know I am changing my question alot, sory).
    David

  • : What I should have said is: Is there a way of putting a DOS comand
    : line on a form?
    Curiosity got the better of me. After managing to make VB segfault a few times and scream error messages at me, I finally got it working. To use this code:-

    1) Create a textBox called txtConsole, set it's multiline property to true and give it scrollbars. Get rid of it's initial value.

    2) Create a timer called tmrRead. Give it an interval of 55 and enable it.

    3) Put the following code on your form:-

    [code]Option Explicit

    ' These API declarations are for pipe communication stuff.
    Private Declare Function CreatePipe Lib "kernel32" ( _
    phReadPipe As Long, _
    phWritePipe As Long, _
    lpPipeAttributes As Any, _
    ByVal nSize As Long) As Long
    Private Declare Function ReadFile Lib "kernel32" ( _
    ByVal hFile As Long, _
    ByVal lpBuffer As String, _
    ByVal nNumberOfBytesToRead As Long, _
    lpNumberOfBytesRead As Long, _
    ByVal lpOverlapped As Any) As Long
    Private Declare Function WriteFile Lib "kernel32" ( _
    ByVal hFile As Long, _
    lpBuffer As Any, _
    ByVal nNumberOfBytesToWrite As Long, _
    lpNumberOfBytesWritten As Long, _
    ByVal lpOverlapped As Any) As Long
    Private Declare Function PeekNamedPipe Lib "kernel32" ( _
    ByVal hNamedPipe As Long, lpBuffer As Any, _
    ByVal nBufferSize As Long, lpBytesRead As Long, _
    lpTotalBytesAvail As Long, lpBytesLeftThisMessage As Long) As Long
    Private Declare Function CreateProcessA Lib "kernel32" (ByVal _
    lpApplicationName As Long, ByVal lpCommandLine As String, _
    lpProcessAttributes As Any, lpThreadAttributes As Any, _
    ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
    ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _
    lpStartupInfo As Any, lpProcessInformation As Any) As Long
    Private Declare Function CloseHandle Lib "kernel32" ( _
    ByVal hObject As Long) As Long

    ' Types related to pipe communication.
    Private Type SECURITY_ATTRIBUTES
    nLength As Long
    lpSecurityDescriptor As Long
    bInheritHandle As Long
    End Type
    Private Type STARTUPINFO
    cb As Long
    lpReserved As Long
    lpDesktop As Long
    lpTitle As Long
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCountChars As Long
    dwYCountChars As Long
    dwFillAttribute As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As Long
    hStdInput As Long
    hStdOutput As Long
    hStdError As Long
    End Type
    Private Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessId As Long
    dwThreadID As Long
    End Type

    ' Some constants that we need for the pipe communication.
    Private Const NORMAL_PRIORITY_CLASS = &H20&
    Private Const STARTF_USESTDHANDLES = &H100&
    Private Const STARTF_USESHOWWINDOW = &H1
    Private Const SW_HIDE = 0

    ' Pipe hanldes.
    Dim hWritePipe As Long
    Dim hReadPipe As Long

    ' Flag for helping strip console echo.
    Dim justSent As Boolean

    ' This sub opens the console and gets pipes.
    Sub OpenConsole()
    ' Dimension any variables.
    Dim retVal As Long
    Dim consoleReadPipe As Long
    Dim consoleWritePipe As Long
    Dim sa As SECURITY_ATTRIBUTES
    Dim startInfo As STARTUPINFO
    Dim procInfo As PROCESS_INFORMATION

    ' Create pipes for us to throw data down and get data from.
    sa.bInheritHandle = True
    sa.nLength = Len(sa)
    retVal = CreatePipe(consoleReadPipe, hWritePipe, sa, 1024)
    If retVal = 0 Then Err.Raise 0 ' Add handling
    retVal = CreatePipe(hReadPipe, consoleWritePipe, sa, 1024)
    If retVal = 0 Then Err.Raise 0 ' Add handling

    ' Spawn the app, re-directing stdin and stdout to the console's
    ' ends of the pipes.
    startInfo.cb = Len(startInfo)
    startInfo.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW
    startInfo.hStdOutput = consoleWritePipe
    startInfo.hStdError = consoleWritePipe
    startInfo.hStdInput = consoleReadPipe
    startInfo.wShowWindow = SW_HIDE
    retVal = CreateProcessA(0&, "cmd.exe", _
    sa, sa, True, NORMAL_PRIORITY_CLASS, _
    0&, 0&, startInfo, procInfo)
    If retVal = 0 Then Err.Raise 0 ' Add handling.

    ' Kill off our handles to the console's ends of the pipes.
    CloseHandle consoleWritePipe
    CloseHandle consoleReadPipe
    End Sub


    ' This sub reads stuff from the console.
    Function ReadConsole() As String
    ' We need a few variables.
    Dim test As Byte
    Dim strBuffer As String * 256
    Dim strOut As String
    Dim bytesRead As Long, bytesAvailable As Long, bytesLeft As Long
    Dim retVal As Long

    ' Peek the pipe to see if there's anything there.
    retVal = PeekNamedPipe(hReadPipe, test, 1, bytesRead, bytesAvailable, bytesLeft)

    ' If the pipe is broken, raise an error.
    If retVal = 0 Then Err.Raise 0 ' Add handling.

    ' If there is nothing to read, give an empty string.
    If bytesAvailable = 0 Then
    ReadConsole = ""
    Exit Function
    End If

    ' As we know there's something there, read it all in and return it.
    Do
    retVal = ReadFile(hReadPipe, strBuffer, 256, bytesRead, 0&)
    strOut = strOut & Left(strBuffer, bytesRead)
    bytesAvailable = bytesAvailable - 256
    Loop While bytesAvailable > 0
    ReadConsole = strOut
    End Function


    ' This sub writes a message to the console.
    Private Sub WriteConsole(Message As String)
    ' Put message in a byte array and send it.
    Dim ba() As Byte, i As Long, retVal As Long
    ba = StrConv(Message, vbFromUnicode)
    retVal = WriteFile(hWritePipe, ba(0), Len(Message), i, CLng(0))
    If retVal = 0 Then Err.Raise 0 ' Add handling.
    End Sub


    ' This sub closes the console session.
    Private Sub CloseConsole()
    ' Just close handles.
    CloseHandle hWritePipe
    CloseHandle hReadPipe
    End Sub

    Private Sub Form_Load()
    OpenConsole
    End Sub

    Private Sub Form_Unload(Cancel As Integer)
    CloseConsole
    End Sub

    ' This is a timer that gets any new data.
    Private Sub tmrRead_Timer()
    Dim Message As String
    tmrRead.Enabled = False
    Message = ReadConsole
    If Message <> "" Then
    ' If something has just been sent, strip off first line.
    ' This is to prevent console echo re-appearing.
    If justSent = True Then
    Message = Right(Message, Len(Message) - InStr(1, Message, vbCrLf))
    justSent = False
    End If

    ' Put message in text box.
    With txtConsole
    .Text = txtConsole.Text & Message
    .SelStart = Len(txtConsole.Text)
    .SelLength = 0
    End With
    End If
    tmrRead.Enabled = True
    End Sub

    Private Sub txtConsole_KeyUp(KeyCode As Integer, Shift As Integer)
    'If enter was pressed, send the last line typed.
    If KeyCode = 13 Then
    Dim Lines() As String
    Dim Parts() As String
    Lines = Split(txtConsole.Text, vbCrLf)
    Parts = Split((Lines(UBound(Lines) - 1)), ">")
    WriteConsole Parts(1) & vbCrLf
    justSent = True
    End If
    End Sub
    [/code]

    Have fun,

    Jonathan

    ###
    for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");

  • [b][red]This message was edited by Jonathan at 2004-1-7 14:22:16[/red][/b][hr]
    : I need to be able to run DOS programs on the form. Is that possible?
    Depends which programs. Some I tried:-

    ping - yes
    tracert - yes
    format - yes
    debug - yes
    edit - no

    (Edit: These are with respect to the solution I posted)

    : (I know I am changing my question alot, sory).
    Yeah, it's a PITA for us guys trying to give you a solution...

    Jonathan

    ###
    for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");



  • [b][red]This message was edited by rhnet at 2004-1-7 16:33:31[/red][/b][hr]
    : : What I should have said is: Is there a way of putting a DOS comand
    : : line on a form?
    : Curiosity got the better of me. After managing to make VB segfault a few times and scream error messages at me, I finally got it working. To use this code:-
    :
    : 1) Create a textBox called txtConsole, set it's multiline property to true and give it scrollbars. Get rid of it's initial value.
    :
    : 2) Create a timer called tmrRead. Give it an interval of 55 and enable it.
    :
    : 3) Put the following code on your form:-
    :
    : [code]Option Explicit
    :
    : ' These API declarations are for pipe communication stuff.
    : Private Declare Function CreatePipe Lib "kernel32" ( _
    : phReadPipe As Long, _
    : phWritePipe As Long, _
    : lpPipeAttributes As Any, _
    : ByVal nSize As Long) As Long
    : Private Declare Function ReadFile Lib "kernel32" ( _
    : ByVal hFile As Long, _
    : ByVal lpBuffer As String, _
    : ByVal nNumberOfBytesToRead As Long, _
    : lpNumberOfBytesRead As Long, _
    : ByVal lpOverlapped As Any) As Long
    : Private Declare Function WriteFile Lib "kernel32" ( _
    : ByVal hFile As Long, _
    : lpBuffer As Any, _
    : ByVal nNumberOfBytesToWrite As Long, _
    : lpNumberOfBytesWritten As Long, _
    : ByVal lpOverlapped As Any) As Long
    : Private Declare Function PeekNamedPipe Lib "kernel32" ( _
    : ByVal hNamedPipe As Long, lpBuffer As Any, _
    : ByVal nBufferSize As Long, lpBytesRead As Long, _
    : lpTotalBytesAvail As Long, lpBytesLeftThisMessage As Long) As Long
    : Private Declare Function CreateProcessA Lib "kernel32" (ByVal _
    : lpApplicationName As Long, ByVal lpCommandLine As String, _
    : lpProcessAttributes As Any, lpThreadAttributes As Any, _
    : ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
    : ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _
    : lpStartupInfo As Any, lpProcessInformation As Any) As Long
    : Private Declare Function CloseHandle Lib "kernel32" ( _
    : ByVal hObject As Long) As Long
    :
    : ' Types related to pipe communication.
    : Private Type SECURITY_ATTRIBUTES
    : nLength As Long
    : lpSecurityDescriptor As Long
    : bInheritHandle As Long
    : End Type
    : Private Type STARTUPINFO
    : cb As Long
    : lpReserved As Long
    : lpDesktop As Long
    : lpTitle As Long
    : dwX As Long
    : dwY As Long
    : dwXSize As Long
    : dwYSize As Long
    : dwXCountChars As Long
    : dwYCountChars As Long
    : dwFillAttribute As Long
    : dwFlags As Long
    : wShowWindow As Integer
    : cbReserved2 As Integer
    : lpReserved2 As Long
    : hStdInput As Long
    : hStdOutput As Long
    : hStdError As Long
    : End Type
    : Private Type PROCESS_INFORMATION
    : hProcess As Long
    : hThread As Long
    : dwProcessId As Long
    : dwThreadID As Long
    : End Type
    :
    : ' Some constants that we need for the pipe communication.
    : Private Const NORMAL_PRIORITY_CLASS = &H20&
    : Private Const STARTF_USESTDHANDLES = &H100&
    : Private Const STARTF_USESHOWWINDOW = &H1
    : Private Const SW_HIDE = 0
    :
    : ' Pipe hanldes.
    : Dim hWritePipe As Long
    : Dim hReadPipe As Long
    :
    : ' Flag for helping strip console echo.
    : Dim justSent As Boolean
    :
    : ' This sub opens the console and gets pipes.
    : Sub OpenConsole()
    : ' Dimension any variables.
    : Dim retVal As Long
    : Dim consoleReadPipe As Long
    : Dim consoleWritePipe As Long
    : Dim sa As SECURITY_ATTRIBUTES
    : Dim startInfo As STARTUPINFO
    : Dim procInfo As PROCESS_INFORMATION
    :
    : ' Create pipes for us to throw data down and get data from.
    : sa.bInheritHandle = True
    : sa.nLength = Len(sa)
    : retVal = CreatePipe(consoleReadPipe, hWritePipe, sa, 1024)
    : If retVal = 0 Then Err.Raise 0 ' Add handling
    : retVal = CreatePipe(hReadPipe, consoleWritePipe, sa, 1024)
    : If retVal = 0 Then Err.Raise 0 ' Add handling
    :
    : ' Spawn the app, re-directing stdin and stdout to the console's
    : ' ends of the pipes.
    : startInfo.cb = Len(startInfo)
    : startInfo.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW
    : startInfo.hStdOutput = consoleWritePipe
    : startInfo.hStdError = consoleWritePipe
    : startInfo.hStdInput = consoleReadPipe
    : startInfo.wShowWindow = SW_HIDE
    : retVal = CreateProcessA(0&, "cmd.exe", _
    : sa, sa, True, NORMAL_PRIORITY_CLASS, _
    : 0&, 0&, startInfo, procInfo)
    : If retVal = 0 Then Err.Raise 0 ' Add handling.
    :
    : ' Kill off our handles to the console's ends of the pipes.
    : CloseHandle consoleWritePipe
    : CloseHandle consoleReadPipe
    : End Sub
    :
    :
    : ' This sub reads stuff from the console.
    : Function ReadConsole() As String
    : ' We need a few variables.
    : Dim test As Byte
    : Dim strBuffer As String * 256
    : Dim strOut As String
    : Dim bytesRead As Long, bytesAvailable As Long, bytesLeft As Long
    : Dim retVal As Long
    :
    : ' Peek the pipe to see if there's anything there.
    : retVal = PeekNamedPipe(hReadPipe, test, 1, bytesRead, bytesAvailable, bytesLeft)
    :
    : ' If the pipe is broken, raise an error.
    : If retVal = 0 Then Err.Raise 0 ' Add handling.
    :
    : ' If there is nothing to read, give an empty string.
    : If bytesAvailable = 0 Then
    : ReadConsole = ""
    : Exit Function
    : End If
    :
    : ' As we know there's something there, read it all in and return it.
    : Do
    : retVal = ReadFile(hReadPipe, strBuffer, 256, bytesRead, 0&)
    : strOut = strOut & Left(strBuffer, bytesRead)
    : bytesAvailable = bytesAvailable - 256
    : Loop While bytesAvailable > 0
    : ReadConsole = strOut
    : End Function
    :
    :
    : ' This sub writes a message to the console.
    : Private Sub WriteConsole(Message As String)
    : ' Put message in a byte array and send it.
    : Dim ba() As Byte, i As Long, retVal As Long
    : ba = StrConv(Message, vbFromUnicode)
    : retVal = WriteFile(hWritePipe, ba(0), Len(Message), i, CLng(0))
    : If retVal = 0 Then Err.Raise 0 ' Add handling.
    : End Sub
    :
    :
    : ' This sub closes the console session.
    : Private Sub CloseConsole()
    : ' Just close handles.
    : CloseHandle hWritePipe
    : CloseHandle hReadPipe
    : End Sub
    :
    : Private Sub Form_Load()
    : OpenConsole
    : End Sub
    :
    : Private Sub Form_Unload(Cancel As Integer)
    : CloseConsole
    : End Sub
    :
    : ' This is a timer that gets any new data.
    : Private Sub tmrRead_Timer()
    : Dim Message As String
    : tmrRead.Enabled = False
    : Message = ReadConsole
    : If Message <> "" Then
    : ' If something has just been sent, strip off first line.
    : ' This is to prevent console echo re-appearing.
    : If justSent = True Then
    : Message = Right(Message, Len(Message) - InStr(1, Message, vbCrLf))
    : justSent = False
    : End If
    :
    : ' Put message in text box.
    : With txtConsole
    : .Text = txtConsole.Text & Message
    : .SelStart = Len(txtConsole.Text)
    : .SelLength = 0
    : End With
    : End If
    : tmrRead.Enabled = True
    : End Sub
    :
    : Private Sub txtConsole_KeyUp(KeyCode As Integer, Shift As Integer)
    : 'If enter was pressed, send the last line typed.
    : If KeyCode = 13 Then
    : Dim Lines() As String
    : Dim Parts() As String
    : Lines = Split(txtConsole.Text, vbCrLf)
    : Parts = Split((Lines(UBound(Lines) - 1)), ">")
    : WriteConsole Parts(1) & vbCrLf
    : justSent = True
    : End If
    : End Sub
    : [/code]
    :
    : Have fun,
    :
    : Jonathan
    :
    : ###
    : for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
    : (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
    : /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");
    :
    :
    Thats exactly what I need. But vb is yelling because of "runtime error 9, subscript out of range" (that happens under the txtConsole_keyup event with [code]writeConsole Parts(1) & vbCrlf[/code] also it yelled at me for "invalid procedure call or argument" (under "sub openconsole" with "if retVal= 0 then" this is the error code : "err.raise 0".

    Thanks for your help.
    David


Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories