Jamsie
asked on
Command Console (NT Workstation) Dos Box
Hi,
I wish to run a process from the command line and return to the same command console some output. E.g.
C:\> myprocess.exe /?
myprocess Help
-a command line argument
etc.
I'm not new to VB but this one gets me every time.
Can anyone help????
Thanks
Jamsie
I wish to run a process from the command line and return to the same command console some output. E.g.
C:\> myprocess.exe /?
myprocess Help
-a command line argument
etc.
I'm not new to VB but this one gets me every time.
Can anyone help????
Thanks
Jamsie
PS - if you are happy with a console that is created in a new process, check out this example
With thanks to ameba!
>1) is it possible to make console programs with VB6
Yes. See http://www.saurik.com/ Goto Samples, smpConsole
With thanks to ameba!
>1) is it possible to make console programs with VB6
Yes. See http://www.saurik.com/ Goto Samples, smpConsole
Would you be willing to start the console from within VB, then use a batch file to execute the program in the console Window? You can do that.
If you have to use the original consil you can use AppActivate to set focus to it and use sendkeys to control it. <smile>
With thanks to someone (mcrider I think) the following code in a module, compiled will take any VB app and convert it into a dos executable. This will run in the console window in which it is started, you can then use the writeconsole/writefile api calls as the smpConsole example shows to return text to the window.
' -------------------------- ---------- ---------- --------
' MakeConsole.BAS -- Copyright (c) Slightly Tilted Software
' By: L.J. Johnson Date: 11-30-1997
' Comments: Contains MAIN(), plus the function
' which take a standard VB 5.0 EXE ( or VB 6.0 ! )
' and change it to a 32-bit console app
' -------------------------- ---------- ---------- --------
Option Explicit
Option Base 1
DefLng A-Z
Private Const GENERIC_READ As Long = &H80000000
Private Const OPEN_EXISTING As Long = 3&
Private Const FILE_ATTRIBUTE_NORMAL As Long = &H80&
Private Const SCS_32BIT_BINARY = 0&
Private Const SCS_DOS_BINARY = 1&
Private Const SCS_WOW_BINARY = 2&
Private Const SCS_PIF_BINARY = 3&
Private Const SCS_POSIX_BINARY = 4&
Private Const SCS_OS216_BINARY = 5&
Private Const constMsgTitle = "Make Console App"
' -------------------------- ---------- ---------
' Windows API calls
' -------------------------- ---------- ---------
Public Declare Sub CopyMem _
Lib "kernel32" Alias "RtlMoveMemory" _
(dst As Any, src As Any, ByVal Size As Long)
Private Declare Function CloseHandle _
Lib "kernel32" _
(ByVal hObject As Long) As Long
Private Declare Function CreateFile _
Lib "kernel32" Alias "CreateFileA" _
(ByVal lpFileName As String, _
ByVal dwDesiredAccess As Long, _
ByVal dwShareMode As Long, _
ByVal lpSecurityAttributes As Long, _
ByVal dwCreationDisposition As Long, _
ByVal dwFlagsAndAttributes As Long, _
ByVal hTemplateFile As Long) As Long
Public Sub Main()
Dim strCmd As String
Dim strMsg As String
Dim strRtn As String
strCmd = Command$
If Trim$(strCmd) = "" Then
strMsg = "You must enter the name of a VB 5.0 standard executable file."
MsgBox strMsg, vbExclamation, constMsgTitle
Else
If InStr(1, strCmd, ".", vbTextCompare) = 0 Then
strCmd = strCmd & ".EXE"
End If
If Exists(strCmd) = True Then
strRtn = SetConsoleApp(strCmd)
MsgBox strRtn, vbInformation, constMsgTitle
Else
strMsg = "The file, " & Trim$(strCmd) & ", does not exist."
MsgBox strMsg, vbCritical, constMsgTitle
End If
End If
End Sub
Private Function SetConsoleApp(xstrFileName As String) As String
Dim lngFileNum As Long
Dim ststrMZ_Header As String * 512
Dim strMagic As String * 2
Dim strMagicPE As String * 2
Dim lngNewPE_Offset As Long
Dim lngData As Long
Dim strTmp As String
Const PE_FLAG_OFFSET As Long = 93&
Const DOS_FILE_OFFSET As Long = 25&
' -------------------------- ---------- ---------
' See if file actually exists
' -------------------------- ---------- ---------
strTmp = Trim$(Dir$(xstrFileName))
If Len(strTmp) = 0 Then
SetConsoleApp = "Failed -- The file, " & xstrFileName & ", does not exist!"
GoTo ExitCheck
End If
' -------------------------- ---------- ---------
' Get a free file handle
' -------------------------- ---------- ---------
On Error Resume Next
lngFileNum = FreeFile
Open xstrFileName For Binary Access Read Write Shared As lngFileNum
' -------------------------- ---------- ---------
' Get the first 512 characters from from file
' -------------------------- ---------- ---------
Seek #lngFileNum, 1
Get lngFileNum, , ststrMZ_Header
' -------------------------- ---------- ---------
' Look for the "magic header" values "MZ"
' If it doesn't exist, then it's not an EXE file
' -------------------------- ---------- ---------
If Mid$(ststrMZ_Header, 1, 2) <> "MZ" Then
SetConsoleApp = "Failed -- File is not an executable file."
GoTo ExitCheck
End If
' -------------------------- ---------- ---------
' Check to see if it's a MS-DOS executable
' -------------------------- ---------- ---------
CopyMem lngData, ByVal Mid$(ststrMZ_Header, DOS_FILE_OFFSET, 2), 2
If lngData < 64 Then
SetConsoleApp = "Failed -- File is 16-bit MSDOS EXE file."
GoTo ExitCheck
End If
' -------------------------- ---------- ---------
' Get the offset for the new .EXE header
' -------------------------- ---------- ---------
CopyMem lngNewPE_Offset, ByVal Mid$(ststrMZ_Header, 61, 4), 4
' -------------------------- ---------- ---------
' Get the "magic" header (NE, LE, PE)
' -------------------------- ---------- ---------
strMagic = Mid$(ststrMZ_Header, lngNewPE_Offset + 1, 2)
strMagicPE = Mid$(ststrMZ_Header, lngNewPE_Offset + 3, 2)
Select Case strMagic
' -------------------------- ---------- ---------
' Check for NT format
' -------------------------- ---------- ---------
Case "PE"
If strMagicPE <> vbNullChar & vbNullChar Then
SetConsoleApp = "Failed -- File is unknown 32-bit NT executable file."
GoTo ExitCheck
End If
' -------------------------- ---------- ---------
' Get the subsystem flags to identify NT
' character-mode
' -------------------------- ---------- ---------
lngData = Asc(Mid$(ststrMZ_Header, lngNewPE_Offset + PE_FLAG_OFFSET, 1))
If lngData <> 3 Then
On Error Resume Next
Err.Number = 0
Seek #lngFileNum, lngNewPE_Offset + PE_FLAG_OFFSET
Put lngFileNum, , 3
If Err.Number = 0 Then
SetConsoleApp = "Success -- Converted file to console app."
Else
SetConsoleApp = "Failed -- Error converting to console app: " & Err.Description
End If
Else
SetConsoleApp = "Failed -- Already a console app"
End If
Case Else
SetConsoleApp = "Failed -- Not correct file type."
End Select
ExitCheck:
' -------------------------- ---------- ---------
' Close the file
' -------------------------- ---------- ---------
Close lngFileNum
On Error GoTo 0
End Function
Public Function Exists(ByVal xstrFullName As String) As Boolean
On Error Resume Next ' Don't accept errors here
Const constProcName As String = "Exists"
Dim lngFileHwnd As Long
Dim lngRtn As Long
' -------------------------- ---------- ------
' Open the file only if it already exists
' -------------------------- ---------- ------
lngFileHwnd = CreateFile(xstrFullName, _
GENERIC_READ, 0&, _
0&, OPEN_EXISTING, _
FILE_ATTRIBUTE_NORMAL, 0&)
' -------------------------- ---------- ------
' If get these specific errors, then
' file doesn't exist
' -------------------------- ---------- ------
If lngFileHwnd = 0 Or lngFileHwnd = -1 Then
Exists = False
Else
' Success -- Must close the handle
lngRtn = CloseHandle(lngFileHwnd)
Exists = True
End If
On Error GoTo 0
End Function
' --------------------------
' MakeConsole.BAS -- Copyright (c) Slightly Tilted Software
' By: L.J. Johnson Date: 11-30-1997
' Comments: Contains MAIN(), plus the function
' which take a standard VB 5.0 EXE ( or VB 6.0 ! )
' and change it to a 32-bit console app
' --------------------------
Option Explicit
Option Base 1
DefLng A-Z
Private Const GENERIC_READ As Long = &H80000000
Private Const OPEN_EXISTING As Long = 3&
Private Const FILE_ATTRIBUTE_NORMAL As Long = &H80&
Private Const SCS_32BIT_BINARY = 0&
Private Const SCS_DOS_BINARY = 1&
Private Const SCS_WOW_BINARY = 2&
Private Const SCS_PIF_BINARY = 3&
Private Const SCS_POSIX_BINARY = 4&
Private Const SCS_OS216_BINARY = 5&
Private Const constMsgTitle = "Make Console App"
' --------------------------
' Windows API calls
' --------------------------
Public Declare Sub CopyMem _
Lib "kernel32" Alias "RtlMoveMemory" _
(dst As Any, src As Any, ByVal Size As Long)
Private Declare Function CloseHandle _
Lib "kernel32" _
(ByVal hObject As Long) As Long
Private Declare Function CreateFile _
Lib "kernel32" Alias "CreateFileA" _
(ByVal lpFileName As String, _
ByVal dwDesiredAccess As Long, _
ByVal dwShareMode As Long, _
ByVal lpSecurityAttributes As Long, _
ByVal dwCreationDisposition As Long, _
ByVal dwFlagsAndAttributes As Long, _
ByVal hTemplateFile As Long) As Long
Public Sub Main()
Dim strCmd As String
Dim strMsg As String
Dim strRtn As String
strCmd = Command$
If Trim$(strCmd) = "" Then
strMsg = "You must enter the name of a VB 5.0 standard executable file."
MsgBox strMsg, vbExclamation, constMsgTitle
Else
If InStr(1, strCmd, ".", vbTextCompare) = 0 Then
strCmd = strCmd & ".EXE"
End If
If Exists(strCmd) = True Then
strRtn = SetConsoleApp(strCmd)
MsgBox strRtn, vbInformation, constMsgTitle
Else
strMsg = "The file, " & Trim$(strCmd) & ", does not exist."
MsgBox strMsg, vbCritical, constMsgTitle
End If
End If
End Sub
Private Function SetConsoleApp(xstrFileName
Dim lngFileNum As Long
Dim ststrMZ_Header As String * 512
Dim strMagic As String * 2
Dim strMagicPE As String * 2
Dim lngNewPE_Offset As Long
Dim lngData As Long
Dim strTmp As String
Const PE_FLAG_OFFSET As Long = 93&
Const DOS_FILE_OFFSET As Long = 25&
' --------------------------
' See if file actually exists
' --------------------------
strTmp = Trim$(Dir$(xstrFileName))
If Len(strTmp) = 0 Then
SetConsoleApp = "Failed -- The file, " & xstrFileName & ", does not exist!"
GoTo ExitCheck
End If
' --------------------------
' Get a free file handle
' --------------------------
On Error Resume Next
lngFileNum = FreeFile
Open xstrFileName For Binary Access Read Write Shared As lngFileNum
' --------------------------
' Get the first 512 characters from from file
' --------------------------
Seek #lngFileNum, 1
Get lngFileNum, , ststrMZ_Header
' --------------------------
' Look for the "magic header" values "MZ"
' If it doesn't exist, then it's not an EXE file
' --------------------------
If Mid$(ststrMZ_Header, 1, 2) <> "MZ" Then
SetConsoleApp = "Failed -- File is not an executable file."
GoTo ExitCheck
End If
' --------------------------
' Check to see if it's a MS-DOS executable
' --------------------------
CopyMem lngData, ByVal Mid$(ststrMZ_Header, DOS_FILE_OFFSET, 2), 2
If lngData < 64 Then
SetConsoleApp = "Failed -- File is 16-bit MSDOS EXE file."
GoTo ExitCheck
End If
' --------------------------
' Get the offset for the new .EXE header
' --------------------------
CopyMem lngNewPE_Offset, ByVal Mid$(ststrMZ_Header, 61, 4), 4
' --------------------------
' Get the "magic" header (NE, LE, PE)
' --------------------------
strMagic = Mid$(ststrMZ_Header, lngNewPE_Offset + 1, 2)
strMagicPE = Mid$(ststrMZ_Header, lngNewPE_Offset + 3, 2)
Select Case strMagic
' --------------------------
' Check for NT format
' --------------------------
Case "PE"
If strMagicPE <> vbNullChar & vbNullChar Then
SetConsoleApp = "Failed -- File is unknown 32-bit NT executable file."
GoTo ExitCheck
End If
' --------------------------
' Get the subsystem flags to identify NT
' character-mode
' --------------------------
lngData = Asc(Mid$(ststrMZ_Header, lngNewPE_Offset + PE_FLAG_OFFSET, 1))
If lngData <> 3 Then
On Error Resume Next
Err.Number = 0
Seek #lngFileNum, lngNewPE_Offset + PE_FLAG_OFFSET
Put lngFileNum, , 3
If Err.Number = 0 Then
SetConsoleApp = "Success -- Converted file to console app."
Else
SetConsoleApp = "Failed -- Error converting to console app: " & Err.Description
End If
Else
SetConsoleApp = "Failed -- Already a console app"
End If
Case Else
SetConsoleApp = "Failed -- Not correct file type."
End Select
ExitCheck:
' --------------------------
' Close the file
' --------------------------
Close lngFileNum
On Error GoTo 0
End Function
Public Function Exists(ByVal xstrFullName As String) As Boolean
On Error Resume Next ' Don't accept errors here
Const constProcName As String = "Exists"
Dim lngFileHwnd As Long
Dim lngRtn As Long
' --------------------------
' Open the file only if it already exists
' --------------------------
lngFileHwnd = CreateFile(xstrFullName, _
GENERIC_READ, 0&, _
0&, OPEN_EXISTING, _
FILE_ATTRIBUTE_NORMAL, 0&)
' --------------------------
' If get these specific errors, then
' file doesn't exist
' --------------------------
If lngFileHwnd = 0 Or lngFileHwnd = -1 Then
Exists = False
Else
' Success -- Must close the handle
lngRtn = CloseHandle(lngFileHwnd)
Exists = True
End If
On Error GoTo 0
End Function
TimCottee,
As far as I can tell that code does *not* change your VB program into a console program. What it seems to allow you do is run an existing DOS .exe through your VB front end or something like that.
Am I missing something.
PS -
Jamsie, this is *not* a newsgroup. We've provided some information, it would be appreciated if you would acknowledge receipt and tell us what you think of it. If one of us managed to answer your question, please grade the answer.
As far as I can tell that code does *not* change your VB program into a console program. What it seems to allow you do is run an existing DOS .exe through your VB front end or something like that.
Am I missing something.
PS -
Jamsie, this is *not* a newsgroup. We've provided some information, it would be appreciated if you would acknowledge receipt and tell us what you think of it. If one of us managed to answer your question, please grade the answer.
caraf_g, perhaps I didn't make it's use clear, if you create an application in VB, Using no forms, but using the Win32 console api calls.
Using the code above, create an executable called MakeVBCon.exe. In a command prompt type
MakeVBCon MyApplication.exe
where MyApplicaton.exe is the executable created for the program written as a console.
This will convert the second exe into a console application.
Try it out, it works! I am using it to create a program which will run in a telnet session from a DOS 5.0 RF scanner handset.
Using the code above, create an executable called MakeVBCon.exe. In a command prompt type
MakeVBCon MyApplication.exe
where MyApplicaton.exe is the executable created for the program written as a console.
This will convert the second exe into a console application.
Try it out, it works! I am using it to create a program which will run in a telnet session from a DOS 5.0 RF scanner handset.
OK.. see my comment of Friday, April 07 2000 - 03:46PM IST
Take the example and compile it. This will create a "console" application.
Start an MS-DOS prompt. Manoeuvre to the correct directory and run the above console application. It will work just like a console, but it will be started in a new window, not in the DOS window from which it was originally called.
So far so good, that was what I was talking about so far...
Then, I took your example program and created it. I ran it against the "console" app described above. It said "Success" (etc).
Now, if I try to run the "console" app, indeed, no second window is opened. But I can't see the original console app anymore. The DOS window from which I started it just seems to "hang".
Still missing something...
Take the example and compile it. This will create a "console" application.
Start an MS-DOS prompt. Manoeuvre to the correct directory and run the above console application. It will work just like a console, but it will be started in a new window, not in the DOS window from which it was originally called.
So far so good, that was what I was talking about so far...
Then, I took your example program and created it. I ran it against the "console" app described above. It said "Success" (etc).
Now, if I try to run the "console" app, indeed, no second window is opened. But I can't see the original console app anymore. The DOS window from which I started it just seems to "hang".
Still missing something...
caraf_g, with the smpConsole example, change the OpenConsole procedure as below:
Public Function OpenConsole(Capt As String)
' If AllocConsole() Then
SetConsoleTitle Capt
hInConsole = GetStdHandle(STD_INPUT_HAN DLE)
hOutConsole = GetStdHandle(STD_OUTPUT_HA NDLE)
' If hOutConsole = 0 Then
' FreeConsole
' Else
' SetConsoleCtrlHandler AddressOf ConsoleHandler, True
' OpenConsole = True
' End If
' End If
End Function
This doesn't create a new console but gets the handles to the current one instead. I have just tried it out and get the same results as the original example but in the original console window.
Public Function OpenConsole(Capt As String)
' If AllocConsole() Then
SetConsoleTitle Capt
hInConsole = GetStdHandle(STD_INPUT_HAN
hOutConsole = GetStdHandle(STD_OUTPUT_HA
' If hOutConsole = 0 Then
' FreeConsole
' Else
' SetConsoleCtrlHandler AddressOf ConsoleHandler, True
' OpenConsole = True
' End If
' End If
End Function
This doesn't create a new console but gets the handles to the current one instead. I have just tried it out and get the same results as the original example but in the original console window.
Wow... I stand corrected!
Jamsie. You better do the decent thing and give TimCottee a straight "A"
Jamsie. You better do the decent thing and give TimCottee a straight "A"
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks Chaps for the help,
It's saved my life.
Sorry about being slow to get back to TimCotte and administer them there points and a deserved Grade **A**
I've got a couple of apps using this stuff already. Very Easy to Use.
Cheers
Jamsey
It's saved my life.
Sorry about being slow to get back to TimCotte and administer them there points and a deserved Grade **A**
I've got a couple of apps using this stuff already. Very Easy to Use.
Cheers
Jamsey
Excellent!
You can create a console app in VB alright, BUT this console app will create *it's own* console into which you can direct stdIN and Output, but you cannot redirect this to the CMD.EXE from which you originally started the program YourVBProgram.exe
Alas....
There's also been an article about this in a recend VB Programmers Journal, but I don't remember which one it was. But trust me on this one.
If you're happy with an application that creates its own console then let me know but from your question I'd say you won't be. In that case you'll have to resign yourself to the fact that you cannot do this.
Please don't shoot the messenger :o)