VBScript - 将 schtasks 命令传递给 运行 方法

VBScript - Passing schtasks command into run method

以下 .vbs 创建所需的任务没有任何问题(请原谅语法):

Option Explicit

Dim wshell
Set wshell = CreateObject("WScript.Shell")
wshell.Run "schtasks /create /sc once /tn ""Reminder"" /tr ""C:\Windows\System32\cmd.exe \""/c title Alert & mode con: cols=40 lines=10 & color f0 & cls & echo *** Message goes here *** & echo. & echo. & echo. & echo. & echo. & echo. & echo. & echo Press any key to exit & pause > nul\"""" /st 18:00 /sd 08/20/2016 /f"

但是,如果我尝试通过变量传递 schtasks 命令字符串,如下所示:

Option explicit
dim strdate, strtime, strmessage, strtask, wshell

strdate = "08/20/2016"
strtime = "18:30"
strmessage = "Turn off pump"

WScript.Echo strdate
WScript.Echo strtime
WScript.Echo strmessage

strtask = """schtasks /create /sc once /tn """"Reminder"""" /tr """"C:\Windows\System32\cmd.exe \""""/c title Alert & mode con: cols=40 lines=10 & color f0 & cls & echo " & strmessage & " & echo. & echo. & echo. & echo. & echo. & echo. & echo. & echo Press any key to exit & pause > nul"""""""" /st " & strtime & " /sd " & strdate & " /f""" & " ,0" & " ,true"

WScript.Echo strtask

Set wshell = CreateObject("WScript.Shell")
wshell.Run strtask

我收到以下错误:

我不明白为什么我会得到这个,毕竟被解析的变量与之前的代码片段(包括引号)相同...有人可以向我解释我缺少的内容?

编辑

感谢 Ansgar Wiechers 的指导。我已经通过删除 运行 命令选项并从本质上检查外部命令错误来设法获得一个有效但不优雅的脚本。见下文:

option explicit
dim strdate, strtime, strmessage, strtask, exitcode, wshell

strdate = "08/21/2016"
strtime = "13:45"
strmessage = "Turn off pump"

WScript.Echo strdate
WScript.Echo strtime
WScript.Echo strmessage

strtask = "schtasks /create /sc once /tn ""Reminder"" /tr ""C:\Windows\System32\cmd.exe \""/c title Alert & mode con: cols=40 lines=10 & color f0 & cls & echo " & strmessage & " & echo. & echo. & echo. & echo. & echo. & echo. & echo. & echo Press any key to exit & pause > nul\"""" /st " & strtime & " /sd " & strdate & " /f"

set wshell = CreateObject("WScript.Shell")
exitcode = wshell.Run(strtask, 0, True)
if exitcode <> 0 
then WScript.Echo "External command failed: " & Hex(exitcode)
End If

我严重怀疑您的原始命令是否有效。 CMD.exe 参数列表周围的嵌套引号应该总是会引发错误。删除那些嵌套的引号(只保留整个 CMD 语句周围的双引号)并从 strTask 中删除 Run 方法的参数,任务创建应该会按预期工作。

strtask = "schtasks /create /sc once /tn ""Reminder""" & _
          " /tr ""C:\Windows\System32\cmd.exe /c title Alert" & _
          " & mode con: cols=40 lines=10 & color f0 & cls" & _
          " & echo " & strmessage & _
          " & echo. & echo. & echo. & echo. & echo. & echo. & echo." & _
          " & echo Press any key to exit & pause > nul""" & _
          " /sd " & strdate & " /st " & strtime & " /f"

exitcode = wshell.Run(strtask, 0, True)

If exitcode <> 0 Then
  WScript.Echo "External command failed: " & Hex(exitcode)
End If

添加一些代码来检查外部命令的退出状态总是一个好主意,这样您就可以检测到是否出了问题。

话虽如此,您可以通过一些修改大大提高此代码的可维护性:

  • 不要将命令行创建为一个大字符串。从内到外构建它。
  • 尽可能使用环境变量(例如 %COMSPEC% 而不是 CMD.exe 的文字路径)
  • 只在需要的地方使用引号。
  • 使用引用函数添加转义双引号。
Function qq(str)
  qq = """" & str & """"
End Function

cmdargs = "/c title Alert & mode con: cols=40 lines=10 & color f0 & cls" & _
          " & echo " & strmessage & " & echo. & echo. & echo. & echo." & _
          " & echo. & echo. & echo. & echo Press any key to exit & pause > nul"
strtask = "schtasks /create /f /sc once /tn Reminder" & _
          " /tr " & qq("%COMSPEC% " & cmdargs) & _
          " /sd " & strdate & " /st " & strtime

exitcode = wshell.Run(strtask, 0, True)

更好的是,将批处理代码放入实际的批处理文件中:

@echo off
title Alert
mode con: cols=40 lines=10
color f0
cls
echo %~1
echo.
echo.
echo.
echo.
echo.
echo.
echo.
echo Press any key to exit
pause > nul

并创建 运行 包含您的消息的批处理文件的任务:

Function qq(str)
  qq = """" & Replace(str, """", "\""") & """"
End Function

batchfile = "C:\path\to\your.bat"
strtask   = "schtasks /create /f /sc once /tn Reminder" & _
            " /tr " & qq(qq(batchfile) & " " & qq(strmessage)) & _
            " /sd " & strdate & " /st " & strtime

exitcode = wshell.Run(strtask, 0, True)