1

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
Denslat
  • 169
  • 2
  • 12
  • I guess that your batch is trying to kill this application or something else ? – Hackoo Feb 04 '15 at 12:42
  • In summary, you want to check if this application is running, so you notify the user with a msgbox "delayed" to hit to wait for a while,if not, you launch the batch file to kill this application ? I'm right or not ? – Hackoo Feb 04 '15 at 12:49
  • 1
    [Popup method](https://msdn.microsoft.com/en-us/library/x83z1d9f(v=vs.84).aspx) could be a good starting point – JosefZ Feb 04 '15 at 13:07

3 Answers3

2

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.

Community
  • 1
  • 1
rojo
  • 24,000
  • 5
  • 55
  • 101
  • Thank you Rojo, this worked perfectly, it made my boss laugh too :D – Denslat Feb 04 '15 at 16:20
  • We have to have a sense of whimsy in this business to keep from going nuts. :) – rojo Feb 04 '15 at 16:27
  • Indeed, you have seriously saved my bacon with this, we have an issue of the program recording how long the user used it, but in order to make sure they were late "or not" they have to log out, and they tend to leave themselves logged in. – Denslat Feb 04 '15 at 16:39
  • Another Question, can you make it make a windows error sound on popup? – Denslat Feb 04 '15 at 16:48
  • 1
    @Denslat Added. Any further new feature requests should probably be asked as a separate question. But try to show that you put some effort into researching a solution before asking. Welcome to S.O.! – rojo Feb 04 '15 at 17:34
  • funny you should say that, I actually solved this using a second batch file and playing it three times haha using the Echo ^G with the weird bell symbol – Denslat Feb 04 '15 at 17:53
  • If you want to mess with your boss, use my version, but replace `Windows Exclamation.wav` with `town.mid` (which lives in the same directory). Or you could probably find a midi file with the Final Jeopardy music I bet. :) – rojo Feb 04 '15 at 17:56
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.

Aacini
  • 65,180
  • 12
  • 72
  • 108
1

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
'**************************************************************************
Hackoo
  • 18,337
  • 3
  • 40
  • 70
  • It ran once successfully. I hit "Cancel" and the script seemed to exit. Now subsequent attempts result in "There is an existing proceeding !\n'%test.vbs%'` You should also modify the `Popup()` final argument to include the 0x1000 bit for always on top. (vbModal? Just a guess.) – rojo Feb 04 '15 at 16:35
  • Because we must launch this script just once and it run in loop and try to open intenet explorer or another batch file for example locate in c:\toto1.bat – Hackoo Feb 04 '15 at 16:41