There are two methods I know of to lock windows and "immediately" run a screensaver at the same time. The first method uses a batch file to run the screensaver. The second line of the batch file locks windows. But that line doesn't fire until after the screensaver is stopped. If a screensaver contains a way to be bypassed (some screensavers can be run in different modes such as "windowed") then a batch file to run a screensaver will not secure your machine. Another method which uses a .NET console application (command prompt program) to reset the screensaver's timeout value when windows locks and the sets it back again when windows unlocks is a secure way to lock your computer and run your screensaver right away. Using this method the screensaver automatically runs 1 minute after the computer is locked. I've created a freeware application that does just that.
To use the application first download its executable from here:
Screen Utility Download (.zip) (For any programmers who would like the source code rather than the compiled .exe, I've placed it at the very end of this article. (It's written in VB.NET 3.5 - if you'd like a C# version feel free to email me I'd be happy to help translate it.)
Here's how to set things up:
-
Unzip the file you downloaded and place the ScreenSaverUtility.exe in a "permanent" location. (Make note of where you save it.)
-
Open windows task scheduler (The easiest way to do so in windows vista is to click the "start" button and then type taskschd.msc into the "search" box and hit enter. You may be prompted for whether or not to continue by vista's user account control, if you are click "Continue".)
-
Task Scheduler lets you create folders to keep tasks sorted. This is completely optional but a good idea. So create a new folder to keep your screensaver tasks in by right clicking on the main folder and choosing "New Folder" from the menu. Repeat this process to create a folder structure to your liking.
-
Next right click the folder you'll be placing your tasks in and choose "Create Task" from the menu.
-
On the "General" tab of the create task window that opens enter a name for your task such as: "Set ScreenSaver Timeout on Windows Lock". Also make sure that the "Run only when user is logged on" radio button is selected.
-
Switch to the "Triggers" tab and click the "New" button.
In the window that opens use the drop down to set the task to run "On workstation lock" and then click the "OK" button.
-
Switch to the "Actions" tab and click the "New" button there. In the window that opens use the "Browse" button to select the "ScreenSaverUtility.exe" you unzipped earlier. In the "Add arguments (optional)" text box place a "/L" (without the quotes).
-
Laptops Only On the "Condtions" tab clear the "Power Settings" checkboxes so the script will still run when running on batteries.
-
Now repeat the same process but create a task that resets the screensaver timeout when windows unlocks. Name the task something like: "Reset ScreenSaver Timeout on Windows Unlock".
-
On the "Triggers" tab for this task set the task to run when the workstation unlocks.
-
On the "Actions" tab once again browse to the "ScreenSaverUtility.exe". But this time in the "Add arguments" text box place a: "/U 1800" Where 1800 is the number of seconds the screensaver timeout is set to. 1800 is 1/2 an hour. Change this value to whatever you'd like. If you only put in the "/U" and don't specify a time the screensaver timeout will default to 600 seconds (10 minutes).
That's it. Now when you lock your computer (the easiest way is to press the "Windows Key" + L) your chosen screensaver will start in one minute. And when you unlock your computer the screensaver's timeout will be reset back to your chosen default value.
Source Code:
Imports System.Runtime.InteropServices
Module ScreenSaverUtility
Private Const SPI_SETSCREENSAVETIMEOUT As Int32 = 15
Private Const SPI_GETSCREENSAVETIMEOUT As Int32 = 14
Private Const SPIF_UPDATEINIFILE As Int32 = &H1
Private Const SPIF_SENDWININICHANGE As Int32 = &H2
Private Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uiAction As Int32, ByVal uiParam As Int32, ByVal pvParam As Int32, ByVal fWinIni As Int32) As Int32
<Flags()> _
Private Enum SHOW_WINDOW As Integer
SW_HIDE = 0
SW_SHOWNORMAL = 1
SW_NORMAL = 1
SW_SHOWMINIMIZED = 2
SW_SHOWMAXIMIZED = 3
SW_MAXIMIZE = 3
SW_SHOWNOACTIVATE = 4
SW_SHOW = 5
SW_MINIMIZE = 6
SW_SHOWMINNOACTIVE = 7
SW_SHOWNA = 8
SW_RESTORE = 9
SW_SHOWDEFAULT = 10
SW_FORCEMINIMIZE = 11
SW_MAX = 11
End Enum
Private Declare Function ShowWindow Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal nCmdShow As SHOW_WINDOW) As Boolean
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
Sub Main()
Console.Title = "ScreenSaverUtility"
Dim LockOrUnlock As String = String.Empty
Dim ResetTime As Int32 = 600
If My.Application.CommandLineArgs.Count > 0 Then
LockOrUnlock = My.Application.CommandLineArgs(0).ToUpper().Replace("-", "/")
End If
If My.Application.CommandLineArgs.Count > 1 Then
If (Not Int32.TryParse(My.Application.CommandLineArgs(1), ResetTime)) Then
ResetTime = 600
End If
End If
If (LockOrUnlock = "/?") Then
DisplayHelp()
ElseIf (LockOrUnlock = "/L") Then
SetScreenSaverTimeout(60)
LockWorkStation()
ElseIf (LockOrUnlock = "/U") Then
SetScreenSaverTimeout(ResetTime)
Else
SetScreenSaverTimeout(600)
End If
End Sub
Public Function SetScreenSaverTimeout(ByVal timeout As Int32) As Boolean
ShowWindow(FindWindow(Nothing, Console.Title), SHOW_WINDOW.SW_HIDE)
If (timeout < 60) Or (timeout > 3600) Then Exit Function
Dim Result As Int32 = SystemParametersInfo(SPI_SETSCREENSAVETIMEOUT, timeout, 0, SPIF_UPDATEINIFILE Or SPIF_SENDWININICHANGE)
If Result = 0 Then Throw New Exception("Api return null")
End Function
<DllImport("user32.dll", SetLastError:=True)> _
Private Function LockWorkStation() As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Private Sub DisplayHelp()
Dim HelpStringBuilder As New System.Text.StringBuilder()
With HelpStringBuilder
.AppendLine()
.AppendLine("/L - Locks the computer and sets screensaver to start in 1 minute.")
.AppendLine("/U <ScreenSaverTimeOutValue> - Resets the screensaver timeout to the given value (in seconds) - Timeout defaults to 600 seconds (10 minutes) if not specified.")
.AppendLine()
.AppendLine("Use:")
.AppendLine("ScreenSaverUtility.exe /L")
.AppendLine("ScreenSaverUtility.exe /U 1800")
End With
Console.Write(HelpStringBuilder.ToString())
End Sub
End Module