Page 1 of 1
Writing Console Applications In Vb 6? Is it possiable without an add on dll?
#5
Re: Writing Console Applications In Vb 6?
Posted 12 January 2005 - 05:48 PM
After Digging Through some api functions i wrote a dll to create a Console window. If you run the application from the command prompt it will create a new console window but it is truly a console window. Code below:
ActiveX DLL
Project Name: Con
Class Name: Console
Then use sub main() as follows
ActiveX DLL
Project Name: Con
Class Name: Console
Private Const FOREGROUND_BLUE = &H1 Private Const FOREGROUND_GREEN = &H2 Private Const FOREGROUND_RED = &H4 Private Const BACKGROUND_BLUE = &H10 Private Const BACKGROUND_GREEN = &H20 Private Const BACKGROUND_RED = &H40 Private Const BACKGROUND_INTENSITY = &H80& Private Const BACKGROUND_SEARCH = &H20& Private Const FOREGROUND_INTENSITY = &H8& Private Const FOREGROUND_SEARCH = (&H10&) Private Const ENABLE_LINE_INPUT = &H2& Private Const ENABLE_ECHO_INPUT = &H4& Private Const ENABLE_MOUSE_INPUT = &H10& Private Const ENABLE_PROCESSED_INPUT = &H1& Private Const ENABLE_WINDOW_INPUT = &H8& Private Const ENABLE_PROCESSED_OUTPUT = &H1& Private Const ENABLE_WRAP_AT_EOL_OUTPUT = &H2& Private Const STD_OUTPUT_HANDLE = -11& Private Const STD_INPUT_HANDLE = -10& Private Const STD_ERROR_HANDLE = -12& Private Const INVALID_HANDLE_VALUE = -1& Private Declare Function AllocConsole Lib "kernel32" () As Long Private Declare Function FreeConsole Lib "kernel32" () As Long Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long Private Declare Function GetStdHandle Lib "kernel32" (ByVal nStdHandle As Long) As Long Private Declare Function WriteConsole Lib "kernel32" Alias "WriteConsoleA" (ByVal hConsoleOutput As Long, lpBuffer As Any, ByVal nNumberOfCharsToWrite As Long, lpNumberOfCharsWritten As Long, lpReserved As Any) As Long Private Declare Function ReadConsole Lib "kernel32" Alias "ReadConsoleA" (ByVal hConsoleInput As Long, ByVal lpBuffer As String, ByVal nNumberOfCharsToRead As Long, lpNumberOfCharsRead As Long, lpReserved As Any) As Long Private Declare Function SetConsoleTextAttribute Lib "kernel32" (ByVal hConsoleOutput As Long, ByVal wAttributes As Long) As Long Private Declare Function SetConsoleTitle Lib "kernel32" Alias "SetConsoleTitleA" (ByVal lpConsoleTitle As String) As Long Private Loaded As Boolean Private hConsoleOut As Long, hConsoleIn As Long, hConsoleErr As Long Sub StartUp(cTitle As String) 'Create console If Loaded Then Shutdown End If If AllocConsole() Then hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE) If hConsoleOut = INVALID_HANDLE_VALUE Then MsgBox "Unable to get STDOUT" hConsoleIn = GetStdHandle(STD_INPUT_HANDLE) If hConsoleOut = INVALID_HANDLE_VALUE Then MsgBox "Unable to get STDIN" Else MsgBox "Couldn't allocate console" End If 'Set the caption of the console window SetConsoleTitle cTitle 'Set the background color of the text in the console SetConsoleTextAttribute hConsoleOut, FOREGROUND_GREEN Or FOREGROUND_INTENSITY Loaded = True End Sub Sub Shutdown() 'Delete console CloseHandle hConsoleOut CloseHandle hConsoleIn FreeConsole Loaded = False End Sub Sub ConsoleWriteLine(sInput As String) ConsoleWrite sInput + vbCrLf End Sub Sub ConsoleWrite(sInput As String) If Loaded = True Then Dim cWritten As Long WriteConsole hConsoleOut, ByVal sInput, Len(sInput), cWritten, ByVal 0& End If End Sub Function ConsoleReadLine() As String If Loaded = True Then Dim ZeroPos As Long 'Create a buffer ConsoleReadLine = String(10, 0) 'Read the input ReadConsole hConsoleIn, ConsoleReadLine, Len(ConsoleReadLine), vbNull, vbNull 'Strip off trailing vbCrLf and Chr$(0)'s ZeroPos = InStr(ConsoleReadLine, Chr$(0)) If ZeroPos > 0 Then ConsoleReadLine = Left$(ConsoleReadLine, ZeroPos - 3) End If End Function Function IsLoaded() As Boolean IsLoaded = Loaded End Function Sub SetTitle(NewTitle As String) SetConsoleTitle NewTitle End Sub
Then use sub main() as follows
Sub Main()
Dim obj as object
Dim TMP as String
obj = createObject("Con.Console")
Obj.StartUp "My Console"
Obj.ConsoleWriteLine "Hello World"
Obj.ConsoleWriteLine "Press Enter To Exit"
tmp = Obj.ConsoleReadLine
Obj.ShutDown
End Sub
#54
Re: Writing Console Applications In Vb 6?
Posted 26 January 2005 - 01:16 AM
It is quite possible, and there can be good reasons for doing so.
The "Basics"
The obvious issue is the user interface. Instead of relying on forms and dialogs, a console-mode VB program uses:
The other way involves Win32 API calls, and has some advantages such as the ability to do binary I/O over the stdio streams (stdin, stdout, and stderr). You can do a web search and find the necessary API function prototypes and sample code lots of places. Here's one: http://support.micro...com/kb/q239588/
To exit and pass a return code you need another API call:
Be careful with this if working within the IDE. It will exit the IDE and all, without saving any pending changes to your project out to disk!
That's About It
That pretty much covers it, except to say that you also start a VB command-line project by creating a regular Standard EXE project, removing Form1, and adding a standard Module. To this module you add Sub Main() which is where your program execution begins.
Then check the project properties, and verify that Sub Main is set as your "startup object." You can also check Unattended Execution (especially for your final compiles) to suppress dialogs popping up for error exceptions or MsgBox calls - which will be diverted to the log. On an NT OS (NT 4.0, Win2K, WinXP) this will default to the NT Application Event Log. You may not want this, so check out the VB App.StartLogging (and for that matter App.LogEvent) method call in the docs.
Oh... The "Secret"
One really important detail nobody talks about much is that for a compiled VB program to run as a console program, it has to be linked for the Console subsystem in Windows. Otherwise none of this will work at all.
The VB IDE doesn't support this - so the easiest option is to relink the EXE after compiling it:
LINK /EDIT /SUBSYSTEM:CONSOLE {your exe's filename}
LINK.EXE comes with VB6, probably VB5 as well. To make this easier I keep this short script around:
Drag'n'drop can be a convenient thing.
One Practical Use
One of the severely underestimated uses of VB is for writing CGI programs. You can build some spiffy web applications that run rings around ASP pages from a performance standpoint... we won't even talk about the elephantine creature that is ASP.Net. Try getting that stuff running on an old PII 233 box!
But CGI demands a true console application, not a GUI VB program.
Last Words
While working within the IDE on a console program you may find that it makes sense to open a new console window to interact in while in develop/test mode. This has already been discussed. Others use a form with a big textbox or something to simulate the console.
In such cases you may want to use conditional compilation (#If blnDevel Then... statements) and the properties dialog's Conditional Compilation Arguments field to include/exclude the testing logic.
The Command$() function returns the whole command line parameter text as one string. If you wanted the parameters parsed acording to space delimiters just use something like Split(Command$(), " ") and you're home free.
But yes, you can write real console applications in VB and there is no reason not to. For simple ones that do text I/O, my example above shows how easy this is: you can do it without a single API call if you use the FSO.
The "Basics"
The obvious issue is the user interface. Instead of relying on forms and dialogs, a console-mode VB program uses:
- Command$()
- Environ$()
- Standard I/O
- Return codes
'Requires a reference to Microsoft Scripting Runtime. Sub Main() Dim FSO As New Scripting.FileSystemObject Dim sin As Scripting.TextStream Dim sout As Scripting.TextStream Dim strWord As String Set sin = FSO.GetStandardStream(StdIn) Set sout = FSO.GetStandardStream(StdOut) sout.WriteLine "Hello!" sout.WriteLine "What's the word?" strWord = sin.ReadLine() sout.WriteLine "So, the word is " & strWord Set sout = Nothing Set sin = Nothing End Sub
The other way involves Win32 API calls, and has some advantages such as the ability to do binary I/O over the stdio streams (stdin, stdout, and stderr). You can do a web search and find the necessary API function prototypes and sample code lots of places. Here's one: http://support.micro...com/kb/q239588/
To exit and pass a return code you need another API call:
Private Declare Sub ExitProcess Lib "kernel32" _ (ByVal uExitCode As Long)
Be careful with this if working within the IDE. It will exit the IDE and all, without saving any pending changes to your project out to disk!
That's About It
That pretty much covers it, except to say that you also start a VB command-line project by creating a regular Standard EXE project, removing Form1, and adding a standard Module. To this module you add Sub Main() which is where your program execution begins.
Then check the project properties, and verify that Sub Main is set as your "startup object." You can also check Unattended Execution (especially for your final compiles) to suppress dialogs popping up for error exceptions or MsgBox calls - which will be diverted to the log. On an NT OS (NT 4.0, Win2K, WinXP) this will default to the NT Application Event Log. You may not want this, so check out the VB App.StartLogging (and for that matter App.LogEvent) method call in the docs.
Oh... The "Secret"
One really important detail nobody talks about much is that for a compiled VB program to run as a console program, it has to be linked for the Console subsystem in Windows. Otherwise none of this will work at all.
The VB IDE doesn't support this - so the easiest option is to relink the EXE after compiling it:
LINK /EDIT /SUBSYSTEM:CONSOLE {your exe's filename}
LINK.EXE comes with VB6, probably VB5 as well. To make this easier I keep this short script around:
Option Explicit
'LinkConsole.vbs
'
'This is a WSH script used to make it easier to edit
'a compiled VB6 EXE using LINK.EXE to create a console
'mode program.
'
'Drag the EXE's icon onto the icon for this file, or
'execute it from a command prompt as in:
'
' LinkConsole.vbs <EXEpath&file>
'
'Be sure to set up strLINK to match your VB6 installation.
Dim strLINK, strEXE, WSHShell
strLINK = _
"""C:\Program Files\Microsoft Visual Studio\VB98\LINK.EXE"""
strEXE = """" & WScript.Arguments(0) & """"
Set WSHShell = CreateObject("WScript.Shell")
WSHShell.Run _
strLINK & " /EDIT /SUBSYSTEM:CONSOLE " & strEXE
Set WSHShell = Nothing
WScript.Echo "Complete!"
Drag'n'drop can be a convenient thing.
One Practical Use
One of the severely underestimated uses of VB is for writing CGI programs. You can build some spiffy web applications that run rings around ASP pages from a performance standpoint... we won't even talk about the elephantine creature that is ASP.Net. Try getting that stuff running on an old PII 233 box!
But CGI demands a true console application, not a GUI VB program.
Last Words
While working within the IDE on a console program you may find that it makes sense to open a new console window to interact in while in develop/test mode. This has already been discussed. Others use a form with a big textbox or something to simulate the console.
In such cases you may want to use conditional compilation (#If blnDevel Then... statements) and the properties dialog's Conditional Compilation Arguments field to include/exclude the testing logic.
The Command$() function returns the whole command line parameter text as one string. If you wanted the parameters parsed acording to space delimiters just use something like Split(Command$(), " ") and you're home free.
But yes, you can write real console applications in VB and there is no reason not to. For simple ones that do text I/O, my example above shows how easy this is: you can do it without a single API call if you use the FSO.
#56
Re: Writing Console Applications In Vb 6?
Posted 03 February 2005 - 06:53 AM
...I am using VB 6 and I am trying to create a simple executable which takes in an argument (from the command-line) and prints it back out to the console.
You would run it like:
C:> myApp.exe some_argument_here
And I would like to see printed out to the console,
Your argument was: some_argument_here
There is no way to do this?...is that what I am hearing? I have to use VB since I am converting a VBScript to VB.
any suggestions help, other than to use C++.
thanks
You would run it like:
C:> myApp.exe some_argument_here
And I would like to see printed out to the console,
Your argument was: some_argument_here
There is no way to do this?...is that what I am hearing? I have to use VB since I am converting a VBScript to VB.
any suggestions help, other than to use C++.
thanks
#57
Re: Writing Console Applications In Vb 6?
Posted 05 February 2005 - 11:19 AM
Reread what I had written up above.
Your program would be as simple as:
It only gets more complicated if you choose not to use the FSO for your stdio streams. This is only slightly more work though, involving calls to Win32 APIs to read or write the console streams.
Your program would be as simple as:
Sub Main() Dim FSO As New Scripting.FileSystemObject FSO.GetStandardStream(StdOut).WriteLine _ "Your argument was " & Command$() End Sub
It only gets more complicated if you choose not to use the FSO for your stdio streams. This is only slightly more work though, involving calls to Win32 APIs to read or write the console streams.
Page 1 of 1

Ask A New Question
Reply




MultiQuote






|