Jump to content
matty45

Unable to change desktop wallpaper (Windows 7 Pro)

Recommended Posts

matty45

Hi, i have tried to use many scripts to change a pcs wallpaper but they dont work.

This script sets the wallpaper but does not refresh it.  Any idea what the problem is?

#include <SendMessage.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <Misc.au3>
#RequireAdmin

$UrlDownload = "http://examplesite.org/test.bmp" ;DL link
$Directory = "C:\test.bmp"      ;Name of your file

Local $download = InetGet($UrlDownload, $Directory,0,1) ; download in the background
Do
Sleep(100)
Until InetGetInfo($download, 2) ;Checks to see if $download is completed (param 2)
InetClose($download)
RunWait($Directory)  ;it will pause the script untill the process of the downloaded file is finished

RegWrite ("HKEY_CURRENT_USER\Control Panel\Desktop", "wallpaper", "REG_SZ", "C:\test.bmp" )

Dim $hWnd = WinGetHandle('[CLASS:Progman]')
_SendMessage($hWnd, $WM_COMMAND, 0x0001A220)

Thanks

Matthew

Edited by matty45

Share this post


Link to post
Share on other sites
Tripredacus

It is because you are writing it to the registry. With this method you need to restart the explorer.exe process. Any script I have done where I am making changes to the theme like that, I always restart the computer.

There is another way to do it, but I did not spend enough time to make it be "nice." One is you save your image file to wherever. Then you make a new or modify an existing .theme file and put in the wallpaper path there. Then you load the theme. If you simply shellexecute the file, it will load everything in it, but it will open the Personalize window.

The other method is to use the API call that Windows normally uses to set the wallpaper, for example if you were to set something from a browser context menu. I never got this to work but I didn't spend enough time on it.

Share this post


Link to post
Share on other sites
rudi

Hi.

You can try to ProcessClose() all instances of explorer.exe, then start explorer.exe again.

Note:

The first instance of Explorer.exe is "the desktop". Maybe it's "re-reading" it's environment, when you restart it. (Pls. test yourself)

 

Note 2:

For Windows 7, there is a solution to plainly force "the desktop" to reload it's environment, including Env-Variables and all the registry keys like that one you are using. I used it few years ago, worked fine. Unfortunately I didn't note howto, and I cannot find the posting again describing how to do so (possibly some rundll32.exe <params>)


Earth is flat, pigs can fly, and Nuclear Power is SAFE!

Share this post


Link to post
Share on other sites
rudi

Hi.

Possibly this could do the trick :D

 

Nothing in WIndows should ever be that hard.

The following has always been the preferred method for refreshing the wallpapaer. Try it.

In PowerShell:

set-itemproperty HKCU:\'Control Panel\Desktop'  Wallpaper 'c:\windows\Coffee Bean.bmp'
RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters ,1 ,True

In batch.

reg add "HKCU\Control Panel\Desktop" /v WallPaper /d "c:\windows\Coffee Bean.bmp" /f
RUNDLL32.EXE USER32.DLL,UpdatePerUserSystemParameters ,1 ,True

 

or that one:

You could try broadcasting a WM_SETTINGCHANGE message. For example:

class Program
{
    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr SendMessageTimeout(IntPtr hWnd, int Msg, IntPtr wParam, string lParam, uint fuFlags, uint uTimeout, IntPtr lpdwResult);

    private static readonly IntPtr HWND_BROADCAST = new IntPtr(0xffff);
    private const int WM_SETTINGCHANGE = 0x1a;
    private const int SMTO_ABORTIFHUNG = 0x0002;

    static void Main(string[] args)
    {
        SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, IntPtr.Zero, null, SMTO_ABORTIFHUNG, 100, IntPtr.Zero);
    }
}

 

 

Regards, Rudi.

Edited by rudi

Earth is flat, pigs can fly, and Nuclear Power is SAFE!

Share this post


Link to post
Share on other sites
matty45

Its ok, I managed to solve it in vbs

Here is the code if your curious:

If WScript.Arguments.Named.Exists("elevated") = False Then
  CreateObject("Shell.Application").ShellExecute "wscript.exe", """" & WScript.ScriptFullName & """ /elevated", "", "runas", 1
  WScript.Quit
End If
User = CreateObject("WScript.Shell").ExpandEnvironmentStrings("%UserProfile%")
dim Key, fso, Eater
Set Key = CreateObject("WScript.Shell")
Set fso = CreateObject("Scripting.FileSystemObject")
Set oSHApp = CreateObject("Shell.Application")
Set Eater = fso.GetFile(Wscript.ScriptFullName)

DownPic
DownChanger
DownBat
ChangeWall
CleanUp

Sub DownPic
dim xHttp, bStrm
Set xHttp = createobject("Microsoft.XMLHTTP")
Set bStrm = createobject("Adodb.Stream")
 xHttp.Open "GET", "http://whatever.com/test.bmp", False
 xHttp.Send

 with bStrm
 .type = 1
 .open
.write xHttp.responseBody
 .savetofile "C:\8ydfdsE.bmp", 2
End With
End Sub

Sub DownChanger
dim xHttp, bStrm
Set xHttp = createobject("Microsoft.XMLHTTP")
Set bStrm = createobject("Adodb.Stream")
 xHttp.Open "GET", "http://matthewsstuff.altervista.org/wallpaperchanger/WallpaperChanger.exe", False
 xHttp.Send

 with bStrm
 .type = 1
 .open
.write xHttp.responseBody
 .savetofile "C:\wpc.exe", 2
End With
End Sub

Sub DownBat
dim xHttp, bStrm
Set xHttp = createobject("Microsoft.XMLHTTP")
Set bStrm = createobject("Adodb.Stream")
 xHttp.Open "GET", "http://matthewsstuff.altervista.org/wallpaperchanger/wpc.bat", False
 xHttp.Send

 with bStrm
 .type = 1
 .open
.write xHttp.responseBody
 .savetofile "C:\wpce.bat", 2
End With
End Sub

Sub ChangeWall
Set rchange = CreateObject ("Wscript.Shell") 
Dim Silent
Silent = "cmd /c C:\wpce.bat"
rchange.Run Silent, 0, false
End Sub

Sub CleanUp
WScript.Sleep 5000
Dim deleter
Set deleter = CreateObject("Scripting.FileSystemObject")
deleter.DeleteFile "C:\8ydfdsE.bmp", True
deleter.DeleteFile "C:\wpce.bat", True
deleter.DeleteFile "C:\wpc.exe", True
End Sub

Thanks for the help

Edited by matty45

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • MMedina
      By MMedina
      Hello all, 
      Been looking for and playing around with a script that would prompt me for a UserName and Password then Map a network drive.
      I have included the code: 
      #AutoIt3Wrapper_icon=your_icon.ico #AutoIt3Wrapper_Run_Obfuscator=y #obfuscator_parameters=/striponly #NoTrayIcon #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> $Form1 = GUICreate("Connect To Your Drive", 265, 135) $username_id = GUICtrlCreateInput("", 88, 16, 153, 21) $password_id = GUICtrlCreateInput("", 87, 44, 153, 21, $ES_PASSWORD) GUICtrlCreateLabel("&Username", 24, 16, 52, 17) GUICtrlCreateLabel("&Password", 26, 46, 50, 17) $connect = GUICtrlCreateButton("&Connect", 24, 80, 217, 33, BitOr($GUI_SS_DEFAULT_BUTTON, $BS_DEFPUSHBUTTON)) GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $connect $username = GUICtrlRead($username_id) $password = GUICtrlRead($password_id) If $username = '' Or $password = '' Then MsgBox(16, 'Error', 'Empty username or password') ContinueLoop EndIf If DriveMapGet("X:") <> '' Then ; very fast MsgBox(16, 'Error', 'The device is already assigned') ContinueLoop EndIf GUISetCursor(15,1) DriveMapAdd("X:", "\\Server\share\filestore\" & $username, 0, $username, $password) ; slow If @error Then Switch @error Case 1 $err_message = 'Undefined / Other error. Windows API return code: ' & @extended Case 2 $err_message = 'Access to the remote share was denied' Case 3 $err_message = 'The device is already assigned' Case 4 $err_message = 'Invalid device name' Case 5 $err_message = 'Invalid remote share' Case 6 $err_message = 'Invalid password' EndSwitch GUISetCursor(2) MsgBox(16, 'Error', $err_message) Else ; everything OK Exit EndIf EndSwitch WEnd  
      When I attempt the build I get the following:
       Obfuscator support has been discontinued and is replaced by Au3Stripper using "#Au3Stripper_" directives.
      ! The directive to run Au3Stripper is: #AutoIt3Wrapper_Run_Au3Stripper=y  ; Default is n
      ! #Au3Stripper_Parameters options are: 
      /pe  : Replace and reference to a Global Const variable with its actual value.
      /tl  : Create Au3Stripper.Log with a trace of all actions.
      /debug: add Debug information to Au3Stripper.Log.
      /so : This is the default when no parameters are provided. same as /sf + /sv
      /sf : Strip all unused Func's
      /sv : Strip all unused Global var records.
      /mo : Just merges the Include files into the source and strips the Comments.
            This is similar to aut2exe and helps finding the errorline.
      /mi : Sets the maximum Iterations Au3Stripper will perform. Default is 5.
      /rm : Rename Variables and Functions to a shorter name.
      /rsln: Replace @ScriptLineNumber with the actual line number.
      /Beta: Use Beta Includes.
      - Icon not found:  your_icon.ico ==> Changing to default ICON.
      >Running AU3Check (3.3.14.5)  from:C:\Program Files (x86)\AutoIt3  input:C:\Users\Migue\Documents\Sync\Batches and Scripts\WDW-Scripts\SMS.au3
      +>18:28:11 AU3Check ended.rc:0
      >Running Au3Stripper (18.708.1148.0)  from:C:\Program Files (x86)\AutoIt3\SciTE\Au3Stripper cmdline:
      - 0.22 Iteration 1 Strip Functions result: Output  1050 lines, stripped 0 Func lines and 234 Commentlines
      - 0.61 Iteration 2 Strip Variables result: Output  88 lines and stripped 962 lines
      - 0.63 Iteration 3 Strip Variables result: Output  58 lines and stripped 30 lines
      - 0.64 Iteration 4 Strip Variables result: Output  52 lines and stripped 6 lines
      - 0.66 Iteration 5 Strip Variables result: Output  51 lines and stripped 1 lines
      +> Source    1285 lines 48435 Characters.
      +> Stripped  999 Func/Var lines and  234 comment lines, Total 46893 Characters.
      +> Saved     95% lines 96% Characters.
      +> Au3Stripper v18.708.1148.0 finished created:C:\Users\Migue\Documents\Sync\Batches and Scripts\WDW-Scripts\SMS_stripped.au3
      +>18:28:12 Au3Stripper ended.rc:0
      >Running AU3Check (3.3.14.5)  from:C:\Program Files (x86)\AutoIt3  input:C:\Users\Migue\Documents\Sync\Batches and Scripts\WDW-Scripts\SMS_stripped.au3
      +>18:28:12 AU3Check ended.rc:0
      >Running:(3.3.14.5):C:\Program Files (x86)\AutoIt3\aut2exe\aut2exe.exe  /in "C:\Users\Migue\Documents\Sync\Batches and Scripts\WDW-Scripts\SMS_stripped.au3" /out "C:\Users\Migue\AppData\Local\AutoIt v3\Aut2exe\~AU495C.tmp.exe" /nopack /comp 2
      +>18:28:13 Aut2exe.exe ended.C:\Users\Migue\AppData\Local\AutoIt v3\Aut2exe\~AU495C.tmp.exe. rc:0
      !>18:28:13 Problem copying file from: C:\Users\Migue\AppData\Local\AutoIt v3\Aut2exe\~AU495C.tmp.exe To :C:\Users\Migue\Documents\Sync\Batches and Scripts\WDW-Scripts\SMS.exe
      +>18:28:14 AutoIt3Wrapper Finished.
      >Exit code: 0    Time: 3.046
       
      When I attempt to run the executable I get the following:

      Many thanks in advance
    • ammaul
      By ammaul
      Hi folks, I'm having problems with a screenshot capture script.
      Let me explain.
      Everyday I (and my colleagues at work) need to take some screenshots from a web-page. These screenshots are used to compile a report. Normally, I (and others) used to log in into the website and took screenshots of desired graphics and tables. This is tediuos and time consuming. To easy this task I made a script using autoit that basically logs into the website (user and password) and using some clicks, stroke send, coordinates, it is able to generate the graphics and save them to some folders into our network (this script saves arouund 50 pics. It works like a sharm.
      In order to make things easier, I tried to schedule this script (compiled to a Screnpics.exe file) using task scheduler from windows. We already use this (task scheduler) to run some vbs scripts, some vba excel scripts and so on. The computer used for this tasks is a windows 7 desktop computer. Due to security policies, the computer locks after some time. All this tasks run in the locked computer.
      My script screenpics.exe runs also from this locked computer. When the computer is unlocked, it does everything as expected. But, when it is locked, all the "pics" are BLACK. As I understand, it runs ok, but, as the "windows" are innactive, it prints what it "sees": a black rectangular.
      Some details: The web-page with hold the information I need, it only works in Firefox and, because of this it couldn`t be managed by vba or some "getobject" like commands. In fact, it has some flash things that make it impossible to control programatically. So my script is based on mouse move to coordinates, mouse click, screen capture and so one.
       
      So, I read many posts trying to figure out a way to overcome this, but... nothing came to mind. My first idea was try to unlock windows. Theses lead me to some posts with no solution. This is worse because I'm not a computer admin, so procedures that need to replace/change the register are not an option.
       
      If someone has any idea, I'll be gratefull.
    • therks
      By therks
      Has anybody else noticed that Windows 7 reacts ignorantly when you use the Windows key + arrow key shortcuts on a GUI with GUIEventMode set to 1? I discovered this recently when I was working on an app where I wanted complete control over the maximize/minimize buttons.
      Just give it a spin:
      #include <GUIConstants.au3> Opt('GUIEventOptions', 1) $hGUI = GUICreate('', 300, 200, Default, Default, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX)) GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_MAXIMIZE ToolTip('Maximized') Case $GUI_EVENT_MINIMIZE ToolTip('Minimized') Case $GUI_EVENT_RESTORE ToolTip('Restored') Case $GUI_EVENT_CLOSE Exit EndSwitch WEnd Run that, then hit Win+Up or Win+Down. None of those events get triggered, and it still maximizes/minimizes. Although I can't get it to restore down from a maximize unless the window is also resizable ($WS_THICKFRAME in the style).
      Is there a way to stop Windows from doing what it wants or is the only option to check with WinGetState() and then change it back?
       
      Windows 10 seems to respect my settings, and I don't have any other versions to test on.
    • msd1994
      By msd1994
      I have a script that just adds some keyboard shortcuts for things like displaying the current song and artist, moving the window to the side so it won't pop up in my way, and play/pause, next song, previous song (these are the only 3 to still work since they don't need the window handle.)
      In some update recently, Spotify's window class swapped from "[CLASS:SpotifyMainWindow]" to "[CLASS:Chrome_WidgetWin_0]". Using the new class in my controls doesn't seem to work, I've tried getting the window handle from the process handle (_GetHwndFromPID($PID)) but that seems to fail as well.
      Does anybody have some idea of a way I could get this script working again?
       
      edit: seems like discord has the same window class name, so could be some issue with this? Still not sure of a way to solve the issue though, I added a function to get the handle of the active window and can just use that now, but it was able to find it on its own before on spotify startup or script startup which would be preferred.
       
      Thanks!
    • steveeye
      By steveeye
      hey, can anybody enlighten on lesser known Windows hacks or uses ?
×