Hey, Scripting Guy! How can I write a script that prevents the screensaver from coming on? Sometimes I get interrupted for a couple minutes (say I get a phone call or something) and the screensaver kicks in, which promptly locks the computer. Is there a way to keep that from happening?
— SS
Hey, SS. We hope you’ll forgive us if we seem a little distracted today. As you probably heard, Bill Gates has decided to step down as Microsoft’s Chief Software Architect. Needless to say, someone will have to replace him and, well – all modesty aside – who would be a more logical choice than the Scripting Guys? We’re expecting the phone to ring any minute now.
Ray Ozzie? No, never heard of him. Why do you ask?
Of course, seeing as how this is Microsoft (although we are thinking about changing the company name after we take over) there’s a good chance that they’ll send us an email instead of calling us. That’s why we decided to see if we could answer your question; after all, we don’t want our screensaver kicking in the moment that email arrives.
Not that it’s arrived yet, mind you. But maybe the server is having problems.
To begin with, we should point out that we had no idea whether we could find a way to keep the computer active and thus prevent the screensaver from running. But we did. And if that doesn’t sound like the perfect qualification for Chief Software Architect, well, we don’t know what does.
Here’s the script we came up with:
If LCase(Right(Wscript.FullName, 11)) = “wscript.exe” Then strPath = Wscript.ScriptFullName strCommand = “%comspec% /k cscript ” & Chr(34) & strPath & chr(34) Set objShell = CreateObject(“Wscript.Shell”) objShell.Run(strCommand) Wscript.Quit End IfDo While True Set objIE = CreateObject(“InternetExplorer.Application”) Wscript.Sleep 1000 objIE.Quit Wscript.Sleep 60000 Loop
We should note that there might be other ways to perform this task. We tried a couple things that didn’t work, then stumbled upon an approach that did work. As soon as we found something that worked, we called it good. After all, while we don’t have any idea what a Chief Software Architect actually does, we assume that someone in that position probably shouldn’t spend hours and hours looking for alternate ways to keep a screensaver from locking. That’s why we went with the first solution we came up with. If you have a better/easier way to do this, let us know.
So what exactly did we come up with? Let’s start by looking at this block of code:
If LCase(Right(Wscript.FullName, 11)) = “wscript.exe” Then strPath = Wscript.ScriptFullName strCommand = “%comspec% /k cscript ” & Chr(34) & strPath & chr(34) Set objShell = CreateObject(“Wscript.Shell”) objShell.Run(strCommand) Wscript.Quit End If
This is actually optional, but we needed a script that could run for an indefinite period of time; after all, there’s no telling how long that telephone conversation or trip to the coffee machine will take. Because we don’t know how long the script needs to run we can’t put in any code that auto-terminates the thing after say, five minutes. In turn, that means we need a quick and easy way to manually terminate the script.
And probably the quickest and easiest way to ensure that is to force the script to run in a command window under CScript.exe. After all, in that case we just need to close the command window and the script will end.
We’d like to see Ray Ozzie come up with an idea like that.
That’s why we start the script with the aforementioned block of code. That code is designed to see if the script is running under Wscript.exe (and thus not running in a command window). That’s something we check for that with this line of code:
If LCase(Right(Wscript.FullName, 11)) = “wscript.exe” Then
In case you’re wondering, the FullName property refers to the script host that the script is running under. The value of FullName will always be something like C:\Windows\System32\Cscript.exe or C:\Windows\System32\Wscript.exe. If the last 11 characters in FullName are wscript.exe then we’re running under Wscript. And we need to do something about that.
So can we change the script host after the script starts running? No, not as far as we know. However, we can do the next best thing: we can restart the script under CScript. That’s what the rest of the code block is for. In order to restart the script, we first grab the value of the ScriptFullName property and store it in a variable named strPath; if you aren’t familiar with ScriptFullName, this property holds the path to the script itself (e.g., C:\Scripts\Test.vbs). That brings us to this line of code:
strCommand = “%comspec% /k cscript ” & Chr(34) & strPath & chr(34)
What we’re doing here is constructing a command-line command that will run the current script under CScript.exe. To do that we start by calling the %comspec% /k environment variable; that will cause a command window to open and remain open (the /k is short for “keep open”). We then specify the script host – cscript – followed by a blank space. After that we insert a pair of double quotes – Chr(34) – followed by the path to the script, followed by a closing pair of double quotes. When we’re done, the variable strCommand will be equal to something along these lines:
%comspec% /k “C:\Scripts\Test.vbs”
Good question: why do we enclose the path in double quotes? Well, in this case, we don’t need to; we only have to do that if the path to the script file contains a blank space (e.g., C:\My Scripts\Test.vbs). We added the double quotes just to be on the safe side.
After we’ve put together our command-line command we then use this line of code to start a second instance of the script:
objShell.Run(strCommand)
And then we call the Quit method to terminate the first instance of the script. That leaves us with one copy of the script, a copy running under CScript.exe.
Note. What if the script already is running under CScript.exe? In that case we simply skip the initial code block altogether. |
That’s all fine and dandy, but what exactly is that script doing? Why, it’s doing this:
Do While True Set objIE = CreateObject(“InternetExplorer.Application”) Wscript.Sleep 1000 objIE.Quit Wscript.Sleep 60000 Loop
What we’ve done here is set up an endless loop, ensuring that the script will run forever and ever. (Or at least until you close the command window.) Inside that loop we create an instance of the InternetExplorer.Application object, an instance we never actually show on screen. After that we call the Sleep method, pausing the script for 1 second (1000 milliseconds). We then immediately terminate our instance of Internet Explorer, pause the script for 60 seconds (60000 milliseconds) and then repeat the process all over again, ad infinitum.
Note. There’s nothing magical abut the 60-second pause; we used that because we had our screensaver timeout set for 2 minutes and we needed to make sure we had some activity before those 2 minutes expired. If you have your screensaver timeout set to a higher value then you can pause a correspondingly-longer time before creating the next instance of Internet Explorer. |
Yes, it’s a crazy idea, but it works: the screensaver stays off and, as an added bonus, nothing else pops up on the screen, either. If you add a shortcut to your Quick Launch taskbar you can invoke this script with a single mouse click. And then, of course, to end the script all you have to do is close the command window. Pretty sweet.
So there you have it, SS. Now, we were wondering if you could do us a favor? Could you give us a call here at the office? We suspect that our phones must not be working. After all, that’s the only reasonable explanation we could come up with as to why no one has called us yet.
0 comments