Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Write a VB Console (the non-GUI) Application

Graphical User Interface (GUI)

Write a VB Console (the non-GUI) Application

by  dilettante  Posted    (Edited  )
The "Basics"

The obvious issue is the user interface. Instead of relying on forms and dialogs, a console-mode VB program uses:
[ul][li]Command$()[/li]
[li]Environ$()[/li]
[li]Standard I/O[/li]
[li]Return codes[/li][/ul]
Standard I/O is accessible in either of two ways. One involves using the Scripting.FileSystemObject and is quick and dirty:
Code:
'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.microsoft.com/kb/q239588/

To exit and pass a return code you need another API call:
Code:
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.

Real Console Programs

I've seen a lot of sample code published that pretends to provide this sort of solution. Most of them simply allocate a new console from within a Windows-mode VB program and let you interact with that.

What good is that? Might be good for debugging a console application from the IDE, but you can't accept redirected or piped streams, interact with .BAT/.CMD files, or create CGI applications for the web.

This mechanism doesn't have those limitations: you get an actual console application out of it.

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, at least on NT-based OSs.

The VB IDE doesn't support this - so the easiest option is to relink the EXE after compiling it:

[tt]LINK /EDIT /SUBSYSTEM:CONSOLE {your exe's filename}[/tt]

LINK.EXE comes with VB6 and VB5 as well. To make this easier I keep this short script around:
Code:
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 VB 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 Use

Imagine using VB technology with web servers other than IIS/PWS!

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. Some people 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 [tt]Split(Command$(), " ")[/tt] 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.
Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top