从Windows批处理文件中显示弹出窗口/消息框

169

有没有一种方法可以从批处理文件中显示消息框(类似于Linux中可以从bash脚本中使用xmessage的方式)?


CMD.EXE是一个32位命令处理器,支持DOS命令。 - Alan B
7
它被称为Windows命令提示符。 - Ricardo Polo Jaramillo
23个回答

154

首先,DOS与此无关,您可能想要一个Windows命令行解决方案(再次强调:不是DOS,纯粹的Windows,只是不是窗口,而是控制台)。

您可以使用boflynn提供的VBScript方法,也可以误用net sendmsgnet send仅适用于较旧版本的Windows:

net send localhost Some message to display

这也取决于 Messenger 服务的运行状态。

对于更新版本(似乎是 XP 及以上):

msg "%username%" Some message to display

需要注意的是,使用 msg.exe 发送的消息框只会持续60秒。但可以使用 /time:xx 开关来覆盖这一设置。


2
您可以使用环境变量来获取本地用户 - %USERNAME%。msg.exe 在我的XP Home机器上,但我听说它不在每个版本的Vista上。我相信NET SEND背后的服务现在已被禁用。 - McDowell
20
我认为答案中缺少一个可行的选项,所以我提出了它。这里没有任何问题。你不需要感到强迫去做什么,我也不是在说boflynn错了。我只是添加了另一个选项,这应该对那些没有单一确定答案的问题非常合适。此外,你可能不是唯一一个有这个问题的人,其他人可能因为各种原因不想使用VBScript。这是一个社区网站,不仅仅属于你 :-) - Joey
9
我自己只是利用这个在远程shell上生成一个“我爱你”的信息,发送到我女友的电脑上。 - Camilo Martin
出于某种原因,这在命令提示符中对我有效;但是在Visual Studio的后期构建事件中对我无效。 - Andrej Adamenko
1
在Windows 8和10上,我发现Windows的版本很重要。对我来说,它可以在专业版上运行,但家庭版不行。其他人报告说它可以在家庭高级版、企业版、旗舰版等上运行。似乎普通的家庭版不支持它(它不存在于System32中,但可以添加)。 - shox
显示剩余9条评论

131

我会创建一个非常简单的VBScript文件,并使用CScript调用它来解析命令行参数。

类似以下内容保存在MessageBox.vbs中:

Set objArgs = WScript.Arguments
messageText = objArgs(0)
MsgBox messageText

你会这样调用它:

cscript MessageBox.vbs "This will be shown in a popup."

如果您想采用这种方式,MsgBox 参考文档或许会对您有所帮助。


谢谢,这就可以了。我会创建一个文件,将数据写入其中,然后使用它,最后删除它。应该可以正常工作 :) - billyy
1
很棒的答案。这样你就可以完全控制图标、按钮和框标题。而且当你将文件保存在路径中的某个位置时,可以从任何位置调用它。我创建了几个带有不同图标的警报文件。 - Deus777
不错。顺便说一下,在Win10中你不需要使用CScript。使用CScript会在命令提示符中得到一些额外的文本。没有CScript,只有警报,这非常好。 - A Child of God
我没有cscript。我使用了start代替。 - sureshvv
有没有无需文件的方法来实现这个?也就是说,你能直接将原始VBScript传递给cscript吗? - Dan Henderson

86

可能会有点闪烁,但不需要临时文件。应该可以在回到(IIRC) IE5时代的某个地方正常工作。

mshta javascript:alert("Message\n\nMultiple\nLines\ntoo!");close();

如果你使用if命令,请务必转义括号

if 1 == 1 (
   mshta javascript:alert^("1 is equal to 1, amazing."^);close^(^);
)

这个命令在命令提示符下运行得非常完美,但是当我把它放到批处理文件中时,就会出现这个错误:close() was unexpected at this time - eye_mew
@eye_mew 也许你需要在批处理文件中删除那些 ^ 转义字符。 - phuclv
1
这对我来说在批处理文件中工作得非常完美(我使用的是Windows 7)。我们能以这种方式运行任何Javascript吗?我们如何将值返回给批处理文件? - Jerry Jeremiah
1
以下是一些令人惊叹的事情的示例:http://www.dostips.com/forum/viewtopic.php?t=5311 LocalDateTime示例返回一个值。感谢您提供的想法! - Jerry Jeremiah
微软在服务器端JavaScript变得流行之前就推出了酷炫的Node.js,但他们错过了这个机会。 - Daniel Sokolowski

86

这将弹出另一个命令提示符窗口:

START CMD /C "ECHO My Popup Message && PAUSE"

1
太棒了,我可能会在其他几个脚本中使用它 :) - billyy
4
更好的选择是:start cmd /c "@echo off & mode con cols=18 lines=2 & echo My Popup Message & pause>nul",将cols=18更改为消息中字符数+2的数量。将lines=2更改为行数+1的数量。 - ender_scythe
1
摆脱PAUSE并使用cmd /k - Artelius

36
尝试:
Msg * "insert your message here" 

如果您正在使用Windows XP的command.com,则会打开一个消息框。
打开新的cmd窗口似乎不是您所要求的。 您还可以使用VBScript,并将其与您的.bat文件一起使用。您可以使用此命令从.bat文件中打开它:
cd C:\"location of vbscript"

这个操作会改变 command.com 查找文件的目录,然后在下一行中:

"insert name of your vbscript here".vbs

然后您创建一个新的记事本文档,输入

<script type="text/vbscript">
    MsgBox "your text here"
</script>

然后,您将此保存为 .vbs 文件(在文件名末尾加上“.vbs”),在文件名下面的下拉框中选择“所有文件”进行保存(以便它不会保存为 .txt),然后单击“保存”!


3
不需要使用<script/>标签。 - surfasb
如何在使用 -> MSG * <text> 时在文本中插入新行(空行) - ZEE
@ZEE 如果你只使用 msg *,系统会提示你输入一条消息,然后按下 ctrl-Z。在这里你可以输入换行符,它们将出现在你的消息中。 - User5910

32

更多方法。

1)最极客和最hack的方法 - 使用IEXPRESS创建小型exe文件,该文件将创建一个带有单个按钮的弹出窗口(还可以创建两种其他类型的弹出消息)。适用于XP及以上的所有Windows系统:

;@echo off
;setlocal

;set ppopup_executable=popupe.exe
;set "message2=click OK to continue"
;
;del /q /f %tmp%\yes >nul 2>&1
;
;copy /y "%~f0" "%temp%\popup.sed" >nul 2>&1

;(echo(FinishMessage=%message2%)>>"%temp%\popup.sed";
;(echo(TargetName=%cd%\%ppopup_executable%)>>"%temp%\popup.sed";
;(echo(FriendlyName=%message1_title%)>>"%temp%\popup.sed"
;
;iexpress /n /q /m %temp%\popup.sed
;%ppopup_executable%
;rem del /q /f %ppopup_executable% >nul 2>&1

;pause

;endlocal
;exit /b 0


[Version]
Class=IEXPRESS
SEDVersion=3
[Options]
PackagePurpose=InstallApp
ShowInstallProgramWindow=1
HideExtractAnimation=1
UseLongFileName=0
InsideCompressed=0
CAB_FixedSize=0
CAB_ResvCodeSigning=0
RebootMode=N
InstallPrompt=%InstallPrompt%
DisplayLicense=%DisplayLicense%
FinishMessage=%FinishMessage%
TargetName=%TargetName%
FriendlyName=%FriendlyName%
AppLaunched=%AppLaunched%
PostInstallCmd=%PostInstallCmd%
AdminQuietInstCmd=%AdminQuietInstCmd%
UserQuietInstCmd=%UserQuietInstCmd%
SourceFiles=SourceFiles
[SourceFiles]
SourceFiles0=C:\Windows\System32\
[SourceFiles0]
%FILE0%=


[Strings]
AppLaunched=subst.exe
PostInstallCmd=<None>
AdminQuietInstCmd=
UserQuietInstCmd=
FILE0="subst.exe"
DisplayLicense=
InstallPrompt=

2) 使用MSHTA。它适用于从XP及以上的所有Windows机器(尽管OP不希望使用“外部”语言,但这里的JavaScript已被最小化)。应该保存为.bat文件:

@if (true == false) @end /*!
@echo off
mshta "about:<script src='file://%~f0'></script><script>close()</script>" %*
goto :EOF */

alert("Hello, world!");

或者用一行来表示:
mshta "about:<script>alert('Hello, world!');close()</script>"

或者

mshta "javascript:alert('message');close()"

或者
mshta.exe vbscript:Execute("msgbox ""message"",0,""title"":close")

3) 这里是参数化的 .bat/jscript 混合体(应保存为 bat)。尽管 OP 请求使用 JavaScript,但作为一个批处理文件,它可以被称为批处理文件而无需担心。它使用 POPUP,它允许比更流行的 MSGBOX 更多的控制。它使用 WSH,但不像上面的例子中使用 MSHTA。

 @if (@x)==(@y) @end /***** jscript comment ******
     @echo off

     cscript //E:JScript //nologo "%~f0" "%~nx0" %*
     exit /b 0

 @if (@x)==(@y) @end ******  end comment *********/


var wshShell = WScript.CreateObject("WScript.Shell");
var args=WScript.Arguments;
var title=args.Item(0);

var timeout=-1;
var pressed_message="button pressed";
var timeout_message="timed out";
var message="";

function printHelp() {
    WScript.Echo(title + "[-title Title] [-timeout m] [-tom \"Time-out message\"] [-pbm \"Pressed button message\"]  [-message \"pop-up message\"]");
}

if (WScript.Arguments.Length==1){
    runPopup();
    WScript.Quit(0);
}

if (args.Item(1).toLowerCase() == "-help" || args.Item(1).toLowerCase() == "-h" ) {
    printHelp();
    WScript.Quit(0);
}

if (WScript.Arguments.Length % 2 == 0 ) {
    WScript.Echo("Illegal arguments ");
    printHelp();
    WScript.Quit(1);
}

for (var arg = 1 ; arg<args.Length;arg=arg+2) {

    if (args.Item(arg).toLowerCase() == "-title") {
        title = args.Item(arg+1);
    }

    if (args.Item(arg).toLowerCase() == "-timeout") {
        timeout = parseInt(args.Item(arg+1));
        if (isNaN(timeout)) {
            timeout=-1;
        }
    }

    if (args.Item(arg).toLowerCase() == "-tom") {
        timeout_message = args.Item(arg+1);
    }

    if (args.Item(arg).toLowerCase() == "-pbm") {
        pressed_message = args.Item(arg+1);
    }

    if (args.Item(arg).toLowerCase() == "-message") {
        message = args.Item(arg+1);
    }
}

function runPopup(){
    var btn = wshShell.Popup(message, timeout, title, 0x0 + 0x10);

    switch(btn) {
        // button pressed.
        case 1:
            WScript.Echo(pressed_message);
            break;

        // Timed out.
        case -1:
           WScript.Echo(timeout_message);
           break;
    }
}

runPopup();

4) 还有一个 jscript.net/.bat 混合文件(应该保存为 .bat)。这次它使用了 .NET 并编译了一个小的 .exe 文件,可以被删除:

@if (@X)==(@Y) @end /****** silent jscript comment ******

@echo off
::::::::::::::::::::::::::::::::::::
:::       compile the script    ::::
::::::::::::::::::::::::::::::::::::
setlocal


::if exist "%~n0.exe" goto :skip_compilation

:: searching the latest installed .net framework
for /f "tokens=* delims=" %%v in ('dir /b /s /a:d /o:-n "%SystemRoot%\Microsoft.NET\Framework\v*"') do (
    if exist "%%v\jsc.exe" (
        rem :: the javascript.net compiler
        set "jsc=%%~dpsnfxv\jsc.exe"
        goto :break_loop
    )
)
echo jsc.exe not found && exit /b 0
:break_loop



call %jsc% /nologo /out:"%~n0.exe" "%~f0" 
::::::::::::::::::::::::::::::::::::
:::       end of compilation    ::::
::::::::::::::::::::::::::::::::::::
:skip_compilation

::
::::::::::
"%~n0.exe" %*
::::::::
::
endlocal
exit /b 0

****** end of jscript comment ******/

import System;
import System.Windows;
import System.Windows.Forms

var arguments:String[] = Environment.GetCommandLineArgs();
MessageBox.Show(arguments[1],arguments[0]);

5) 最后只需一次调用PowerShell即可创建弹出窗口(如果已安装PowerShell,则可以从命令行或批处理中调用):

powershell [Reflection.Assembly]::LoadWithPartialName("""System.Windows.Forms""");[Windows.Forms.MessageBox]::show("""Hello World""", """My PopUp Message Box""")

6) 这里可以看到dbenham的方法(链接)

start "" cmd /c "echo(&echo(&echo              Hello world!     &echo(&pause>nul"

7) 如果你想要进行系统托盘通知,可以尝试使用这个

call SystemTrayNotification.bat  -tooltip warning -time 3000 -title "Woow" -text "Boom" -icon question

在#2下的第一个示例中,@if(true == false) @end的目的是什么? - Dan Henderson
@DanHenderson 在批次处理中会因为 @ 符号而保持安静。对于 JScript,可以使用 @if 指令来实现 - https://documentation.help/MS-Office-JScript/jsstmconditionalif.htm。它被用于静默地启用 JScript 注释。 - npocmaka

30

使用这种方式,你的批处理文件将创建一个VBS脚本并显示弹出窗口。运行完成后,批处理文件将删除该中间文件。

使用MSGBOX的优点是它非常可定制(可以更改标题、图标等),而MSG.exe的定制性不如此好。

echo MSGBOX "YOUR MESSAGE" > %temp%\TEMPmessage.vbs
call %temp%\TEMPmessage.vbs
del %temp%\TEMPmessage.vbs /f /q

23

以下是一种 PowerShell 变体,它在创建窗口之前不需要加载程序集,但是其运行速度明显较慢(增加约50%),与 @npocmaka 在此处发布的 PowerShell MessageBox 命令相比:

powershell (New-Object -ComObject Wscript.Shell).Popup("""Operation Completed""",0,"""Done""",0x0)
您可以将最后一个参数从“0x0”更改为以下值以在对话框中显示图标(有关详细信息,请参见Popup 方法):
        Stop 0x10 停止
        Question Mark 0x20 问号
        Exclamation Mark 0x30 惊叹号
        Information Mark 0x40 信息图标
摘自Microsoft TechNet文章PowerTip: 使用 PowerShell 显示弹出窗口

1
第二个参数是nSecondsToWait,可选。数字值,表示您希望弹出消息框显示的最大秒数。如果nSecondsToWait为零(默认值),则弹出消息框将一直保持可见,直到用户关闭它。https://learn.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/windows-scripting/x83z1d9f(v=vs.84) - Sergey Nemchinov

11
echo X=MsgBox("Message Description",0+16,"Title") >msg.vbs

在“+”符号之前,您可以写入0、1、2、3或4中的任何数字。以下是每个数字的含义:

0 = Ok Button  
1 = Ok/Cancel Button  
2 = Abort/Retry/Ignore button  
3 = Yes/No/Cancel  
4 = Yes/No  

- 你可以在“+”符号后面写任何数字,包括16、32、48和64。每个数字的含义如下:

16 – Critical Icon  
32 – Warning Icon  
48 – Warning Message Icon   
64 – Information Icon  

3
你如何从VB脚本中获取响应? - Marcello B.

8

消息 * "在这里插入您的消息"

运行良好,只需在记事本中保存为 .bat 文件或确保格式设置为“所有文件”


1
文档中说“*”将“向指定服务器上的所有会话发送消息”,即在终端服务或快速用户切换上会中断。 - Fowl
2
你可以使用 msg %SESSIONNAME% msg - Fowl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接