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!

BatchFile Output redirection > with Wscript.shell

Status
Not open for further replies.

stanlyn

Programmer
Sep 3, 2003
945
US
Hi,

I'm having an issue running a batch file from Wscript.shell that has a redirector ">" to a file within. The batch file works perfectly if run from Explorer by double clicking it or command line with cmd. When running it via a VFP program, it creates an empty file (0kb). Here is the batch file contents
Code:
whois.exe  -v  yahoo.com >C:\temp\output.txt

Using VFP's run command produces the same result.

Also, breaking the redirect parameter out of the .bat file and passing it as an external parameter also produces the same result.

The only way that I've been able to get a non-empty output.txt file is outside of VFP at the command line or Explorer.

Environment is Windows 10pro64 and VFP9sp2.

Any ideas?

Thanks, Stanley
 
Curious, I did this

Code:
	DECLARE INTEGER ShellExecute IN SHELL32.DLL ;
		INTEGER handle,;
		STRING @sFile,;
		STRING @lp,;
		STRING @DIR,;
		STRING @dir1,;
		INTEGER ncmd
SHELLEXECUTE(0, "open", "c:\$incoming\che.bat", "", "", 1)

Where che.bat contained:

Code:
whois -v yahoo.com > c:\$incoming\my.txt

and that worked fine on windows 10 - from the command box in VFP9

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
In general, I would always advise using ShellExecute() rather than the RUN command. So follow Griff's advice. But I'm not sure about the spurious MODIFY COMMAND in the first line of his code (was that intentional, Griff?).

This doesn't explain why your batch file is not working, but the advantage of ShellExecute() is that it returns a reply code which would indicate the reason for any possible error.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Thanks Mike, I cut and pasted straight from the command window and got a bit careless!

Regards

Griff
Keep [Smile]ing

There are 10 kinds of people in the world, those who understand binary and those who don't.

I'm trying to cut down on the use of shrieks (exclamation marks), I'm told they are !good for you.
 
One other point about ShellExecute():

You only have to do the DECLARE once, for example at the start of your program - not every time you call the function.

In fact, I do the DECLARE in the general start-up routine of all my applications. I use the function all the time, and that way I don't need to think about it.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Chris, I also suspected that this was a pathing issue. But I discarded that because the command is clearly running, as it is producing an output file, albeit an empty one.

That said, Stanley, are you sure that the command is producing a zero-length output file when run from with in VFP? If that file happens to be left over from some earlier attempts, that would explain the problem.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Mike,

if you don't have whois, like me, it still produces output by the > alone. That is whois errors, but has stderr and stdout output, the stderr goes to nirvana and the empty stdout gets to the file,.

After I installed whois from the download and did explicitly call it with full path I got output.

Chriss
 
For simplicity, try whois without any parameter from the command prompt.

I get
CMD said:
The command "whois" is either misspelled or could not be found.

That's a sure sign whois isn't a shell command, as stanlyn initially posted, it's a separate standalone exe. A console application.
I guess it worked on another computer that had this installed but now it's missing completely or the path to it isn't integrated in GETENV('PATH').

Chriss
 
That sounds plausible, Chris.

So, Stanley, if that's right, what you need to do is this:

Code:
[highlight #FCE94F]c:\mydir\[/highlight]whois.exe  -v  yahoo.com >C:\temp\output.txt

where c:\mydir is the directory where whois.exe is located.

And you should be able to do that directly from VFP, without the need for a batch file.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Or you set the path into PATH and windows will figure out where whois.exe is.

I think you could also put it into syswow64.

Anyway, I'd like to have it where your own EXE is and then know the path by sys(16,0) or configuration and use that. And then perhaps the ShellExecute has one more advantage, you can call it without displaying a shell window, when you let the last parameter be 0 (SW_HIDE) and whois.exe is complying with it.

Chriss
 
Hi,

I changed from this:
lcWhoIsStr = "whois.exe -v "+ Alltrim(lcDomainName) + " >C:\temp\output.txt"
to this:
lcWhoIsStr = "C:\Windows\System32\whois.exe -v "+ Alltrim(lcDomainName) + " >C:\temp\output.txt"
with same behavior...

Yes, whois.exe is from Sysinternals.

I do not think it is a pathing issue since everything works except for the redirection and that is actually working by creating a zero byte file. As Chris said, the > by itself may create the the empty file.

Also, to make sure that the record in scope gets clean data, I erase all the related files immediately before processing the current record by issuing:
Code:
Erase 'C:\temp\output.txt'
Erase 'c:\temp\getdomain.bat'

I am not using shellexec, instead I'm using wscript. I'll change it to shellexec and report back.

Reporting back...
Code:
lcDomainName = lcWord + '.' + lcTLD
lcWhoIsStr = "whois.exe -v "+ Alltrim(lcDomainName) + " > C:\temp\output.txt"
Strtofile(lcWhoIsStr, 'C:\temp\getdomain.bat')
SHELLEXECUTE(0, "open", "c:\temp\getdomain.bat", "", "", 1)

also produces a zero byte file and errors with "File access is denied c:\temp\getdomain.bat" on the line: "Erase 'c:\temp\getdomain.bat'" after processing 18 records. Probably a data issue and not worried about that. The .bat file looks like this...

Code:
whois.exe -v a_c.com > C:\temp\output.txt

Issuing:

Code:
C:\Windows\System32\whois.exe -v 10th.com > C:\temp\output.txt
causes the "File access" error after processing 0 records.

Running the .bat file from the os works as expected, otherwise I get a zero length file as output.

Thanks, Stanley

 
Hi again,

Running

Code:
"c:\temp\getdomain.bat"

from VFP's command also creates a zero size file...

The .bat file contains...

Code:
C:\Windows\System32\whois.exe -v 10th.com > C:\temp\output.txt

Thanks, Stanley
 
Hi all,

Looks like a pathing issue after all related to the .exe file. I moved it to within the project's app subfolder and is now working.

I still believe there is an issue because I hardcoded the path to the "C:\Windows\System32\whois.exe" (see above) and it was failing. The exe file is there. The batch file that now works looks like this...

Code:
C:\Users\SlaAdmin\Desktop\DomStatus\Apps\whois.exe -v $100-a-plate_dinner.com > C:\temp\output.txt

Thanks, Stanley
 
VFP works with 32bit and those files are in SysWow64, not System32.

You can also call/run a 64bit exe, though, but I doubt the whois.exe really is in System32. If you use VFP to write into System32 the writes will succeed, but will write redirected to Syswow64. Same for 32bit cmd.exe you start with RUN or 32bit Windows API ShellExecute.

So yes, moving that into your own directory is the way to go.

myself said:
I think you could also put it into syswow64.
Just for completeness, yes that works. Then you can RUN whois without path, Windows (cmd.exe) will look for whois.exe in syswow64.

Chriss
 
Hi Chris,

I would expect the command to run in the system32 folder or anywhere else since it was hardcoded to look there and it actually being there.

You know of any way to output the external command's response into a variable instead of a file to eliminate a lot of the i/o?

Thanks again,
Stanley
 
Again, there is redirection, any 32bit process accessing system32 is redirected to syswow64. That even includes 32bit installers, which actually were the case for which this redirection was implemented. They should continue to work but put 32bit applications into SysWow64.

Another demonstration, also for Mike: Run hishhhyiso >output.txt will create an empty output, too.

To get to your last question. Well, you would need to capture stdout of a console application, that needs more control over the process than you get with RUN and ShellExecute.

The easy way is
Code:
oWScript = CreateObject('Wscript.Shell')
oWhoisProcess = oWScript.Exec('whois -v google.com')
? oWhoisProcess.Stdout.ReadAll()

Well, or instead of ? assign it to a string variable, of course.

Edit: Isn't it in your title, already? Using Wscript.Shell means doing that, not running a bat/cmd file.

Chriss
 
Hi Chriss,

I've changed my routine to use your stdout solution and the exec command as you wrote out. I need to suppress the dos window as it takes focus from everything else as it runs.

If I use the run command, how would I get the output into a var. Run allows black dialog suppression and waiting. I do not see a suppression parameter for the exec.

Also important is the need for the command to wait until the run or exec finishes. The exec as you wrote is doing that nicely, if I can get rid of the black box, I would consider it done.

Thanks,
Stanley
 
Stanley,

You asked how to get the result into a variable rather than a text file. One option would be to add a line of code in your VFP program, immediately after executing the batch file, using FILETOSTR()to copy the output file to the variable.

To allow time for the WHOIS to execute, you would probably need to pause execution for a few hundred milliseconds between calling the batch file and doing the FILETOSTR(). One way to do that would be to use the Sleep() function:
Code:
DECLARE Sleep IN WIN32API INTEGER iPeriod
  && do this once, at the start of your app

 ....

Sleep(500)
  && pause for the specified number of millisecs

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Hi Mike,

Using Chriss's code above, I have gotten it to bypass the whole writing to a file, filetostr() and strtofile() methods as they are too costly in i/o. The only improvement I need now is ridding the black dos window. His method is also waiting for the command to complete which is necessary as whois against many domains can take a long time. So far I have seen as high as 20-30 seconds, while average is about 1-2 seconds.

Thanks,
Stanley
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top