Solved

Console output (STDOut for VB)?

Posted on 2001-08-15
16
666 Views
Last Modified: 2012-06-27
Okay, I wrote a command line program with no forms (just a quick cludge) and I wanted to be able to output to the console some message.

I've searched quite a bit and haven't found anything that will let me print a simple string to the cmdline like I want.  The only way I've been able to do it is to use msgbox, but I don't want any windows involved.  Just return a result by command line.

Is there a simple way to do this that I'm missing?
0
Comment
Question by:Sorklin
  • 5
  • 4
  • 3
  • +3
16 Comments
 
LVL 8

Expert Comment

by:DennisBorg
ID: 6389443
0
 
LVL 20

Expert Comment

by:hes
ID: 6389457
Also take a look here:
http://www.saurik.com/samples/

look at smpConsole
0
 
LVL 38

Expert Comment

by:PaulHews
ID: 6389625
The trouble I've seen with this is that I've been unable to attach to a pre-existing command line window, only start a new console window.  At this point, I have not solved it or seen it solved.
0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
LVL 8

Expert Comment

by:DennisBorg
ID: 6389870
Good point, Paul.

But how would one determine which pre-existing console window to target? One could have many open at the time, but all would have been spawned by COMMAND.COM or CMD.EXE

-Dennis Borg
0
 
LVL 38

Expert Comment

by:PaulHews
ID: 6390358
That's part of the trouble.  The other part is that VB programs do not have any built in console function, they are compiled as GUI applications, not console apps.  They can allocate a new console easily enough, but there doesn't seem to be anyway to attach to an existing StdIn/StdOut the way one would when starting a program from a batch file or from the command prompt.

This is detailed here:
HOWTO: Attach a Console Window to Your Visual Basic Program

http://support.microsoft.com/support/kb/articles/Q171/6/54.asp
0
 
LVL 38

Expert Comment

by:PaulHews
ID: 6390364
Quote:

If a Visual Basic application is started from a console application, the operating system automatically detaches it from the console, preventing the Visual Basic application from interacting with it. This article does not provide a method to prevent this from happening, but does demonstrate creating a new console window that your application can interact with. It also demonstrates running a console application (batch file, in this case) from Visual Basic, which utilizes the created console.
0
 
LVL 14

Expert Comment

by:wsh2
ID: 6390712
<Movie line; circa 1940s.. "Say it isn't so Joe">

Sad, but true.. <sigh>
0
 
LVL 8

Expert Comment

by:DennisBorg
ID: 6390833
Good info, Paul. Thank you for the input!
0
 
LVL 43

Accepted Solution

by:
TimCottee earned 100 total points
ID: 6391727
Sorklin, there is a solution to this but not an obvious one. Firstly get rid of any allocconsole in your application you won't need this any more as it will spawn an additional console window which is not what you need. Then compile your application as normal but before you run it hack it using the following:

Simply paste this code into a module and then compile to MakeVBCon.EXE. Then with the compiled console application executable do

MakeVBCon MyApplication.exe. This will then run in the original console window in which it was launched.

' ------------------------------------------------------
' 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

Essentially windows is fooled by this rewrite of the executable header into thinking that the application is actually a DOS one not a GUI one. I have used this a number of times to create applications that run in a telnet environment. Accessed by handheld scanners such as Symbol and Telxon running VT220 terminal emulation against the telnet server.
0
 
LVL 8

Expert Comment

by:DennisBorg
ID: 6392462
Thanks, Tim!
0
 
LVL 38

Expert Comment

by:PaulHews
ID: 6392568
Neat hack!
0
 
LVL 1

Author Comment

by:Sorklin
ID: 6392763
Tim, I haven't tried it yet, but I will.  Sounds like what I want.
0
 
LVL 1

Author Comment

by:Sorklin
ID: 6392872
Very neat hack.  Where did you ever figure this one out?
0
 
LVL 43

Expert Comment

by:TimCottee
ID: 6393052
Not my code I freely admit, I found it in an old question posted by mcrider I think. Gave it a go and it worked excellently. It is a handy tool to keep in the arsenal.
0
 
LVL 8

Expert Comment

by:DennisBorg
ID: 6393296
>It is a handy tool to keep in the arsenal.

A very good thing to know!
0
 
LVL 1

Author Comment

by:Sorklin
ID: 6393897
Exactly what this forum is for.  It would take me a thousand years to come up with something like this.  Thanks.
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
VBA to copy paste columns form one file to other 20 90
Run code from text file in vb 1 71
vbModal 12 57
VBA: Insert New column with specific format type 12 38
Introduction I needed to skip over some file processing within a For...Next loop in some old production code and wished that VB (classic) had a statement that would drop down to the end of the current iteration, bypassing the statements that were c…
Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

807 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question