Board index » Visual Studio » VB6 Shell Question

VB6 Shell Question

Visual Studio175
I have a command line program that I want to execute from my visual basic

program, which is easy enough. But I cannot figure out how to read the text

that the command line program returns. I just need to know if the programs

executes correctly, and if not, it returns an error string which would be

helpful to provide an explanation to the user.



Any help would be greatly appreciated! Thanks,



Nathan


-
 

Re:VB6 Shell Question

Nathan Perkins wrote:

Quote
I have a command line program that I want to execute from my visual basic

program, which is easy enough. But I cannot figure out how to read the text

that the command line program returns. I just need to know if the programs

executes correctly, and if not, it returns an error string which would be

helpful to provide an explanation to the user.



Any help would be greatly appreciated! Thanks,



Nathan



This shows how to get an Exit Code from a shelled app. It may help.



HOWTO: Use a 32-Bit Application to Determine When a Shelled Process Ends

http://support.microsoft.com/default.aspx?scid" rel="nofollow" target="_blank">support.microsoft.com/default.aspx=kb;EN-US;129796



--

Ken Halter - MS-MVP-VB - www.vbsight.com">www.vbsight.com

Please keep all discussions in the groups..

-

Re:VB6 Shell Question

I tried that, but I actually need the text returned, not just the exit code.



Thanks though - Nathan



"Ken Halter" <Ken_Halter@Use_Sparingly_Hotmail.com>wrote in message

Quote
Nathan Perkins wrote:

>I have a command line program that I want to execute from my visual basic

>program, which is easy enough. But I cannot figure out how to read the

>text that the command line program returns. I just need to know if the

>programs executes correctly, and if not, it returns an error string which

>would be helpful to provide an explanation to the user.

>

>Any help would be greatly appreciated! Thanks,

>

>Nathan



This shows how to get an Exit Code from a shelled app. It may help.



HOWTO: Use a 32-Bit Application to Determine When a Shelled Process Ends

http://support.microsoft.com/default.aspx?scid" rel="nofollow" target="_blank">support.microsoft.com/default.aspx=kb;EN-US;129796



--

Ken Halter - MS-MVP-VB - www.vbsight.com">www.vbsight.com

Please keep all discussions in the groups..





-

Re:VB6 Shell Question

"Nathan Perkins" <NPerkins@maxmo.net>wrote in message

Quote
I tried that, but I actually need the text returned, not just the

exit code.



the easiest way is usually to redirect the text to a file but it depends on

if the text is written to stdout or stderr and whether you need to support

Win9x systems or not.



-

Re:VB6 Shell Question

I tried using



shell "prog.exe>output.txt"



, but no file was created. Is there something more to writing the output to

a file? I am pretty sure the output is written via stderr. Would I have to

change the line to make that work?



I am not fully set on 9x systems, but it would be nice. What difference

exists there?



"Bob Butler" <tiredofit@nospam.com>wrote in message

Quote
"Nathan Perkins" <NPerkins@maxmo.net>wrote in message

news:OXhKLlVWEHA.3476@tk2msftngp13.phx.gbl

>I tried that, but I actually need the text returned, not just the

>exit code.



the easiest way is usually to redirect the text to a file but it depends

on

if the text is written to stdout or stderr and whether you need to support

Win9x systems or not.







-

Re:VB6 Shell Question

Nathan Perkins wrote:

Quote
I tried using



shell "prog.exe>output.txt"





Did you try specifying the path to 'output.txt'? Maybe it was created

but you can't find it. If prog.exe's in a folder that's specified in the

Path environment variable, it'll run but that file's going to end up in

the systems current folder... unless you specify the path



--

Ken Halter - MS-MVP-VB - www.vbsight.com">www.vbsight.com

Please keep all discussions in the groups..

-

Re:VB6 Shell Question

The following is a compilation of several posts I've given in the past

regarding the Shell command. Your question is addressed in there; the

remainder is for your consideration.



Rick -MVP



You can use the Shell command. To execute internal DOS command (Dir,

Copy, etc. as well as redirection of screen output), the command

processor must be specified (using the Environ$ function and "comspec"

as its argument returns the correct command processor path on NT and

non-NT systems) . Specifying the command processor is safe & generic and

will work with non-internal commands also. That syntax, using an XCopy

command as an example is:



Shell Environ$("comspec") & " /c xcopy """ & _

Source & """ """ & Destination & """ " & Option, vbHide



You set the Source and Desination (string variables) to the appropriate

paths and the Option (string variable), if any, which can be found by

opening an MSDOS Prompt window and typing xcopy /?. (Note: You can type

/? after any DOS command at a DOS prompt to list the available options

for that command.) One more example would be to list all the files in a

directory including subdirectories and subdirectories of subdirectories

and all of their files.



CommandLine = "dir """ & FileSpec & _

""" /s/b>""" & RedirectTo & """"

Shell Environ$("comspec") & " /c " & CommandLine, vbHide



Here, the output of a Dir command is redirected to a file-path you

specify in the RedirectTo (string variable). The /s/b are options to the

Dir command that tell it to recurse throught its subdirectories and not

to include header or summary information.



I used a variable for the file name so that I could more easily explain

the benefit of encasing it in quotemarks. If you redirect to a file that

has spaces in its name, or if there are spaces in the path specification

itself, then the filename *must* be quoted to protect the spaces from

DOS's desire to use them as delimiters. (That's what all those

quotemarks in the Shell statement are for.) If the filename doesn't have

spaces in it, the quotes aren't necessary BUT they don't hurt either.

Hence, the above will work with either.



As for your PING question, something like the following should work:



strIP = "4.17.23.1"

Shell Environ$("comspec") & " /c ping " & _

strIP & ">""" & RedirectFile & """", vbHide



Although you didn't specify it in your original post, I assume you want

to use vbHide for the optional 2nd parameter to Shell. This hides the

DOS window so that your user doesn't see it. If you want the DOS window

to remain visible, you would use the vbNormalFocus BUT you must use a /k

instead of a /c for the command processor argument. Basically, the /c

tells the command processor "here comes a command and, when its finished

executing, close the DOS shell it is running in" whereas the /k also

tells the command processor that a command follows, but it instructs it

to leave the DOS session running.



The above assumes you do NOT have to wait for this file to be completely

written before your code continues executing. If you have to work with

this file right after it is created, consider one of these (which makes

your program wait until the DOS process is finished):



MICROSOFT 'S OFFICIAL WAY

========================

See this link



support.microsoft.com/support/kb/articles/Q129/7/96.asp">support.microsoft.com/support/kb/articles/Q129/7/96.asp



Note: This method doesn't use Shell -- it uses CreateProcessA.





FAST AND DIRTY METHOD (WORKS ALMOST ALL THE TIME)

=================================================

Paste these lines in the (General)(Declarations) section of the form

where the Shell is being called (or remove the Private keywords and put

them in a BAS module if more than one form will use them):



Private Declare Function OpenProcess _

Lib "kernel32" _

(ByVal dwDesiredAccess As Long, _

ByVal bInheritHandle As Long, _

ByVal dwProcessId As Long) As Long

Private Declare Function CloseHandle _

Lib "kernel32" _

(ByVal hObject As Long) As Long

Private Declare Function WaitForSingleObject _

Lib "kernel32" _

(ByVal hHandle As Long, _

ByVal dwMilliseconds As Long) As Long



Call your Shell command in this form with the appropriate Shell

arguments placed in the parentheses:



PID = Shell( <<Put Shell Arguments Here>>)



And finally, paste the following IMMEDIATELY after the PID=Shell

statement above (making sure to handle the possible error where

indicated; i.e. stop the code from falling through to your other

commands if the Shell failed):



If PID = 0 Then

'

'Handle Error, Shell Didn't Work

'

Else

hProcess = OpenProcess(&H100000, True, PID)

WaitForSingleObject hProcess, -1

CloseHandle hProcess

End If











"Nathan Perkins" <NPerkins@maxmo.net>wrote in message

Quote
I tried using



shell "prog.exe>output.txt"



, but no file was created. Is there something more to writing the

output to

a file? I am pretty sure the output is written via stderr. Would I

have to

change the line to make that work?



I am not fully set on 9x systems, but it would be nice. What

difference

exists there?



"Bob Butler" <tiredofit@nospam.com>wrote in message

news:eApdR4VWEHA.2288@TK2MSFTNGP10.phx.gbl...

>"Nathan Perkins" <NPerkins@maxmo.net>wrote in message

>news:OXhKLlVWEHA.3476@tk2msftngp13.phx.gbl

>>I tried that, but I actually need the text returned, not just the

>>exit code.

>

>the easiest way is usually to redirect the text to a file but it

depends

>on

>if the text is written to stdout or stderr and whether you need to

support

>Win9x systems or not.

>







-

Re:VB6 Shell Question

That helps a lot, but I am still having some minor problems.



I have decided to just write my program for 2000 and XP, so I can redirect

stderr, but due to the complexity of my command, it doesn't execute.



My shell command essentially ends up as:



cmd.exe /c "C:\Software Projects\current\blah.exe" -x "C:\Documents and

Settings\Nathan Perkins\My Documents\some text file.txt">"C:\Software

Projects\current\output.tmp" 2>&1



In the end, a command window opens but that is it. I think that I need to

escape certain characters. Any idea?

"Rick Rothstein" <rickNOSPAMnews@NOSPAMcomcast.net>wrote in message

Quote
The following is a compilation of several posts I've given in the past

regarding the Shell command. Your question is addressed in there; the

remainder is for your consideration.



Rick -MVP



You can use the Shell command. To execute internal DOS command (Dir,

Copy, etc. as well as redirection of screen output), the command

processor must be specified (using the Environ$ function and "comspec"

as its argument returns the correct command processor path on NT and

non-NT systems) . Specifying the command processor is safe & generic and

will work with non-internal commands also. That syntax, using an XCopy

command as an example is:



Shell Environ$("comspec") & " /c xcopy """ & _

Source & """ """ & Destination & """ " & Option, vbHide



You set the Source and Desination (string variables) to the appropriate

paths and the Option (string variable), if any, which can be found by

opening an MSDOS Prompt window and typing xcopy /?. (Note: You can type

/? after any DOS command at a DOS prompt to list the available options

for that command.) One more example would be to list all the files in a

directory including subdirectories and subdirectories of subdirectories

and all of their files.



CommandLine = "dir """ & FileSpec & _

""" /s/b>""" & RedirectTo & """"

Shell Environ$("comspec") & " /c " & CommandLine, vbHide



Here, the output of a Dir command is redirected to a file-path you

specify in the RedirectTo (string variable). The /s/b are options to the

Dir command that tell it to recurse throught its subdirectories and not

to include header or summary information.



I used a variable for the file name so that I could more easily explain

the benefit of encasing it in quotemarks. If you redirect to a file that

has spaces in its name, or if there are spaces in the path specification

itself, then the filename *must* be quoted to protect the spaces from

DOS's desire to use them as delimiters. (That's what all those

quotemarks in the Shell statement are for.) If the filename doesn't have

spaces in it, the quotes aren't necessary BUT they don't hurt either.

Hence, the above will work with either.



As for your PING question, something like the following should work:



strIP = "4.17.23.1"

Shell Environ$("comspec") & " /c ping " & _

strIP & ">""" & RedirectFile & """", vbHide



Although you didn't specify it in your original post, I assume you want

to use vbHide for the optional 2nd parameter to Shell. This hides the

DOS window so that your user doesn't see it. If you want the DOS window

to remain visible, you would use the vbNormalFocus BUT you must use a /k

instead of a /c for the command processor argument. Basically, the /c

tells the command processor "here comes a command and, when its finished

executing, close the DOS shell it is running in" whereas the /k also

tells the command processor that a command follows, but it instructs it

to leave the DOS session running.



The above assumes you do NOT have to wait for this file to be completely

written before your code continues executing. If you have to work with

this file right after it is created, consider one of these (which makes

your program wait until the DOS process is finished):



MICROSOFT 'S OFFICIAL WAY

========================

See this link



support.microsoft.com/support/kb/articles/Q129/7/96.asp">support.microsoft.com/support/kb/articles/Q129/7/96.asp



Note: This method doesn't use Shell -- it uses CreateProcessA.





FAST AND DIRTY METHOD (WORKS ALMOST ALL THE TIME)

=================================================

Paste these lines in the (General)(Declarations) section of the form

where the Shell is being called (or remove the Private keywords and put

them in a BAS module if more than one form will use them):



Private Declare Function OpenProcess _

Lib "kernel32" _

(ByVal dwDesiredAccess As Long, _

ByVal bInheritHandle As Long, _

ByVal dwProcessId As Long) As Long

Private Declare Function CloseHandle _

Lib "kernel32" _

(ByVal hObject As Long) As Long

Private Declare Function WaitForSingleObject _

Lib "kernel32" _

(ByVal hHandle As Long, _

ByVal dwMilliseconds As Long) As Long



Call your Shell command in this form with the appropriate Shell

arguments placed in the parentheses:



PID = Shell( <<Put Shell Arguments Here>>)



And finally, paste the following IMMEDIATELY after the PID=Shell

statement above (making sure to handle the possible error where

indicated; i.e. stop the code from falling through to your other

commands if the Shell failed):



If PID = 0 Then

'

'Handle Error, Shell Didn't Work

'

Else

hProcess = OpenProcess(&H100000, True, PID)

WaitForSingleObject hProcess, -1

CloseHandle hProcess

End If











"Nathan Perkins" <NPerkins@maxmo.net>wrote in message

news:e7V7O7VWEHA.3476@tk2msftngp13.phx.gbl...

>I tried using

>

>shell "prog.exe>output.txt"

>

>, but no file was created. Is there something more to writing the

output to

>a file? I am pretty sure the output is written via stderr. Would I

have to

>change the line to make that work?

>

>I am not fully set on 9x systems, but it would be nice. What

difference

>exists there?

>

>"Bob Butler" <tiredofit@nospam.com>wrote in message

>news:eApdR4VWEHA.2288@TK2MSFTNGP10.phx.gbl...

>>"Nathan Perkins" <NPerkins@maxmo.net>wrote in message

>>news:OXhKLlVWEHA.3476@tk2msftngp13.phx.gbl

>>>I tried that, but I actually need the text returned, not just the

>>>exit code.

>>

>>the easiest way is usually to redirect the text to a file but it

depends

>>on

>>if the text is written to stdout or stderr and whether you need to

support

>>Win9x systems or not.

>>

>

>







-

Re:VB6 Shell Question

Nathan Perkins <NPerkins@maxmo.net>wrote:

Quote
That helps a lot, but I am still having some minor problems.



I have decided to just write my program for 2000 and XP, so I can redirect

stderr, but due to the complexity of my command, it doesn't execute.



My shell command essentially ends up as:



cmd.exe /c "C:\Software Projects\current\blah.exe" -x "C:\Documents and

Settings\Nathan Perkins\My Documents\some text file.txt">"C:\Software

Projects\current\output.tmp" 2>&1



In the end, a command window opens but that is it. I think that I need to

escape certain characters. Any idea?



What's that 2>&1 at the end of that string? Usually pipes, not redirects, are used

if there's that much going on.



Anyway, maybe what you want to do is perfect the command in an interactive session,

then have your application write a temporary batch file and shell to that?



Later... Karl

--

[Microsoft Basic: 1976-2001, RIP]





-