【问题标题】:reading a text file after executing a batch file through VBScript通过 VBScript 执行批处理文件后读取文本文件
【发布时间】:2013-11-14 01:06:02
【问题描述】:

我必须使用 run 执行一个批处理文件并在一个文本文件中获取输出并在该文件中搜索一个字符串,代码如下所示,

用于运行bat文件

 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

我发现运行后执行不会进入下一行,但是如果我在任务管理器中结束 cmd.exe 的进程,就会执行。

我已经提到过真正的等待过程完成,如下所示,

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

compile.bat 是如何执行的,compile.txt 是如何创建的,但读取过程没有发生。如果我从运行命令中删除“true”,则会收到“compile.txt 文件不存在”错误。

我不知道哪里出错了请帮帮我..

【问题讨论】:

  • 你有 "./compile.txt" 并且 Windows 使用反斜杠。这会影响它吗?
  • @foxidrive FileSystemObject 方法不区分 /\
  • @ansgarwiechers 感谢您的评论。我认为一些命令行工具因正斜杠而失败,我不确定 VBS 是做什么的。我确实注意到很多人在真正应该使用反斜杠的地方使用正斜杠。

标签: batch-file vbscript


【解决方案1】:

根据您的所有问题,我假设您的问题背后的故事 是这样的:

您的老板 D. Vader 先生要求您开发构建系统 他的 Java 应用程序。 “好吧”,你说,“让我们使用 Eclipse 和/或 Ant。” “不,”维德先生说,“我们将拥有一个带有 .BAT 的现代 BS 和一个 按钮 GUI”。

所以你建立了一个实验项目:

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

从一个最小的 Good.java 开始:

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

您已验证:

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

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

java Good
use Eclipse! <-- it works

对坏人采取同样的程序:

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

然后你编写了最小的 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>

和'代码背后'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

并验证 GUI 知道什么在哪里(并且自动绑定有效)。

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

为了让球滚动,您向 .hta 添加了一个按钮

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

还有一些 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

现在 GUI 显示两个 MessageBoxes 用于坏情况:

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

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

先生。维达不高兴:到处都是黑色的窗户,没有一个 .BAT! 您设置goWSH.CurrentDirectory 的巧妙技巧并不令人印象深刻 完全是他。

所以你写了 bgood.bat:

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

和相应的 bbad.bat。一些测试:

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

现在故事变成了科幻小说。你会听从我的建议 使用我的BTicks function 稍微修改以更好地处理目录并减去删除日志文件的错误。所以 util.vbs 看起来像

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

由于必须包含此文件,因此不需要“旧”按钮 现在,javacompile.hta 更改为

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

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")

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

现在不再有黑框,最后一个显示(用于 bbad.bat)显示 魔术字失败。

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

【讨论】:

    【解决方案2】:

    你能指定绝对路径吗?

    如果您为objFSO.OpenTextFile 使用true 参数,那么如果找不到文件,它将创建。我不明白为什么在你的情况下你会想要这样做,这可以解释为什么你没有“阅读”文件。如果你只是在某个地方创建它,它会是空的。

    如果您知道compile.bat 正在创建文本文件,下一步就是找出为什么OpenTextFile 没有找到它。如果你使用绝对路径,你可以快速解决这个问题。

    如果绝对路径不是一个选项,则使用MsgBox WScript.ScriptFullName 或其他东西来验证脚本运行的路径。

    您也可以这样做,这将使用脚本运行位置的相对路径
    strPath = Replace(WScript.ScriptFullName,WScript.ScriptName,"")
    objShell.Run ".\lib\Compile.bat" &amp; " &gt; " &amp; strPath &amp; "compile.txt", 0 ,True
    Set objReadFile = objFSO.OpenTextFile(strPath &amp; "compile.txt",1)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-04-12
      • 2015-05-12
      • 1970-01-01
      • 2012-08-07
      • 1970-01-01
      • 2013-10-05
      • 2012-02-27
      相关资源
      最近更新 更多