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

169

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


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

6
msg * /time:0 /w Hello everybody!

当单击“确定”按钮之前,此消息会一直等待(默认情况下持续一分钟),在Windows 8.1中运行良好。


自2009年以来,相同的答案一直存在。 - jeb
抱歉 >_< 请删除它 :) - MoE bis
如何在文本中插入新行(空行) - ZEE
3
msg * /time:0 /w <C:\Somewhere\Message.txt 这条命令会从文件中读取普通文本(包含回车换行符),并发送给所有用户。 - MoE bis

4
为了实现这个目标,您需要一个小程序来显示消息框,并从批处理文件中运行它。
您可以打开一个显示提示符的控制台窗口,但是仅使用cmd.exe和相关工具获取GUI消息框是不可能的。

你有更多相关信息吗? - billyy
1
回显“xx”,暂停或设置/p var=prompt是cmd.exe选项。 - Macke

4

接着@Fowl的回答,你可以使用下面的代码来增加一个超时时间,使其只在10秒内出现:

mshta "javascript:var sh=new ActiveXObject( 'WScript.Shell' ); sh.Popup( 'Message!', 10, 'Title!', 64 );close()"

更多细节请参见此处


检测到病毒 xD - Julien

3
您可以调用user32.dll中的dll函数,类似于:

Rundll32.exe user32.dll, MessageBox (0, "文本", "标题文本", {额外标志,如置顶消息框等})

从我的手机输入,不要评判我...否则我会提供额外标志的链接。

当我在运行框中执行rundll32.exe user32.dll,MessageBoxA X时,我可以显示一个标题为X的消息框。无论我将X设置为什么,我都无法将其解释为多个参数 - 所有内容都进入标题。因此,rundll32.exe user32.dll,MessageBoxA (0, "MyTitle", "MyText", 0) 显示一个标题为(0, "MyTitle", "MyText", 0)的消息框。但是,我无法从命令行使它完全工作 - 只能从运行框中使用。在命令行上它根本不起作用。它是否确实可以从命令行或批处理文件中工作,还是只能从运行框中使用? - Jerry Jeremiah
根据文档,rundll32.exe只能运行专门为此目的设计的过程,因为它们必须解析“可选参数”部分。MessageBox-ish函数不是这样设计的。为什么它可以通过Win+R(运行框)工作,这仍然是一个大问题! - Yuri Pozniak

2

据赛门铁克杀毒软件显示,此存档文件包含木马病毒。 - David
3
@David - 我曾有过一些批处理文件和文本文件被杀毒软件标记为恶意文件。实际上,我曾经使用AVG杀毒软件捕获了一个命令行指令,并声称它是病毒。 - James K
2
值得一提的是,Virus Total 表示在该文件上有 11/51 个病毒检测器检测到病毒:https://www.virustotal.com/en/file/04ab7621d575ed755f8c353986a4e79fad2e52d9023545a2120f356fc1e779da/analysis/1401001549/ - Matthew Lock

2

1
这个应用程序可以实现这一点,如果你将批处理文件转换(包装)为可执行文件。

  1. Simple Messagebox

    %extd% /messagebox Title Text
    

  1. Error Messagebox

    %extd% /messagebox  Error "Error message" 16
    
  2. Cancel Try Again Messagebox

    %extd% /messagebox Title "Try again or Cancel" 5
    

4) "再也不要问我"消息框

%extd% /messageboxcheck Title Message 0 {73E8105A-7AD2-4335-B694-94F837A38E79}

1
这是我根据其他帖子中的好答案编写的批处理脚本。
您可以设置标题超时时间,甚至可以使用 sleep 命令来安排后续操作,并使用 \n 来换行。
将其命名为 popup.bat 并将其放置在 Windows 路径文件夹中,以便在整个计算机上全局使用。
例如,popup Line 1\nLine 2 将生成一个两行的弹出框(输入 popup /? 查看用法)。
下面是代码:
<!-- : Begin CMD
@echo off
cscript //nologo "%~f0?.wsf" %*
set pop.key=[%errorlevel%]
if %pop.key% == [-1] set pop.key=TimedOut
if %pop.key% == [1]  set pop.key=Ok
if %pop.key% == [2]  set pop.key=Cancel
if %pop.key% == [3]  set pop.key=Abort
if %pop.key% == [4]  set pop.key=Retry
if %pop.key% == [5]  set pop.key=Ignore
if %pop.key% == [6]  set pop.key=Yes
if %pop.key% == [7]  set pop.key=No
if %pop.key% == [10] set pop.key=TryAgain
if %pop.key% == [11] set pop.key=Continue
if %pop.key% == [99] set pop.key=NoWait
exit /b 
-- End CMD -->

<job><script language="VBScript">
'on error resume next
q   =""""
qsq =""" """
Set objArgs = WScript.Arguments
Set objShell= WScript.CreateObject("WScript.Shell")
Popup       =   0
Title       =   "Popup"
Timeout     =   0
Mode        =   0
Message     =   ""
Sleep       =   0
button      =   0
If objArgs.Count = 0 Then 
    Usage()
ElseIf objArgs(0) = "/?" or Lcase(objArgs(0)) = "-h" or Lcase(objArgs(0)) = "--help" Then 
    Usage()
End If
noWait = Not wait() 
For Each arg in objArgs
    If (Mid(arg,1,1) = "/") and (InStr(arg,":") <> 0) Then haveSwitch   =   True
Next
If not haveSwitch Then 
    Message=joinParam("woq")
Else
    For i = 0 To objArgs.Count-1 
        If IsSwitch(objArgs(i)) Then 
            S=split(objArgs(i) , ":" , 2)
                select case Lcase(S(0))
                    case "/m","/message"
                        Message=S(1)
                    case "/tt","/title"
                        Title=S(1)
                    case "/s","/sleep"
                        If IsNumeric(S(1)) Then Sleep=S(1)*1000
                    case "/t","/time"
                        If IsNumeric(S(1)) Then Timeout=S(1)
                    case "/b","/button"
                        select case S(1)
                            case "oc", "1"
                                button=1
                            case "ari","2"
                                button=2
                            case "ync","3"
                                button=3
                            case "yn", "4"
                                button=4
                            case "rc", "5"
                                button=5
                            case "ctc","6"
                                button=6
                            case Else
                                button=0
                        end select
                    case "/i","/icon"
                        select case S(1)
                            case "s","x","stop","16"
                                Mode=16
                            case "?","q","question","32"
                                Mode=32
                            case "!","w","warning","exclamation","48"
                                Mode=48
                            case "i","information","info","64"
                                Mode=64
                            case Else 
                                Mode=0
                        end select
                end select
        End If
    Next
End If
Message = Replace(Message,"/\n", "°"  )
Message = Replace(Message,"\n",vbCrLf)
Message = Replace(Message, "°" , "\n")
If noWait Then button=0

Wscript.Sleep(sleep)
Popup   = objShell.Popup(Message, Timeout, Title, button + Mode + vbSystemModal)
Wscript.Quit Popup

Function IsSwitch(Val)
    IsSwitch        = False
    If Mid(Val,1,1) = "/" Then
        For ii = 3 To 9 
            If Mid(Val,ii,1)    = ":" Then IsSwitch = True
        Next
    End If
End Function

Function joinParam(quotes)
    ReDim ArgArr(objArgs.Count-1)
    For i = 0 To objArgs.Count-1 
        If quotes = "wq" Then 
            ArgArr(i) = q & objArgs(i) & q 
        Else
            ArgArr(i) =     objArgs(i)
        End If
    Next
    joinParam = Join(ArgArr)
End Function

Function wait()
    wait=True
    If objArgs.Named.Exists("NewProcess") Then
        wait=False
        Exit Function
    ElseIf objArgs.Named.Exists("NW") or objArgs.Named.Exists("NoWait") Then
        objShell.Exec q & WScript.FullName & qsq & WScript.ScriptFullName & q & " /NewProcess: " & joinParam("wq") 
        WScript.Quit 99
    End If
End Function

Function Usage()
    Wscript.Echo _
                     vbCrLf&"Usage:" _
                    &vbCrLf&"      popup followed by your message. Example: ""popup First line\nescaped /\n\nSecond line"" " _
                    &vbCrLf&"      To triger a new line use ""\n"" within the msg string [to escape enter ""/"" before ""\n""]" _
                    &vbCrLf&"" _
                    &vbCrLf&"Advanced user" _
                    &vbCrLf&"      If any Switch is used then you must use the /m: switch for the message " _
                    &vbCrLf&"      No space allowed between the switch & the value " _
                    &vbCrLf&"      The switches are NOT case sensitive " _
                    &vbCrLf&"" _
                    &vbCrLf&"      popup [/m:""*""] [/t:*] [/tt:*] [/s:*] [/nw] [/i:*]" _
                    &vbCrLf&"" _
                    &vbCrLf&"      Switch       | value |Description" _
                    &vbCrLf&"      -----------------------------------------------------------------------" _
                    &vbCrLf&"      /m: /message:| ""1 2"" |if the message have spaces you need to quote it " _
                    &vbCrLf&"                   |       |" _
                    &vbCrLf&"      /t: /time:   | nn    |Duration of the popup for n seconds " _
                    &vbCrLf&"                   |       |<Default> untill key pressed" _
                    &vbCrLf&"                   |       |" _
                    &vbCrLf&"      /tt: /title: | ""A B"" |if the title have spaces you need to quote it " _
                    &vbCrLf&"                   |       | <Default> Popup" _
                    &vbCrLf&"                   |       |" _
                    &vbCrLf&"      /s: /sleep:  | nn    |schedule the popup after n seconds " _
                    &vbCrLf&"                   |       |" _
                    &vbCrLf&"      /nw /NoWait  |       |Continue script without the user pressing ok - " _
                    &vbCrLf&"                   |       | botton option will be defaulted to OK button " _
                    &vbCrLf&"                   |       |" _
                    &vbCrLf&"      /i: /icon:   | ?/q   |[question mark]"  _
                    &vbCrLf&"                   | !/w   |[exclamation (warning) mark]"  _
                    &vbCrLf&"                   | i/info|[information mark]"  _
                    &vbCrLf&"                   | x/stop|[stop\error mark]" _
                    &vbCrLf&"                   | n/none|<Default>" _
                    &vbCrLf&"                   |       |" _
                    &vbCrLf&"      /b: /button: | o     |[OK button] <Default>"  _
                    &vbCrLf&"                   | oc    |[OK and Cancel buttons]"  _
                    &vbCrLf&"                   | ari   |[Abort, Retry, and Ignore buttons]"  _
                    &vbCrLf&"                   | ync   |[Yes, No, and Cancel buttons]" _
                    &vbCrLf&"                   | yn    |[Yes and No buttons]" _
                    &vbCrLf&"                   | rc    |[Retry and Cancel buttons]" _
                    &vbCrLf&"                   | ctc   |[Cancel and Try Again and Continue buttons]" _
                    &vbCrLf&"      --->         | --->  |The output will be saved in variable ""pop.key""" _
                    &vbCrLf&"" _
                    &vbCrLf&"Example:" _
                    &vbCrLf&"        popup /tt:""My MessageBox"" /t:5 /m:""Line 1\nLine 2\n/\n\nLine 4""" _
                    &vbCrLf&"" _
                    &vbCrLf&"                     v1.9 By RDR @ 2020"
    Wscript.Quit
End Function

</script></job>

1
我会创建一个批处理子程序MSGBOX,如下所示,您可以通过以下方式调用:
call :MSGBOX "Test-Message 1" "Test-Title 1"

您可以随时使用。

例如:

@ECHO OFF

:: call message box sub-routine
call :MSGBOX "Test-Message 1" "Test-Title 1"
call :MSGBOX "Test-Message 2" "Test-Title 2"

:END
EXIT /B


::::::::::::::::
:: sub-routines

:MSGBOX
:: 1. parameter: message
:: 2. parameter: title

:: find temporary name for VBS file
:uniqueLoop
set "uniqueFileName=%tmp%\msgbox~%RANDOM%.vbs"
if exist "%uniqueFileName%" goto :uniqueLoop

:: write to temporary VBS file, execute, delete file
echo msgbox"%~1",vbInformation , "%~2"> %uniqueFileName% 
%uniqueFileName% 
erase %uniqueFileName%
EXIT /B

1

Bat文件:

@echo off
echo wscript.Quit((msgbox("question?",4+32+256, "title")-6) Mod 255) > %temp%\msgbox.vbs
start /wait %temp%\msgbox.vbs
rem echo wscript returned %errorlevel%
if errorlevel 1 goto error
echo We have Yes
goto end
:error
echo We have No
:end
del %temp%\msgbox.vbs /f /q

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