I've been pounding my head against my monitor all day on this one -
It defies any logical explanation - so hats off to anyone who can
solve this bugger.
I've gone through the huge number of posts on Deja, and so far none
have worked.
I'm trying to run a basic DOS redirection command from within VB 6.
I know that there's lots of difficulties supporting this command
within the language. I've tried several solutions which have not
worked:
- Use the Shell() function to directly execute the redirection command
- Create a Batch file containing the basic redirection operation:
DOS_Command.exe > textfile.txt
And when I execute this batch file from within VB using the Shell()
function, I see the DOS window appear, but nothing has been executed.
I can execute the batch file manually, and it works.
- Run the above batch file with:
cmd /c DOS_Command.exe > textfile.txt
- Run the above batch file with:
Call Shell (Environ$("comspec") & " /c " & DOS_Command.exe >
textfile.txt
(and also its batch-file equivalent)
- Create a C++ application which uses the WinExec() function to
execute the batch command, and call the C++ .exe from within my VB
application. The C++ application works great, and does exactly what
it's supposed to do. BUT, when called from within my VB program, I get
the quick flash of a DOS window, and nothing happens. I can run the
C++ application manually, and it works.
I've toyed with the CreateProcessA method suggested by the Micrsoft
support site.
So far, no luck.
Essentially what I'm trying to do is create a program which schedules
tasks on Windows NT/2000 using the AT command. (so it would be AT >
ATLIST.TXT)
I'm using Windows 2000 Pro, so that might be the source of the
problem.
I'm also using Visual Basic 6 Professional Edition, with Service Pack
5, in case that makes a difference.
I'm pretty much at my wits end here, so anything you folks can suggest
would be greatly appreciated.
-Gerry Mandering
burts_ta...@hotmail.com
Call Shell (Environ$("comspec") & " /c " & Chr$(34) & DOS_Command.exe >
textfile.txt & Chr$(34)
I think this is necessary because of the spaces involved in the
redirection you're doing.
Dag.
"Gerry Mandering" <burts_ta...@hotmail.com> wrote in message
news:eabcd59.01060...@posting.google.com...
Rick
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 so that you can then read it into your program):
MICROSOFT'S OFFICIAL WAY
========================
See this link
http://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
One note -- there are some NT systems (those with VERY tight security measures in place)
where this call won't work. No problem at all on 95/98 though.
Rick Rothstein
"Gerry Mandering" <burts_ta...@hotmail.com> wrote in message
news:eabcd59.01060...@posting.google.com...
-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----== Over 80,000 Newsgroups - 16 Different Servers! =-----
Try using Debug.Print to display exactly the same text you are Shelling and
look at it to be sure that is OK.
If you can run the batch file manually with the direction arrow OK, then try
setting the DOS.bat file properties to "close on Exit"
You can do this be selecting the .bat file with Windows explorer, right
clicking the .bat file. Then click properties and look for "Program", or
something similar, Click this and then look for "Close on Exit" and click this.
This will create a .pif file wilth the same name as the .bat file, usually in
in the Windows directory. This might fix your problem.
If you have an distributed App that uses this, distribute the .pif file with it
and put it in the Windows directory.
If this works, let us know.
True, but including it won't hurt. This (along with the parentheses I spoke about) will
allow you to make a single, more general subroutine for Shell purposes.
Rick
Rick
"Rick Rothstein" <rick_ne...@email.com> wrote in message
news:3b1ee950$1...@Newsfeeds.com...
Unfortunately, I wasn't able to get the shell function to work the
ways you folks suggested. Apparently it's a Windows 2000 issue - the
way VB handles Shell statements differs from Windows NT - since my app
worked using a basic shell statement in Win NT.
Does it sound plausible that the command.com structure is different?
My solution in the end was to create a C++ application which first
runs the redirection (using the system() function) and then starts my
VB application.
Not the best of all possible solutions, but the important thing is
that it works and I can move on to tackling the other problems
involved in creating a scheduling application.
Once again, I appreciate the time you all took to help out.
-Gerry Mandering