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