如何使用批处理命令"其中"并从VBScript设置变量?

时间:2014-12-28 13:41:11

标签: batch-file vbscript command

我使用批处理在每个客户端本地执行robocopy命令,同步文件夹,然后启动一个具有自己模式的批处理的应用程序。

我的下一个项目是在VBScript中转换此批处理,直接从远程共享文件夹中使用它,而不是将批处理存储在每个客户端中。

即使我不是一个优秀的VBScript程序员,关于指标,我几乎已经设定,但我仍然坚持将where命令移植到VBScript。

在我的批处理文件中,我执行以下命令:

FOR /F "tokens=* USEBACKQ" %%F IN (`where /R C:\appfolder startapp.bat /F`) DO (
  SET strAPP=%%F
)

C:\appfolder中,每个客户端都安装了一个软件,由于某些原因,可能会以错误和不同的模式安装,因此公共startapp.bat可能在每个客户端中具有不同的模式。出于这个原因,上面的FOR实例帮助我创建了一个名为%strapp%的变量,该变量稍后在批处理中用于启动应用程序。

现在,我的VBScript正在使用确切的模式,但没有这个"其中命令预防",我希望具有与批处理相同的功能,只是为了防止将来客户端可能有再次以非常见模式安装错误。

e.g。在VBS中使用strmsg菜单,当用户从其客户端选择正确的选项时,VBScript启动应用程序:

objShell.Run("%comspec% /K C:\appfolder\startapp.bat & exit"), 1, True

strFlag = True

它有效,我尝试添加旧where命令并设置变量add&在每个连接命令中,所有这些都在一行中没有运气....

e.g。

objShell.Run("%comspec% /K FOR /F "tokens=* USEBACKQ" %%F IN (`where /R C:\appfolder startapp.bat /F`) DO (SET strAPP=%%F) & %strapp% & exit"), 1, True

strFlag = True

我尝试使用双引号""没有运气。

2 个答案:

答案 0 :(得分:1)

where的VBScript实现可能如下所示:

Function Where(fldr, filename)
  For Each f In fldr.Files
    If LCase(f.Name) = LCase(filename) Then
      Where = f.Path
      Exit Function
    End If
  Next

  For Each sf In fldr.SubFolders
    Where = Where(sf, filename)
    If Not IsEmpty(Where) Then Exit Function
  Next
End Function

该函数将被调用如下:

Set fso = CreateObject("Scripting.FileSystemObject")

strAPP = Where(fso.GetFolder("C:\appfolder"), "startapp.bat")

Set objShell = CreateObject("WScript.Shell")
objShell.Run "%comspec% /c """ & strAPP & """", 1, True

作为旁注,无论如何,当您要退出时,使用选项CMD(保持窗口)启动/k实例毫无意义。使用选项/c(关闭窗口)启动它,然后删除exit语句。

根据Ansgar建议,添加方法参数0,隐藏CMD窗口

objShell.Run "%comspec% /c """ & strAPP & """", 0, True

答案 1 :(得分:0)

发现了一些错误:

  • 展开%comspec% ...没有必要(感谢Ansgar Wiechers的评论),这只是我对VBScript中使用的环境变量毫无根据和过度怀疑的一个方面... Paranoia 我认为是正确的术语:)
  • 内部"引号应加倍
  • 参数名称来自命令行%F;仅批量加倍%百分号(%%F
  • /V:ON启用延迟环境变量扩展使用!作为分隔符。例如,/ V:ON将允许!var!在执行时扩展变量var。 %var%语法在输入(解析)时扩展变量,这在FOR循环内部以及在&连接命令行中时非常不同
  • usebackq:在(`where ...`)中错过了引号...
  • !&echo !strapp!&pause之前添加&exit。这样你就可以在调试时看到结果......

忘了什么?但是,所有VBScript如下:

option explicit
Dim strResult: strResult=Wscript.ScriptName

Dim WshShell: Set WshShell = WScript.CreateObject("WScript.Shell")
Dim cmd, retrn, params
cmd = WshShell.ExpandEnvironmentStrings("%comspec%") 
params = " /E:ON /V:ON /K FOR /F ""USEBACKQ tokens=*"" %F IN (`where /R C:\appfolder startapp.bat /F`) DO (SET strAPP=%F)&!strapp!&echo !strapp!&pause&exit"
retrn = WshShell.Run(cmd & params, 1, true)

strResult = strResult & vbNewline & cmd
strResult = strResult & vbNewline & params
strResult = strResult & vbNewline & retrn

Wscript.Echo strResult
Wscript.Quit

@JosefZ

感谢您的回答,即使我喜欢Ansgar解决方案,我也让您工作,我想在此发布,以防万一对某人有用。 最后,使用where命令修改的工作VBscript(对我而言)就是这个:

option explicit
Dim strResult: strResult=Wscript.ScriptName

Dim WshShell: Set WshShell = WScript.CreateObject("WScript.Shell")
Dim cmd, retrn, params
cmd = WshShell.ExpandEnvironmentStrings("%comspec% /C") 
params = "FOR /F ""tokens=* USEBACKQ"" %F IN (`where /R C:\appfolder startapp.bat /F`) DO (SET strAPP=%F) & cmd /C %strapp%"
retrn = WshShell.Run(cmd & params, 1, true)
Wscript.Quit