How do I create a Delayable count down msg box, wh

2019-02-16 01:32发布

问题:

Hi I'm attempting to create a Message box with a "DELAY" button If the user does not press the Delay button the script will launch a batch file (or command)

So it should go like this:

Hello User Your Administrator has requested you to log out of this application after work, we have detected you are still using the program, please press Delay if you are still at your machine.

Ideally, I would like it to detect when a certain program is active, and only activate if it is

Thanks

Here is the final version

@if (@CodeSection == @Batch) @then
@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
setlocal
set "task=agent.exe"
set "timeout=120"
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'),
    nag = 'Greetings!  Your administrator has requested you to log out of Touchstar '
        + 'after work.  It appears you are still using it.'
        + ' If you are still here, Press Yes to continue working.\n\n'
        + 'Otherwise, press no to close touchstar.'
        + 'Touchstar will close automatically in less than ' + WSH.Arguments(0) + ' seconds.';
    popup = osh.Popup(nag, WSH.Arguments(0), 'Are you still here?', 0x4 + 0x20 + 0x1000);
WSH.Quit(popup - 6);

Thank you to all who helped create this (big shoutout to Rojo), and all who answered.

  • Denslat

回答1:

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.



回答2:

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.



回答3:

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
'**************************************************************************