来自批处理脚本的非模态通知框

Posted

技术标签:

【中文标题】来自批处理脚本的非模态通知框【英文标题】:Non-Modal Notification Box from batch script 【发布时间】:2009-04-16 15:47:09 【问题描述】:

我想要一个名为批处理文件的非模态警报框。目前我正在使用 vbscript 创建一个模态警报框:

>usermessage.vbs ECHO WScript.Echo^( "Generating report - this may take a moment." ^)
WSCRIPT.EXE usermessage.vbs

但我想在不等待用户交互的情况下继续执行脚本(生成报告)。我怎样才能做到这一点?我不在乎它是否是 vbscript - 我只想让它在我的批处理脚本中工作(在 Windows XP 中)。

【问题讨论】:

【参考方案1】:

对当前技巧没有新要求的简单答案是使用start 命令将脚本与批处理文件执行分离。

这可能看起来像:

>usermessage.vbs ECHO WScript.Echo^("生成报告 - 这可能需要一点时间。" ^) 启动 WSCRIPT.EXE usermessage.vbs echo 这段文字代表了写报告的辛勤工作

唯一的区别是使用start 运行wscript。这确实存在缺陷,即它会在当前目录中留下一个临时文件,并且最终需要手动关闭该框。

这两个问题都很容易处理:

@echo 关闭 设置本地 设置 msg="%TMP%\tempmsg.vbs" ECHO WScript.Echo^("正在生成报告 - 这可能需要一点时间。" ^) >%msg% 启动 WSCRIPT.EXE /I /T:15 %msg% echo 这段文字代表了写报告的辛勤工作 ping -n 5 127.0.0.1 >NULL 删除 %msg% >NUL 2>&1

在这里,我将临时脚本移至%TMP% 文件夹,并记住在完成后将其删除。我使用了echoping 命令来浪费一些时间来演示长时间的进程运行。而且,我使用wscript/I/T 选项来确保脚本以“交互方式”运行并设置允许脚本运行的最长时间。

@echo offsetlocal 使它在命令提示符下运行时看起来更干净,并防止它在提示符环境中留下名称 `%msg%。

编辑: Johannes Rössel 在 cmets 中对 setlocal 的批评是不正确的。如果这是在命令提示符下调用的,没有setlocal,变量 msg 将对提示符以及从该提示符启动的其他批处理文件和程序可见。如果您实际上编写的不仅仅是一次性脚本,最好使用setlocal 隔离批处理文件中的局部变量。

这很容易证明:

C:> 输入 seta.bat @set A=SomeValue C:>设置A ALLUSERSPROFILE=C:\Documents and Settings\所有用户 APPDATA=C:\Documents and Settings\Ross\Application Data C:> seta.bat C:>设置A A=某个值 ALLUSERSPROFILE=C:\Documents and Settings\所有用户 APPDATA=C:\Documents and Settings\Ross\Application Data C:>

【讨论】:

抱歉,您假设 cmd.exe 太像 *nix shell。在命令提示符处调用的每个批处理文件都由该 cmd.exe 的副本解释,并且确实可以更改其他命令的环境。这就是添加 setlocal 的原因。但是,如果从资源管理器调用批处理文件,则您是正确的。从 DOS 1.0 和 COMMAND.COM 开始就是如此,至少在 XP 中仍然如此。【参考方案2】:

我在同样的问题上苦苦挣扎,我有一个 VBScript 需要弹出一个消息框,但不能停止并继续。我想在一段时间后关闭。这对我有用。本质上,一个 vbscript 创建另一个 vbscript 文件,然后使用 shellexecute 执行该消息框文件,超时时间为 15 秒。

Set wshShell = CreateObject( "WScript.Shell" )
tmpPath = wshShell.ExpandEnvironmentStrings( "%TMP%" )
set wshShell = Nothing

msgFile = tmpPath & "\tempmsg.vbs"
Set fs = CreateObject("Scripting.FileSystemObject")
Set objFile = fs.CreateTextFile(msgFile,True)
objFile.Write "MsgBox " & chr(34) & "It worked!" & chr(34) & vbCrLf
objFile.Close
Set fs = Nothing

dim objShell
set objShell = CreateObject("shell.application")
objShell.ShellExecute "cscript.exe", "/I /T:15 " & (char34) & msgFile & chr(34), "", "open", 0
set objShell = Nothing

【讨论】:

以上是关于来自批处理脚本的非模态通知框的主要内容,如果未能解决你的问题,请参考以下文章

如何在 linux 中显示来自 bash 脚本的 GUI 消息框?

记录工作用到的一个简单js脚本

模态窗口和控件显示前后

如何接收和处理 Chrome 通知/推送通知?

选择特定网络打印机时显示消息框的批处理脚本

来自 CLI 的 scala/spark 脚本