VBS popup doesn't appear at a specific time using a loop - vbscript

I have a VBS file with the following code:
dtsnow = Now()
hours = Right("00" & Hour(dtsnow), 2)
minutes = Right("00" & Minute(dtsnow), 2)
Do
If hours > 10 And minutes > 30 Then
CreateObject("Wscript.Shell").Popup "ok", 0, "Window title"
End If
WScript.sleep 2000 'every 2 seconds
Loop
If I run the file for example at 11:31, the popup is apperaed every 2 seconds, as expected. But if I run the file e.g. at 11:30 i.e. then clock minutes are not more than 30 and then wait a few minutes, the popup doesn't appear when clock minutes are more than 30 while the loop checks the time every 2 seconds.
Why?

Related

Idle handler function is not running at the exact specified interval

The script uses idle handler that runs every 5 minutes and alerts me to perform the task. But the script always runs late by 10-40 seconds. I am not sure why that is happening.
global numberOfBeeps, beepcycle
on idle
if beepcycle is greater than 0 then
say "Update 5 minute data and watchlist " using "Serena"
set beepcycle to beepcycle - 1
else
say "Update 30 minute data and watchlist" using "Kate"
set beepcycle to 5
end if
return 300
end idle
on run
set beepcycle to 6
end run
The if statement in your script adds this 10-40 seconds to the on idle handler. So, you should correct the return time of on idle handler some way. For example, you can do something like this:
global numberOfBeeps, beepcycle
on idle
set currentDate to (get current date)
if beepcycle is greater than 0 then
say "Update 5 minute data and watchlist " using "Serena"
set beepcycle to beepcycle - 1
else
say "Update 30 minute data and watchlist" using "Kate"
set beepcycle to 5
end if
set timeElapsed to (get current date) - currentDate
return (300 - timeElapsed)
end idle
on run
set beepcycle to 6
end run

AppleScript Progress Bar with Reboot Button

I've recently been tasked with working on a project to switch antivirus software in the environment as we are changing to a new vendor. Naturally, this kind of effort will require a reboot on our endpoints once the old A/V software has been removed.
What I'm trying to do is create a reboot notification prompt for our Mac customers (since many are high up on the food chain) to let them know what we are doing.
This prompt will let them know they have 3 hours to reboot their Macs to complete the removal of the software if they are logged in. If they do not reboot within 3 hours, their workstation will automatically reboot.
Applescript has a great workflow that allows me to effectively communicate with our users, but I would like to change the Stop button to a reboot, so that our customers can reboot their Macs on demand.
I will work in logic later on to automatically reboot if they are not logged in.
I modified one of the scripts that I, "borrowed," from here
https://macscripter.net/viewtopic.php?id=46572
-- Progress Bar - Reboot Timer
progress_timer("03:00:00", "Reboot Timer") -- call the progress timer with an HMS time and timer label
return result
------------------------------------------
-- subroutines in alphabetical order --
------------------------------------------
-- getTimeConversion converts a time in HMS format (hh:mm:ss) to a time in seconds
on getTimeConversion(HMS_Time)
set HMSlist to the words of HMS_Time -- get {hh, mm, ss} from HMS time (p. 158 Rosenthal)
set theHours to item 1 of HMSlist
set theMinutes to item 2 of HMSlist
set theSeconds to item 3 of HMSlist
return round (theHours * (60 ^ 2) + theMinutes * 60 + theSeconds)
end getTimeConversion
-- progress_timer displays the elapsed time in a progress bar. For information on progress bars see: https://developer.apple.com/library/archive/documentation/LanguagesUtilities/Conceptual/MacAutomationScriptingGuide/DisplayProgress.html
on progress_timer(HMS_Time, timerLabel)
set theTimeSec to getTimeConversion(HMS_Time) -- convert the HMS format to seconds
set progress total steps to theTimeSec
set progress completed steps to 0
set startTime to (current date)
repeat with i from 0 to theTimeSec -- begin at i = 0 to start the timer at 00:00:00
set HMS_SoFar to TimetoText(i) -- convert the seconds so far to HMS format for display
set HMS_ToGo to TimetoText(theTimeSec - i) -- convert the seconds to go to HMS format for display
set progress completed steps to 0
set progress description to "
Your IT Department needs to make changes to your Mac.
Your workstation must be rebooted in order for these changes to take effect.
Your workstation will reboot in " & HMS_ToGo
set progress additional description to ¬
""
--"Time Elapsed: " & HMS_SoFar & return & ¬
--"Counting Down: " & HMS_ToGo
set progress completed steps to i
set elapsedTime to (current date) - startTime -- get actual elapsed time for adjusting delay
set lagAdjust to elapsedTime - i -- compute lag adjustment
delay 1 - lagAdjust -- delay 1 second minus any cumulative lag that needs removing
end repeat
--set HMS_Elapsed to TimetoText(elapsedTime) -- convert elapsedTime back to HMS format for display
set dialogText to null
--set dialogText to "Elapsed Time: " & return & ¬
-- "Nominal = " & HMS_Time & return & ¬
-- "Actual = " & HMS_Elapsed
tell me to activate
--display dialog dialogText with title timerLabel & " Timer"
return dialogText
end progress_timer
-- TimetoText converts a time in seconds to a time in HMS format (hh:mm:ss)
on TimetoText(theTime)
-- parameters - TheTime [integer]: the time in seconds
-- returns [text]: the time in the format hh:mm:ss
-- Nigel Garvey points out this script is only valid for parameter values up to 86399 seconds (23:59:59) and offers a solution for longer times here: https://macscripter.net/viewtopic.php?pid=134656#p134656
if (class of theTime) as text is "integer" then
set TimeString to 1000000 + 10000 * (theTime mod days div hours) -- hours
set TimeString to TimeString + 100 * (theTime mod hours div minutes) -- minutes
set TimeString to (TimeString + (theTime mod minutes)) as text -- seconds
tell TimeString to set theTime to (text -6 thru -5) & ":" & (text -4 thru -3) & ":" & (text -2 thru -1)
end if
return theTime
end TimetoText
Here's a screenshot of the resulting output.

trying to write an apple script that chimes every hour

I'm trying to write this script that chimes on every hour. I saved it as an application and selected the checkbox run after completion but it doesn't work. My code looks like this:
global chime
set chime to (path to resource "chime.mp3")
on idle
set currenthour to hours of (current date)
if currenthour = 0 then
set currenthour to 12
end if
if currenthour > 12 then
set currenthour to currenthour - 12
end if
set currentminute to minutes of (current date)
set currentsecond to seconds of (current date)
set currenttime to {currentminute, currentsecond} as text
if currenttime is "" then
repeat currenthour times
do shell script "afplay " & (quoted form of POSIX path of chime)
end repeat
end if
return 1
end idle
In a script app, the number you return from the on idle handler tells the system how long to sleep the app before the next idle invocation. You can use this set up a (loosely) accurate timer.
global chime, firstRun
on run
-- I'm not sure if this is necessary, but I always use explicit run handlers in script apps.
set chime to (path to resource "chime.mp3")
set firstRun to true
end run
on idle
set {currenthour, currentminute, currentsecond} to {hours, minutes, seconds} of (current date)
-- don't chime when the script app is activated
if not firstRun then
-- quick mathy way to retrieve the number of chimes.
set chimeCount to (currenthour + 11) mod 12 + 1
repeat chimeCount times
do shell script "afplay " & (quoted form of POSIX path of chime)
end repeat
else
set firstRun to true
end if
-- calculate the number of seconds until the next hour mark and tell app to sleep until then
return 60 * (60 - currentminute) + 60 - currentsecond
end idle

VBscript loop - Tell time every 15 minutes

I just want a file I can double-click and have Windows verbally tell me the time every 15 minutes. (Until I kill the process)
I found this tutorial for a VBscript that tells the time every hour, on the hour:
https://www.nextofwindows.com/windows-trick-how-to-make-your-computer-to-speak-out-time-at-every-hour
I couldn't get the Windows scheduler working with it for my purposes (start only when double-clicked and run every 15 minutes), and honestly, I just want a 15-minute-interval loop programmed into the script itself. (perhaps by using a Do/While loop and Sleep()?)
Another issue:
I tried adding a minutes variable so Windows would announce the minutes as well:
Dim speaks, speech
speaks = “It is ” & hour(time) & minute(time)
Set speech = CreateObject(“sapi.spvoice”)
speech.Speak speaks
However, it announces the time in an odd format this way. For example, It's currently 5:01AM, and when I run the script, Windows says "It is fifty-one." Why would it interpret 5:01 as fifty plus one? Earlier when I tested it at 4:32, it said "four hundred and thirty-two." I'd like it to just state the time in a normal 12-hour fashion.
This does 5 secs. So 60 x 15 = 900.
You need spaces between numbers if you want them parsed as individual numbers.
Set speech = CreateObject("sapi.spvoice")
Do
If Hour(Now) < 12 then
Var = Hour(Now) & " AM"
else
Var = Hour(Now) - 12 & " PM"
End If
speech.Speak Var & " and " & Minute(Now) & " minutes and " & Second(Now) & " seconds"
wscript.sleep 5
Loop

How to convert 24:00 hours to 12:00 format

I need help with my pseudocode assignment: convert 2400 hours to 12 format
Design an algorithm that will prompt for and receive the item expresses in 2400 format (e.g. 2305 Hours), convert it to 12 hour format (e.g. 11.05pm) and display sentinel time of 9999 is entered.
Prompt for hrs, mins
Get hrs, mins
DOWHILE(hrs NOT = 99) AND (mins NOT = 99) // If hrs & mins not = to 99 then it will run if not it will stop
IF (hrs = 00) THEN // midnight. 0030. It will + 12 and display 12:30am
format = am
time = hrs + 12
Display hrs, ":" , mins, format
ELSE
IF (hrs > 12) THEN // afternoon. 1630. It will – 12 and display 4:30pm
format = pm
hrs = hrs – 12
Display hrs, ":" , mins, format
ELSE
IF (hrs < 12) THEN // from midnight 0100 to 1159. It will display AM
format = am
Display hrs, ":" , mins, format
IF (hrs = 12) THEN // if format is 1230. It will display 1230PM
format = pm
Display hrs, ":" , mins, format
ENDIF
ENDIF
ENDIF
ENDIF
IF (hrs < 0) OR (hrs > 23) THEN // hrs less than 0 or more than 23 is error.
Display ‘Invalid hour input’
IF (mins < 0) OR (mins >59) THEN // mins less than 0 or more than 59 is error.
Display ‘Invalid mins input’
ENDIF
ENDIF
Prompt for hrs, mins // you prompt again , we are still in the loop until we hit 9999
Get hrs, mins
ENDDO // which stop here because it’s 9999
Am i doing correctly? Please advice. New student here! many thanks!
Well, depending upon how your professor expects your pseudocode to look like, what you have should work fine, I think. A few of the lines are a bit redundant, though. You could combine the out-of-bounds checking of the hours and minutes into one IF statement. You could then set your time variable to "am" by default, which would turn your IF - ELSE IF - ELSE to a single IF - ELSE. Oh, and not that I'm sure it matters much, but rather than using hours = hours + 12 when hours = 0, you could probably just do hours = 12. Again, what you have should work just fine, I think.
EDIT: Ah... again, not sure if this matters, but have a way to possibly terminate the program might be useful, too. Otherwise, you'll be stuck in your loop forever, it seems.
EDIT 2: Here's what I would do...
done = false
DOWHILE !done
PROMPT hours, minutes
GET hours, minutes
IF hours < 0 OR hours > 23 OR minutes < 0 OR minutes > 60
DISPLAY "Invalid Time"
ELSE
format = "AM"
IF hours > 12
format = "PM"
hours = hours - 12
ELSE IF hours == 0
hours = 12
ELSE IF hours == 12
format = "PM"
DISPLAY hours ":" minutes format
ENDIF
ENDIF
PROMPT "Are you done?"
GET done
ENDLOOP

Resources