I have a code that will automatically open the Personalization window, change the theme to Windows 7 Basic, and then close the window. The problem is, the window does not close after the run command is completed. The code I'm using is this:
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "rundll32.exe %SystemRoot%\system32\shell32.dll,Control_RunDLL %SystemRoot%\system32\desk.cpl desk,@Themes /Action:OpenTheme /file:""C:\Windows\Resources\Ease of Access Themes\basic.theme""",1,true
WshShell.AppActivate("Desktop Properties")
WshShell.Sendkeys "%FC"
WshShell.Sendkeys "{F4}"
Now, with the "true" statement at the end, isn't it supposed to basically wait for this command to complete, and THEN it will move on? Because if I remove the "true" statement as well as the "1" at the end, and instead add in a timer such as:
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "rundll32.exe %SystemRoot%\system32\shell32.dll,Control_RunDLL %SystemRoot%\system32\desk.cpl desk,@Themes /Action:OpenTheme /file:""C:\Windows\Resources\Ease of Access Themes\basic.theme"""
Wscript.Sleep 5000
WshShell.AppActivate("Desktop Properties")
WshShell.Sendkeys "%FC"
WshShell.Sendkeys "{F4}"
Only here it will wait for the task to complete, and then close the window. What am I doing wrong! Also, can someone explain exactly what the "%FC" and "{F4}" do? I know one of them closes the window but I'm having trouble finding exactly what they mean. Thank you in advance!!
I wish i knew the real reason for it but it seems that the script is working by design. RunDll32.exe must be passing off processing to another process which is why the script appears to continue without waiting. I updated the script to prove what was happening
Set WshShell = WScript.CreateObject("WScript.Shell")
msgbox (IsProcessRunning("rundll32.exe"))
WshShell.Run "rundll32.exe %SystemRoot%\system32\shell32.dll,Control_RunDLL %SystemRoot%\system32\desk.cpl desk,@Themes /Action:OpenTheme /file:""C:\Windows\Resources\Ease of Access Themes\basic.theme""",1,true
msgbox (IsProcessRunning("rundll32.exe"))
WshShell.AppActivate("Desktop Properties")
WshShell.Sendkeys "%FC"
WshShell.Sendkeys "{F4}"
Function IsProcessRunning(pProcessName)
' Function will do a WMI query to determine if a the process pProcessName is currently
' running on the local computer. Returns True if detected.
Dim objWMIService
Dim strWMIQuery
strWMIQuery = "Select * From Win32_Process Where name Like '" & pProcessName & "'"
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
' Run The query against the WMI for the local machine
If (objWMIService.ExecQuery(strWMIQuery).Count > 0) Then
IsProcessRunning = True
Else
IsProcessRunning = False
End If
End Function
I added a function that checks if a process is running. Once before your command to prove it is not already running. After the rundll32.exe call to also prove it is still not running. While this might seem redundant to show the second False message box will appear before the proccessing of the theme change is complete.
Snippet from an old MS KB article: http://support.microsoft.com/kb/164787
How Rundll Works
Rundll performs the following steps:
1. It parses the command line.
2. It loads the specified DLL via LoadLibrary().
3. It obtains the address of the function via GetProcAddress().
4. It calls the function, passing the command line tail which is the .
5. When the function returns, Rundll.exe unloads the DLL and exits.
Hopefully someone can embellish this.