How do I create a Delayable count down msg box, which triggers bat file

徘徊边缘 提交于 2019-12-01 01:12:46
rojo

Challenge: accepted. Save this as a .bat file and run it.

@if (@CodeSection == @Batch) @then

@echo off
setlocal

set "task=cmd.exe"
set "timeout=60"

rem // Is %task% running?
tasklist /fi "imagename eq %task%" | find /i "%task%" >NUL && (

    rem // Re-launch script with JScript interpreter
    wscript /e:JScript /nologo "%~f0" %timeout% || (

        rem // If timeout or user hits No, kill %task%
        taskkill /im "%task%" /f
    )
)

rem // End main runtime
goto :EOF

rem // Begin JScript portion
@end

var osh = WSH.CreateObject('WScript.Shell'),
    noise = WSH.CreateObject('WMPlayer.OCX.7'),
    nag = 'Greetings!  Your administrator has requested you to log out of this '
        + 'application after work.  It appears you are still using the program.  If '
        + 'you are, in fact, not at your computer, please ignore this message.\n\n'
        + 'Otherwise, press Yes to continue working, or No to go ahead and close the '
        + 'application.  This message will self-destruct in ' + WSH.Arguments(0)
        + ' seconds.';

with (noise) {
    URL = osh.Environment('Process')('SYSTEMROOT') + '\\Media\\Windows Exclamation.wav';
    Controls.play();
}

popup = osh.Popup(nag, WSH.Arguments(0), 'Are you still here?', 0x4 + 0x20 + 0x1000);

WSH.Quit(popup - 6);

The script employs JosefZ's suggested WshShell.Popup() method, and is pretty straight forward. It uses a hybrid convention for including JScript within a batch script without having to use secondary / temporary files. It also employs conditional execution to evaluate the exit code of find and wscript.

The WMPlayer.OCX.7 idea to play a sound came from this answer.


Edit: I saw your edit above and your struggle to include ^G in your paste. Check this out. You can capture a beep to a variable like this:

@echo off
setlocal

for /f %%I in ('forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo 0x07"') do set "beep=%%I"
set /P "=%beep%"<NUL
set /P "=%beep%"<NUL
set /P "=%beep%"<NUL

... will beep 3 times without echoing a new line.

Save this as a .bat file:

@if (@CodeSection == @Batch) @then

@echo off
CScript //nologo //E:JScript "%~F0"
if %errorlevel% equ -1 (
   echo The user NOT confirmed, proceed to auto-destruction!
) else (
   echo Continue normally...
)
pause
goto :EOF

@end

WScript.Quit(WScript.CreateObject("WScript.Shell").Popup(
   "This program will proceed to auto-destruction\nunless you press OK in 10 seconds",
   10,"Popup Title",48))

The 10 is the number of seconds, the 48 the type of icon shown (an exclamation mark in this case), but you may modify it as described here.

Here is another solution in pure vbscript that let you monitor more than one application. just give a try and you will know what i mean.

Option Explicit
If AppPrevInstance() Then   
    MsgBox "There is an existing proceeding !" & VbCrLF & CommandLineLike(WScript.ScriptName),VbExclamation,"There is an existing proceeding !"    
    WScript.Quit   
Else   
    Do   
        Call Main(Array("c:\toto1.bat","c:\toto2.bat","c:\toto3.bat","%ProgramFiles%\Internet Explorer\iexplore.exe"))
        Call Pause(1) 'Sleeping for 1 minute
    Loop   
End If   
'**************************************************************************
Sub Main(colProcessPaths)   
    Dim ProcessPath   
    For Each ProcessPath In colProcessPaths     
        CheckProcess(ProcessPath)   
    Next   
End Sub   
'**************************************************************************
Sub CheckProcess(ProcessPath)   
    On error resume Next
    Dim Process,objWMIService,colProcesses,wshShell,btn,Timeout,User
    Dim ProcessName : ProcessName = StripProcPath(ProcessPath)   
    Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\.\root\cimv2")
    Set colProcesses = objWMIService.ExecQuery _
    ("SELECT * FROM Win32_Process WHERE Commandline LIKE " & CommandLineLike(ProcessName))
    For Each Process in colProcesses    
        If colProcesses.Count > 0 Then
            Set wshShell = CreateObject("WScript.Shell")
            User = CreateObject("WScript.Network").UserName
            Timeout = 30 'Call the Popup method with a 30 seconds timeout.
            btn = WshShell.Popup("Hello "& DblQuote(User) & " !" & vbcr &_
            "Your Administrator has requested you to log out of this application after work. " & vbcr &_
            "We have detected you are still using the program : "& DblQuote(ProcessName) & vbcr &_
            "Please press on cancel button if you are still at your machine ?",Timeout,"Question", vbOKCancel + vbQuestion)
            Select Case btn
' Yes button pressed.
            case 1
                Process.Terminate(0)
' No button pressed.
            case 2
                Exit Sub
' Timed out.
            case -1
                Process.Terminate(0)
            End Select
        Else    
            Exit Sub    
        End if 
    Next            
End Sub   
'**************************************************************************
Function AppPrevInstance()   
    With GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\.\root\cimv2")   
        With .ExecQuery("SELECT * FROM Win32_Process WHERE CommandLine LIKE " & CommandLineLike(WScript.ScriptFullName) & _
            " AND CommandLine LIKE '%WScript%' OR CommandLine LIKE '%cscript%'")   
            AppPrevInstance = (.Count > 1)   
        End With   
    End With   
End Function   
'**************************************************************************
Sub Pause(Minutes)    
    Wscript.Sleep(Minutes*1000*60)    
End Sub   
'**************************************************************************
Function StripProcPath(ProcessPath)   
    Dim arrStr : arrStr = Split(ProcessPath, "\")   
    StripProcPath = arrStr(UBound(arrStr))   
End Function   
'**************************************************************************
Function CommandLineLike(ProcessPath)   
    ProcessPath = Replace(ProcessPath, "\", "\\")   
    CommandLineLike = "'%" & ProcessPath & "%'"   
End Function
'**************************************************************************
Function DblQuote(Str)
    DblQuote = Chr(34) & Str & Chr(34)
End Function
'**************************************************************************
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!