0

I have to execute a batch file using run and get the output in a text file and search that file for a string the code snippet as below,

For running the bat file

 Set objShell = WScript.CreateObject("WScript.Shell")
 MsgBox("Compiling Source files..Please wait..")
 objShell.Run CHR(34) & ".\lib\Compile.bat" & CHR(34) & " > compile.txt" & CHR(34), 0 ,True

I found out that the execution is not going to the next line after run, but if i end process of cmd.exe in task manager the execution happens.

I have mentioned true to wait for the process to get complete after this am reading like below,

Dim objFSO, strLine, objReadFile
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objReadFile = objFSO.OpenTextFile("./compile.txt", 1 , true)
Do Until objReadFile.AtEndOfStream
strLine = objReadFile.ReadLine
    ....
    ....

How ever the compile.bat is executing and compile.txt is getting created but the reading process doesn't happen. If i remove the "true" from run command am getting "compile.txt file doesn't exist" error.

I don't know where am making mistake please help me with it..

user2572985
  • 75
  • 1
  • 2
  • 8
  • You have `"./compile.txt"` and Windows uses backslashes. Does this affect it? – foxidrive Nov 13 '13 at 07:00
  • @foxidrive `FileSystemObject` methods don't distinguish between `/` and ``\``. – Ansgar Wiechers Nov 13 '13 at 12:59
  • @ansgarwiechers Thanks for that comment. I think some command line tools fail with forward slashes, and I wasn't sure what VBS does. I do notice many people using forward slashes where backslashes should really be used. – foxidrive Nov 13 '13 at 13:48

2 Answers2

1

From all your questions I assume the the story behind your problem goes something like this:

Your boss, Mr. D. Vader, asked you to develop the build system for his Java application. "Ok", you said, "let's use Eclipse and/or Ant." "No", said Mr. Vader, "we will have a modern BS with .BATs and one button GUIs".

So you set up an experimental project:

tree /a /f .
E:\TRIALS\SOTRIALS\ANSWERS\19944721
|
+---vbs
|   |   javacompile.hta
|   |   javacompile.vbs
|
\---java
    +---good
    |       Good.java
    |
    \---bad
            Bad.java

Starting with a minimal Good.java:

class Good {
  public static void main(String[] args) {
    System.out.println("use Eclipse!");
  }
}

you verified:

javac Good.java
- no news are good news --

echo %ERRORLEVEL%
0 <-- javac may set ERRORLEVEL

java Good
use Eclipse! <-- it works

Same procedure for the bad:

class Bad {
  public static void main(String[] args) {
    System.out.println("D. Vader says: 'Use .bat and one button GUI!'.");
  }

javac Bad.java
Bad.java:4: reached end of file while parsing
  }
   ^     <-- javac finds the missing }
1 error

echo %ERRORLEVEL%
1 <-- javac really sets ERRORLEVEL

Then you wrote the minimal GUI: javacompile.hta

<html>
 <head>
  <Title>JavaCompile</Title>
  <hta:application id="javacompile" scroll = "no">
  <script type="text/vbscript" src="javacompile.vbs"></script>
 </head>
 <body>
  <form>
   <input type="button" id="bttCheckBasics" value="Check Basics"/>
  <form>
 </body>
</html>

and the 'code behind' javacompile.vbs

Option Explicit

Dim goFS    : Set goFS = CreateObject("Scripting.FileSystemObject")

' document.location: "file:///E:/trials/SoTrials/answers/19944721/vbs/javacompile.hta"
Dim gsVbsF  : gsVbsF  = Replace(goFS.GetParentFolderName(Mid(document.location, 9)), "/", "\")
Dim gsJavaF : gsJavaF = goFS.GetAbsolutePathName(goFS.BuildPath(gsVbsF, "..\java"))
Dim gsGoodF : gsGoodF = goFS.BuildPath(gsJavaF, "good")
Dim gsBadF  : gsBadF  = goFS.BuildPath(gsJavaF, "bad")

Sub bttCheckBasics_onclick()
  MsgBox "Sub bttCheckBasics_onclick() was called."
  MsgBox Join(Array("Known Folders:", gsVbsF, gsJavaF, gsGoodF, gsBadF), vbCrLf)
End Sub

and verified that the GUI knows where is what (and the auto-binding works).

(Copy from MessageBox)
Known Folders:
E:\trials\SoTrials\answers\19944721\vbs
E:\trials\SoTrials\answers\19944721\java
E:\trials\SoTrials\answers\19944721\java\good
E:\trials\SoTrials\answers\19944721\java\bad
---------------------------
OK
---------------------------

To get the ball rolling, you added a button to the .hta

   <br/>
   <input type="button" id="bttKiss" value="Keep It Simple, Stupid"/>

and some code to the vbs:

Sub bttKiss_onclick()
  MsgBox "Sub bttKiss_onclick() was called."
  KissCompile gsGoodF, "Good.java", "bgood.bat"
  KissCompile gsBadF, "Bad.java", "bbat.bat"
End Sub

Sub KissCompile( sF, sJava, sBat)
  goWSH.CurrentDirectory = sF
  Dim sCmd  : sCmd      = Join(Array("javac", sJava))
  Dim oExec : Set oExec = goWSH.Exec(sCmd)
  Do Until cnWshFinished = oExec.Status : Loop
  MsgBox Join(Array(qq(sCmd), "(javac) ExitCode:", oExec.ExitCode))
  If 0 <> oExec.ExitCode Then MsgBox oExec.StdErr.ReadAll(), vbAbortRetryIgnore, "You messed it up, Mr. Vader!"
End Sub

Function qq(s)
  qq = """" & s & """"
End Function

Now the GUI shows for two MessageBoxes for the bad case:

---------------------------
"javac Bad.java" (javac) ExitCode: 1
---------------------------
OK
---------------------------

---------------------------
You messed it up, Mr. Vader!
---------------------------
Bad.java:4: reached end of file while parsing
  }
   ^
1 error
---------------------------

Mr. Vader is not amused: Black windows all over the place and not a single .BAT! Your ingenious trick of setting goWSH.CurrentDirectory does not impress him at all.

So you wrote bgood.bat:

@echo off
javac Good.java
IF ERRORLEVEL 1 GOTO :bingo
echo SUCCESS
GOTO :end
:bingo
echo FAILURE
:end

and a corresponding bbad.bat. Some tests:

bbad
Bad.java:4: reached end of file while parsing
  }
   ^
1 error
FAILURE
JAVA E:\trials\SoTrials\answers\19944721\java\bad
echo %ERRORLEVEL%
1

Now the story changes to science fiction. You will follow my advice to use my BTicks function slightly modified for a better handling of directories and minus a bug wrt to the deletion of log files. So util.vbs looks like

Option Explicit

Const cnWshRunning       =  0 ' The job is still running.
Const cnWshFinished      =  1 ' The job has completed.
Const SW_SHOWMINNOACTIVE =  7
Const ForReading         =  1

Function qq(s)
  qq = """" & s & """"
End Function

' BTicks - execute sCmd via WSH.Run
'  aRet( 0 ) : goWSH.Run() result
'  aRet( 1 ) : StdErr / error message
'  aRet( 2 ) : StdOut
'  aRet( 3 ) : command to run
Function BTicks(sExecF, sLogF, sCmd )
  goWSH.CurrentDirectory = sExecF
  Dim aRet    : aRet     = Array(-1, "", "", "")
  Dim sFSpec1 : sFSpec1  = goFS.BuildPath(sLogF, goFS.GetTempName() )
  Dim sFSpec2 : sFSpec2  = goFS.BuildPath(sLogF, goFS.GetTempName() )

  aRet(3) = Join(Array( _
       qq("%comspec%") _
     , "/c" _
     , qq(Join(Array( _
            sCmd _
          , "1>" & qq(sFSpec1) _
          , "2>" & qq(sFSpec2) _
  )))))
  Dim aErr
 On Error Resume Next
  aRet(0) = goWSH.Run(aRet( 3 ), SW_SHOWMINNOACTIVE, True)
  aErr    = Array(Err.Number, Err.Description, Err.Source)
 On Error GoTo 0
  If 0 <> aErr(0) Then
     aRet(0) = aErr(0)
     aRet(1) = Join(Array(aErr(1), aErr(2), "(BTicks)"), vbCrLf)
     BTicks  = aRet
     Exit Function
  End If

  Dim nIdx : nIdx = 1
  Dim sFSpec
  For Each sFSpec In Array(sFSpec2, sFSpec1)
      If goFS.FileExists(sFSpec) Then
         Dim oFile : Set oFile = goFS.GetFile(sFSpec)
         If 0 < oFile.Size Then
            aRet(nIdx) = oFile.OpenAsTextStream(ForReading).ReadAll()
         End If
         oFile.Delete
      End If
      nIdx = nIdx + 1
  Next
  BTicks = aRet
End Function

As this file has to be included and the 'old' buttons aren't needed anymore, javacompile.hta changes to

<html>
 <head>
  <Title>JavaCompile</Title>
  <hta:application id="javacompile" scroll = "no">
  <script type="text/vbscript" src="javacompile.vbs"></script>
  <script type="text/vbscript" src="util.vbs"></script>
 </head>
 <body>
  <form>
   <input type="button" id="bttBTicks" value="Use BTicks, Stupid"/>
  <form>
 </body>
</html>

and javacompile.vbs gets shorter too:

Option Explicit

Dim goFS    : Set goFS = CreateObject("Scripting.FileSystemObject")

' document.location: "file:///E:/trials/SoTrials/answers/19944721/vbs/javacompile.hta"
Dim gsVbsF  : gsVbsF  = Replace(goFS.GetParentFolderName(Mid(document.location, 9)), "/", "\")
Dim gsJavaF : gsJavaF = goFS.GetAbsolutePathName(goFS.BuildPath(gsVbsF, "..\java"))
Dim gsGoodF : gsGoodF = goFS.BuildPath(gsJavaF, "good")
Dim gsBadF  : gsBadF  = goFS.BuildPath(gsJavaF, "bad")

Dim goWSH : Set goWSH = CreateObject( "WScript.Shell" )

Sub bttBTicks_onclick()
  MsgBox "Sub bttUseBTicks_onclick() was called."
  Dim aRet
  aRet = BTicksCompile(gsGoodF, "javac Good.java")
  aRet = BTicksCompile(gsGoodF, "bgood.bat")
  aRet = BTicksCompile(gsBadF , "javac Bad.java")
  aRet = BTicksCompile(gsBadF , "bbad.bat")
End Sub

Function BTicksCompile(sF, sCmd)
  BTicksCompile = BTicks(sF, gsVbsF, sCmd)
  MsgBox Join(BTicksCompile, vbCrLf & "--------" & vbCrLf)
End Function

Now there are no more black boxes and the last display (for bbad.bat) shows the magic word FAILURE.

---------------------------
0
--------
Bad.java:4: reached end of file while parsing
  }
   ^
1 error
--------
FAILURE
--------
"%comspec%" /c "bbad.bat 1>"E:\trials\SoTrials\answers\19944721\vbs\rad6CE21.tmp" 2>"E:\trials\SoTrials\answers\19944721\vbs\radC7CE6.tmp""
---------------------------
OK   
---------------------------
Community
  • 1
  • 1
Ekkehard.Horner
  • 38,498
  • 2
  • 45
  • 96
0

Can you specify absolute paths?

If you use the true argument for objFSO.OpenTextFile then it will create the file if it's not found. I can't see why in your case you would want to do that, and this would explain why you are not "reading" the file. If you just created it somewhere, it would be empty.

If you know compile.bat is creating the text file, the next step is to figure out why OpenTextFile isn't finding it. If you use absolute paths, you can quickly resolve this.

If absolute paths are not an option, then use a MsgBox WScript.ScriptFullName or something to verify the path from where the script is running.

You might also do something like this, which would use the relative path of the script's running location
strPath = Replace(WScript.ScriptFullName,WScript.ScriptName,"")
objShell.Run ".\lib\Compile.bat" & " > " & strPath & "compile.txt", 0 ,True
Set objReadFile = objFSO.OpenTextFile(strPath & "compile.txt",1)

langstrom
  • 1,652
  • 11
  • 14