I am getting an AppleEvent timed out error when my Applescript is running and the screensaver turns on and locks the screen. The applescript completes the current operation and when trying to do the next Finder operation it does not proceed but waits and times out.
I cannot increase the time-out time limit since I will not unlock the screen at all. Is there a way to ignore waiting for the screen unlock or some other solution to this?
Thanks in advance.
The best answer I have received (from macscripter.net) is to use shell commands instead of Finder commands to avoid this timeout.
I don't know how you could bypass the locked screen so your code keeps working, however you might use an if statement such that when the screen saver is running then your code isn't executed. That would at least prevent the timeout error. For example suppose you wanted to run a repeat loop 10 times for some reason, and you wanted not to run some code when the screen saver is running... you could do this.
set i to 0
repeat
set screenSaverEngineIsRunning to false
tell application "System Events"
if (exists process "ScreenSaverEngine") then set screenSaverEngineIsRunning to true
end tell
if not screenSaverEngineIsRunning then
set i to i + 1
-- do some code here
end if
delay 1
if i is 10 then exit repeat
end repeat
http://www.macupdate.com/app/mac/10387/sleepwatcher
I just did a test using Python + Appscript to do my scripting rather than Applescript and it continued to run without trouble on my system when either the user was suspended (i.e. going to the login window but with the user still logged in) or if the screen save was running. It was a simple script but presumably demonstrates what you needed to do.
Appscript comes with ASTranslate which translates Applescript calls into the equivalent Python + Appscript call. It doesn't handle variables but typically you can do a little cutting and pasting to figure out how to convert your script. It really goes quick and Python is a vastly superior language to script in than Applescript.
#!/usr/bin/python
import sys, os
from appscript import *
import time
def gettodos():
cs = app(u'iCal').calendars.get()
for c in cs:
print c.name()
tds = c.todos()
for t in tds:
print " ", t.summary()
def test():
for i in range(1,1000):
print
print "Run # " + str(i)
print
gettodos()
time.sleep(10)
if __name__ == '__main__':
test()
# change to 0 for success, 1 for (partial) failure
sys.exit(0)
I cannot reproduce your problem. I tried the following script and it worked fine even when the screensaver was running.
delay 10
tell application "Finder"
name of startup disk
end tell
delay 5
tell application "Finder"
contents of startup disk
end tell
The problem must depend on the specific commands your script is executing. What are they?
Related
Using windows cmd I have to put large programs on compilation which take large amount of time. Everytime to know whether operation is complete or not I have to check cmd again and again. I want to know whether there is way by which I can make changes to cmd such that it gives me a signal that operation has been completed by playing sound or by opening a dialog etc.
Please share if anyone has some idea
There can be many ways to achieve this
This is the easiest
While your code is compiling (ie compiling has just began) in the same cmd prompt
type " ctrl + G " and press enter this will go to the input stream of cmd and will wait there until it can be executed , ctrl +G is the BEL character which gives you a single beep when you execute it .
You can also enter multiple BEL characters to get multiple beeps upon completion of the task.
A harder way could be , to write a python script that executes the compilation command say "g++ my_prog.cpp" and upon completion plays a sound or give you a simple popup notification via a windows message box.
Include in yout batch file
msg console /time:3600 "The task has ended"
Send a message to the console and keep it open (if not closed by the user) 3600 seconds (if not indicated there is a 60 seconds timeout).
I have a VBScript I am working on that uses another object.
Sometimes that Object will get stuck. My VBScript code will hang on that line until it's "done". When it times out, I want to send the .Close command to the Object before the VBScript closes.
How can I tell when my VBScript times out?
I know that I can put WScript.Timeout = 60
Maybe something like..
WScript.Timeout = 5
do while true
loop
sub WScript_timeout()
msgbox("OK")
end sub
By setting the Timeout property you instruct the interpreter to automatically terminate the script when the timer expires. This is the same as running the interpreter with the option //T:xx and can't be caught/handled from within the script. What you want requires the ability to run code asynchronously, and VBScript doesn't really support that.
The real answer (to the question "How can I tell when my VBScript times out?") is that you can't. In common with almost all scripts, if VBScript stops running (because it's timed-out) the running thread ceases to run, so it can't report its status.
But there is a solution. However, it requires some cunning.
If you run a batch script instead, wherever you use that script to launch a new batch script (e.g. batch_1.bat includes this line: CALL batch_2.bat), the 2nd script will run, but the 1st script will wait.
Processing of the 1st script sits and waits (at the CALL) until script 2 stops running: at that point, control is returned to script 1, which continues with any code following the CALL, code which might be used to report the fact that script 2 has ended -
CALL batch_2.bat
ECHO The batch_2.bat script has stopped running && cmd /k
There are ways of launching batch_2.bat without causing batch_1.bat to pause until the 2nd script has finished, but they are not relevent here.
Theoretically, a batch script doesn't support parallel processing. VBScript certainly doesn't either. But the foregoing technique shows one method whereby parallel processing can be achieved, after a fashion, in a batch script -- which makes it one-up on vbScript!
.
One way to be certain that vbScript will time out, if the script hangs, so that the script must either complete successfully or fail (so you are never left with a frozen script due to it "hanging"), is to use a WScript function in your .vbs file and set the Windows Script Host settings to time out after (say) 30 seconds -
A. Open the "Windows Script Host Settings" dialog box:
Go to: Start > Run
In the "Open" box, type: WSCRIPT
Click "OK".
B. Set a timeout, to occur whenever WSH runs:
Select the option: "Stop script after specified
number of seconds".
In the "seconds" box, type the time limit to be
applied to all scripts (default is 10 seconds).
.
Here's a function to find and show what the current WSH/WScript timeout setting is (and if it shows that this setting hasn't been set yet, set it) -
WScript.Echo("WSH timeout: " + WScript.Timeout);
.
The option //T:xx can't be used, because it's a CScript function, which doesn't work in WScript, so can't be used in a .vbs vbScript file.
.
If you could give my a hand that would be great?
I have a HTA file nothing to fancy its to install a few programs one by one
I have been reading in a few places on how to wait for installation to complete
then install the next program but none make sense to me for what i want, also
they are saying to use wscript.sleep that would be great but it doesnt work in a HTA right ?
I have firefox, utorrent, symantec antivirus, adobe reader, office 2003 (packaged with KEY already)
and a few others.
i want to find switches to install silently but thats not important if this code someone is willing to show me works...
I hope I make sense ?
If you can help me it would be great ?
Cheers Pavle.
You might find something useful in my answer (https://stackoverflow.com/a/3742182/128427) to this question: How to get an HTA to restart itself?
It uses a VBScript helper to wait for a process to end (the HTA itself) then restarts the HTA. You could modify the vbscript instead to wait for a specific process to end (one of your installers), then return control to the HTA which starts the next installer and calls the wait script again.
I don't think an HTA can call the WScript.Sleep routine, but there are the setTimeout and setInterval methods in HTA that call a routine after X seconds, or repeatedly call a routine after every X seconds until cancelled. You can use these to check periodically if a process is still running (using WMI Win32_Process as I show in my other answer).
To process a list of items like this, instead of using a loop to go through a list and pause after each item, you have a central state-machine routine that calls itself every so often to advance the system.
'!! extremely "pseudo" pseudo-code follows
sub StartSystem()
state = "next program"
list = list of programs to install
AdvanceSystem()
end sub
sub AdvanceSystem()
if state = "next program"
if more items in list
start next installer
remove from list (or increment an index)
set state to "check program"
else
set state to "done"
if state = "check program"
use WMI to see if process is still running
if no
state = "next program"
if state <> "done"
setInterval(AdvanceSystem, 5000) ' call again in 5 seconds
end sub
' then somewhere in your HTA interface have a button to start things off
buttonClick = StartSystem()
Using an arrangement like this you may not even need to run a separate VBScript to check the process and sleep. Also, with this kind of incremental process, you can send output to a DIV somewhere so the user can see progress, whereas when processing things in a loop, output doesn't show up until the whole process has finished. After each pass through AdvanceSystem, the control returns to the HTA level and the system can update itself.
Let me know if you need a more specific example, I'll try to write something up.
There is an screensaver that will launch scripts in OS X - which is great, but the problem I am having is that it launches multiple copies of the script. Is there a simple way to ensure that only one copy of this script is running at a time?
John Gruber wrote a post on something very similar to this a while back. Long story short, you would just wrap the entire thing in a block similar to the following:
tell application "System Events"
count (every process whose name is "BBEdit")
end tell
replacing "BBEdit" with your app name, and then launch only if the count is 0.
System Events has the virtue of being very flexible, intuitive and universal (i.e. it works whether the application has scripting support or not) but it feels wrong to make important scripts that aren't fat-finger-proof. Is there any way to block user input either all or part of the time a script is running? How would it be done in the script below?
tell application "System Events"
keystroke "Please! "
delay 1
keystroke "I need your help. "
delay 1
keystroke "My kludgy nature annoys my maker. "
delay 1
keystroke "I must learn how to work without interference!"
delay 1
end tell
An experienced applescript guy --StefanK at the macscripter forum-- told me this was impossible.