显示批处理文件中的气球通知
Show balloon notifications from batch file
我想显示来自 运行 长时间的批次的气球通知。
我知道you can show popups(有些解决方案非常有想象力),但也有这个选项会很有趣。
有没有办法从批处理文件中显示气球通知?请至少从 Windows 7 开始,但也欢迎 XP。
我想至少需要一个托盘图标,但坦率地说,我不能走得更远。也许 rundll32.exe
?我知道 this is not a recommended way to do anything from command line.
The function signature required for functions called by rundll32.exe
is documented in this Knowledge Base
article.
That hasn't stopped people from using rundll32 to call random
functions that weren't designed to be called by rundll32, like user32
LockWorkStation
or user32
ExitWindowsEx.
但我发现这个 RunAnyDll utility by Yaniv Pessach 似乎使 .dll 调用正确。不幸的是,我发现没有有效的 link 来测试它(不,它不在 Internet 存档中)。我写信给作者要一个。让我们看看。
(我什至不知道它是否有用,但它是一个有趣的实用程序。也许它可以解决 this answer 弹出问题。我认为 Run
框之间的区别并且命令行执行与 Raymond Chen post.)
中的调用约定有关
另一个无法测试的实用程序是已弃用的 eventtriggers,但我再次不确定它是否有帮助。
编辑澄清:
npocmaka 和 greg zakharov 的回答都很有趣。 npocmaka 的一个更接近我的要求,因为它会产生气球通知。 greg zakharov 使用了不同的技术,但其结果非常相似(在本例中,文本出现在鼠标指针位置)。我已经在 XP 中对它们进行了测试,并且都可以正常工作(安装了 .NET)。两者都有超时,我不知道如何在用户点击之前保留通知(以防万一用户不在但你想看到它)。
理想情况下,我的问题是关于得到这样的东西。
@echo off
echo Some long part job that goes well.
call :balloon "Report about above tasks" [optional parameters about icon, title, timeout, etc.]
echo More tasks but one fails
if errorlevel 1 call :balloon "Error this and that" [optional parameters]
echo This is the end of the tasks
goto :eof
:balloon
echo If you don't want to make a temporary file
echo then you must make one-liner calls to PowerShell, wscript or whatever.
exit /b
因此,作为混合脚本,我看到的缺点是很难将其插入任何批处理中。如果您要在批次中多次重复使用,则为每个气球生成一个 .exe
似乎是不切实际的,所以最后,正如 greg zakharov 所说,它更健壮和灵活只生成一个接受参数并重用它的 .exe(就像 notifu)。最后,我认为使用 :balloon
子例程进行单行 powershell 调用是您可以获得的最好方法(几乎在 XP 中是本机的,因为您需要下载但也需要 .net)。
这是一个 jscript.net/bat 多语言脚本(必须另存为 .bat
),带有硬编码值(代码几乎与我评论中 link 中的代码相同),它将创建一个简单的系统托盘通知(将在每个安装了 .NET 的系统上工作。从 Windows Vista 开始,每台 windows 机器默认安装 .NET,所以这比 powershell 更向后兼容):
@if (@X)==(@Y) @end /* JScript comment
@echo off
setlocal
del /q /f %~n0.exe >nul 2>&1
for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d /o:-n "%SystemRoot%\Microsoft.NET\Framework\*jsc.exe"') do (
set "jsc=%%v"
)
if not exist "%~n0.exe" (
"%jsc%" /nologo /out:"%~n0.exe" "%~dpsfnx0"
)
if exist "%~n0.exe" (
"%~n0.exe" %*
)
endlocal & exit /b %errorlevel%
end of jscript comment*/
import System;
import System.Windows;
import System.Windows.Forms;
import System.Drawing;
import System.Drawing.SystemIcons;
var notification;
try {
notification = new System.Windows.Forms.NotifyIcon();
} catch (err){
}
notification.Icon = System.Drawing.SystemIcons.Hand; // Could be Application,Asterisk,Error,Exclamation,Hand,Information,Question,Shield,Warning,WinLogo
notification.BalloonTipText = "Message!!";
notification.Visible = true;
// optional - BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info;
// optional - BalloonTipTitle = "My Title",
// Display for 2 seconds.
notification.ShowBalloonTip(2000);
System.Threading.Thread.Sleep(2100);
notification.Dispose();
它将编译一个将被调用的小可执行文件。
如果您不想创建临时可执行文件,您可以检查使用的 msbuild 技术 (尽管这仅适用于 windows 10)。我也可以创建它的参数化版本。
编辑:here's a tool 命令行选项:
call systemTrayNotification.bat -tooltip warning -time 3000 -title "Woow" -text "Boom" -icon question
有很多 hacky 方法可以实现既定目标。其中之一是由 npocmaka 描述的。请密切注意,同样的方法也可以用于 PowerShell(可以找到如何组合 PowerShell 脚本的示例 here)。另一种可以产生心智的怪物(这个可以兼容WinXP)可以是CMD加WSH。
0</* :
@echo off
setlocal
echo Some batch code here...
cscript /nologo /e:jscript "%~f0" "Warning!"
pause
echo Another batch code...
cscript /nologo /e:jscript "%~f0" "All done!"
pause
endlocal
exit /b*/0;
(function(msg) {
with (new ActiveXObject('Internet.HHCtrl')) {
TextPopup(msg, 'Lucida Console, 23', 1, 1, 1, 1);
WScript.Sleep(1500);
}
}(
WScript.Arguments.length !== 1 ?
WScript.Quit(1) : WScript.Arguments.Unnamed(0)
));
请注意,我不强烈建议使用混种和其他hymera。我敢肯定,最好的方法就是编写特殊的命令行工具。
方法一:LC.exeCMDLet
这个小 CMDlet(您可以从批处理文件中调用的便携式 .exe 文件)可以比较两个文件,并在名为 old.txt
的 txt 文档中导出第一个文件独有的行,在名为 old.txt
的 txt 文档中导出第二个文件独有的行new.txt
上下文是 lc File1.txt File2.txt
这是文件:1drv.ms/u/s!AlRLV33Rdz2CgrgeqSerXbeXyVhRYQ
方法 2: 批处理文件中的 Powershell 脚本
:notification
::Synax is call :notification [Title] [Body] [Icon]
echo notification: %1 %2 %3
echo [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") > notfy.ps1
echo $objNotifyIcon = New-Object System.Windows.Forms.NotifyIcon >> notfy.ps1
echo $objNotifyIcon.Icon = "ico%3.ico" >> notfy.ps1
echo $objNotifyIcon.BalloonTipIcon = "None" >> notfy.ps1
echo $objNotifyIcon.BalloonTipText = %2 >> notfy.ps1
echo $objNotifyIcon.BalloonTipTitle = %1 >> notfy.ps1
echo $objNotifyIcon.Visible = $True >> notfy.ps1
echo $objNotifyIcon.ShowBalloonTip(10000) >> notfy.ps1
Powershell "& ""%cd%\notfy.ps1"""
del /f /q "notfy.ps1"
exit /b
只需将其添加到您的批处理文件中并使用 call :notification "Title" "Body" "Icon File"
调用它
注意: 此方法需要将 Powershell 执行策略设置为不受限制(不是默认设置)。你可以用这个来测试:
powershell Get-ExecutionPolicy >pgep.t
Find "Unrestricted" "pgep.t" >nul
if %errorlevel%==0 goto setuphere
del /f /q pgep.t
:setuphere
::Start a Batch File as admin with the command [Powershell Set-ExecutionPolicy $POLICY -Force] in it. (remove the brackets).
使用 PowerShell 一行代码
无需创建文件,无论执行策略如何都有效。感谢 Mark Dodsons 使用 PS 和 npocmaka 的图标列表。
另存为,例如,balloon.bat
(当然,您可以将其作为子程序插入任何批次)。
@echo off
if "%~1"=="" call :printhelp & exit /b 1
setlocal
if "%~2"=="" (set Icon=Information) else (set Icon=%2)
powershell -Command "[void] [System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); $objNotifyIcon=New-Object System.Windows.Forms.NotifyIcon; $objNotifyIcon.BalloonTipText='%~1'; $objNotifyIcon.Icon=[system.drawing.systemicons]::%Icon%; $objNotifyIcon.BalloonTipTitle='%~3'; $objNotifyIcon.BalloonTipIcon='None'; $objNotifyIcon.Visible=$True; $objNotifyIcon.ShowBalloonTip(5000);"
endlocal
goto :eof
:printhelp
echo USAGE: %~n0 Text [Icon [Title]]
echo Icon can be: Application, Asterisk, Error, Exclamation, Hand, Information, Question, Shield, Warning or WinLogo
exit /b
如果没有第二个参数,则默认为 Information
。
我想你可以使用 mshta
和 vbscript 或 javascript,但直到现在我都没有成功。
从@cdlvcdlv 简化而来,如果从不同的文件调用,它运行得更快。
notify.bat
@echo off
if "%~3"=="" (set Icon=Information) else (set Icon=%3)
cmd /c powershell -WindowStyle Hidden -Command "[void] [System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); $global:balloon = New-Object System.Windows.Forms.NotifyIcon; $balloon.Icon = [system.drawing.systemicons]::%Icon%; $balloon.Visible = $true; $balloon.ShowBalloonTip(5000, '%1', '%2', 'None'); Timeout /NoBreak 5; $balloon.Dispose(); Exit;"
EXIT 0
现在可以这样调用:
// Synthax
notify.bat "Title" "Message" "Type"
// Example 1
notify.bat "MyScript - Warning" "Some files are missing" "Warning"
// Example 2
cmd /c notify.bat "MyScript - Success" "Client is running"
如果你注意到了,所有 这些:
$balloon.BalloonTipIcon = 'Icon'
$balloon.BalloonTipText = 'Text'
$balloon.BalloonTipTitle = 'Title'
是否简化为:
$balloon.ShowBalloonTip(5000, 'Title', 'Text', 'Icon');
我想显示来自 运行 长时间的批次的气球通知。
我知道you can show popups(有些解决方案非常有想象力),但也有这个选项会很有趣。
有没有办法从批处理文件中显示气球通知?请至少从 Windows 7 开始,但也欢迎 XP。
我想至少需要一个托盘图标,但坦率地说,我不能走得更远。也许 rundll32.exe
?我知道 this is not a recommended way to do anything from command line.
The function signature required for functions called by rundll32.exe is documented in this Knowledge Base article. That hasn't stopped people from using rundll32 to call random functions that weren't designed to be called by rundll32, like user32 LockWorkStation or user32 ExitWindowsEx.
但我发现这个 RunAnyDll utility by Yaniv Pessach 似乎使 .dll 调用正确。不幸的是,我发现没有有效的 link 来测试它(不,它不在 Internet 存档中)。我写信给作者要一个。让我们看看。
(我什至不知道它是否有用,但它是一个有趣的实用程序。也许它可以解决 this answer 弹出问题。我认为 Run
框之间的区别并且命令行执行与 Raymond Chen post.)
另一个无法测试的实用程序是已弃用的 eventtriggers,但我再次不确定它是否有帮助。
编辑澄清:
npocmaka 和 greg zakharov 的回答都很有趣。 npocmaka 的一个更接近我的要求,因为它会产生气球通知。 greg zakharov 使用了不同的技术,但其结果非常相似(在本例中,文本出现在鼠标指针位置)。我已经在 XP 中对它们进行了测试,并且都可以正常工作(安装了 .NET)。两者都有超时,我不知道如何在用户点击之前保留通知(以防万一用户不在但你想看到它)。
理想情况下,我的问题是关于得到这样的东西。
@echo off
echo Some long part job that goes well.
call :balloon "Report about above tasks" [optional parameters about icon, title, timeout, etc.]
echo More tasks but one fails
if errorlevel 1 call :balloon "Error this and that" [optional parameters]
echo This is the end of the tasks
goto :eof
:balloon
echo If you don't want to make a temporary file
echo then you must make one-liner calls to PowerShell, wscript or whatever.
exit /b
因此,作为混合脚本,我看到的缺点是很难将其插入任何批处理中。如果您要在批次中多次重复使用,则为每个气球生成一个 .exe
似乎是不切实际的,所以最后,正如 greg zakharov 所说,它更健壮和灵活只生成一个接受参数并重用它的 .exe(就像 notifu)。最后,我认为使用 :balloon
子例程进行单行 powershell 调用是您可以获得的最好方法(几乎在 XP 中是本机的,因为您需要下载但也需要 .net)。
这是一个 jscript.net/bat 多语言脚本(必须另存为 .bat
),带有硬编码值(代码几乎与我评论中 link 中的代码相同),它将创建一个简单的系统托盘通知(将在每个安装了 .NET 的系统上工作。从 Windows Vista 开始,每台 windows 机器默认安装 .NET,所以这比 powershell 更向后兼容):
@if (@X)==(@Y) @end /* JScript comment
@echo off
setlocal
del /q /f %~n0.exe >nul 2>&1
for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d /o:-n "%SystemRoot%\Microsoft.NET\Framework\*jsc.exe"') do (
set "jsc=%%v"
)
if not exist "%~n0.exe" (
"%jsc%" /nologo /out:"%~n0.exe" "%~dpsfnx0"
)
if exist "%~n0.exe" (
"%~n0.exe" %*
)
endlocal & exit /b %errorlevel%
end of jscript comment*/
import System;
import System.Windows;
import System.Windows.Forms;
import System.Drawing;
import System.Drawing.SystemIcons;
var notification;
try {
notification = new System.Windows.Forms.NotifyIcon();
} catch (err){
}
notification.Icon = System.Drawing.SystemIcons.Hand; // Could be Application,Asterisk,Error,Exclamation,Hand,Information,Question,Shield,Warning,WinLogo
notification.BalloonTipText = "Message!!";
notification.Visible = true;
// optional - BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info;
// optional - BalloonTipTitle = "My Title",
// Display for 2 seconds.
notification.ShowBalloonTip(2000);
System.Threading.Thread.Sleep(2100);
notification.Dispose();
它将编译一个将被调用的小可执行文件。
如果您不想创建临时可执行文件,您可以检查使用的 msbuild 技术
编辑:here's a tool 命令行选项:
call systemTrayNotification.bat -tooltip warning -time 3000 -title "Woow" -text "Boom" -icon question
有很多 hacky 方法可以实现既定目标。其中之一是由 npocmaka 描述的。请密切注意,同样的方法也可以用于 PowerShell(可以找到如何组合 PowerShell 脚本的示例 here)。另一种可以产生心智的怪物(这个可以兼容WinXP)可以是CMD加WSH。
0</* :
@echo off
setlocal
echo Some batch code here...
cscript /nologo /e:jscript "%~f0" "Warning!"
pause
echo Another batch code...
cscript /nologo /e:jscript "%~f0" "All done!"
pause
endlocal
exit /b*/0;
(function(msg) {
with (new ActiveXObject('Internet.HHCtrl')) {
TextPopup(msg, 'Lucida Console, 23', 1, 1, 1, 1);
WScript.Sleep(1500);
}
}(
WScript.Arguments.length !== 1 ?
WScript.Quit(1) : WScript.Arguments.Unnamed(0)
));
请注意,我不强烈建议使用混种和其他hymera。我敢肯定,最好的方法就是编写特殊的命令行工具。
方法一:LC.exeCMDLet
这个小 CMDlet(您可以从批处理文件中调用的便携式 .exe 文件)可以比较两个文件,并在名为 old.txt
的 txt 文档中导出第一个文件独有的行,在名为 old.txt
的 txt 文档中导出第二个文件独有的行new.txt
上下文是 lc File1.txt File2.txt
这是文件:1drv.ms/u/s!AlRLV33Rdz2CgrgeqSerXbeXyVhRYQ
方法 2: 批处理文件中的 Powershell 脚本
:notification
::Synax is call :notification [Title] [Body] [Icon]
echo notification: %1 %2 %3
echo [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") > notfy.ps1
echo $objNotifyIcon = New-Object System.Windows.Forms.NotifyIcon >> notfy.ps1
echo $objNotifyIcon.Icon = "ico%3.ico" >> notfy.ps1
echo $objNotifyIcon.BalloonTipIcon = "None" >> notfy.ps1
echo $objNotifyIcon.BalloonTipText = %2 >> notfy.ps1
echo $objNotifyIcon.BalloonTipTitle = %1 >> notfy.ps1
echo $objNotifyIcon.Visible = $True >> notfy.ps1
echo $objNotifyIcon.ShowBalloonTip(10000) >> notfy.ps1
Powershell "& ""%cd%\notfy.ps1"""
del /f /q "notfy.ps1"
exit /b
只需将其添加到您的批处理文件中并使用 call :notification "Title" "Body" "Icon File"
调用它
注意: 此方法需要将 Powershell 执行策略设置为不受限制(不是默认设置)。你可以用这个来测试:
powershell Get-ExecutionPolicy >pgep.t
Find "Unrestricted" "pgep.t" >nul
if %errorlevel%==0 goto setuphere
del /f /q pgep.t
:setuphere
::Start a Batch File as admin with the command [Powershell Set-ExecutionPolicy $POLICY -Force] in it. (remove the brackets).
使用 PowerShell 一行代码
无需创建文件,无论执行策略如何都有效。感谢 Mark Dodsons
另存为,例如,balloon.bat
(当然,您可以将其作为子程序插入任何批次)。
@echo off
if "%~1"=="" call :printhelp & exit /b 1
setlocal
if "%~2"=="" (set Icon=Information) else (set Icon=%2)
powershell -Command "[void] [System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); $objNotifyIcon=New-Object System.Windows.Forms.NotifyIcon; $objNotifyIcon.BalloonTipText='%~1'; $objNotifyIcon.Icon=[system.drawing.systemicons]::%Icon%; $objNotifyIcon.BalloonTipTitle='%~3'; $objNotifyIcon.BalloonTipIcon='None'; $objNotifyIcon.Visible=$True; $objNotifyIcon.ShowBalloonTip(5000);"
endlocal
goto :eof
:printhelp
echo USAGE: %~n0 Text [Icon [Title]]
echo Icon can be: Application, Asterisk, Error, Exclamation, Hand, Information, Question, Shield, Warning or WinLogo
exit /b
如果没有第二个参数,则默认为 Information
。
我想你可以使用 mshta
和 vbscript 或 javascript,但直到现在我都没有成功。
从@cdlvcdlv
notify.bat
@echo off
if "%~3"=="" (set Icon=Information) else (set Icon=%3)
cmd /c powershell -WindowStyle Hidden -Command "[void] [System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); $global:balloon = New-Object System.Windows.Forms.NotifyIcon; $balloon.Icon = [system.drawing.systemicons]::%Icon%; $balloon.Visible = $true; $balloon.ShowBalloonTip(5000, '%1', '%2', 'None'); Timeout /NoBreak 5; $balloon.Dispose(); Exit;"
EXIT 0
现在可以这样调用:
// Synthax
notify.bat "Title" "Message" "Type"
// Example 1
notify.bat "MyScript - Warning" "Some files are missing" "Warning"
// Example 2
cmd /c notify.bat "MyScript - Success" "Client is running"
如果你注意到了,所有 这些:
$balloon.BalloonTipIcon = 'Icon'
$balloon.BalloonTipText = 'Text'
$balloon.BalloonTipTitle = 'Title'
是否简化为:
$balloon.ShowBalloonTip(5000, 'Title', 'Text', 'Icon');