1
votes

I'm working on a simple (I thought) program to set a different desktop background for every day of the week. It runs with no errors but nothing happens. The path to the images are valid. Any ideas?

import time;
import ctypes;
SPI_SETDESKWALLPAPER = 20

localtime = time.localtime(time.time())
wkd = localtime[6]

if wkd == 6:
    ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER,0,r"C:\Users\Owner\Documents\Wallpaper\1.jpg",0)

elif wkd == 0:
    ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER,0,r"C:\Users\Owner\Documents\Wallpaper\2.jpg",0)

elif wkd == 1:
    ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER,0,r"C:\Users\Owner\Documents\Wallpaper\3.jpg",0)

elif wkd == 2:
    ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER,0,r"C:\Users\Owner\Documents\Wallpaper\4.jpg",0)

elif wkd == 3:
    ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER,0,r"C:\Users\Owner\Documents\Wallpaper\5.jpg",0)

elif wkd == 4:
    ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER,0,r"C:\Users\Owner\Documents\Wallpaper\6.jpg",0)

elif wkd == 5:
    ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER,0,r"C:\Users\Owner\Documents\Wallpaper\7.jpg",0)
3
What does SystemParametersInfo actually return? - Dolda2000
A day is a long time to wait to check code. Try running it as a loop so it calls ctypes.windll.user32.SystemParametersInfoA every couple of seconds and see if anything happens, or if it changes the background. - user764357
You need to use fWinIni=SPIF_SENDCHANGE, which is 2. This broadcasts a WM_SETTINGCHANGE message. - Eryk Sun
Just make the last argument 2 instead of 0. Read the docs. - Eryk Sun
You're using Python 3.x. It's passing a unicode (UTF-16) string. Use SystemParametersInfoW to pass a wide string. - Eryk Sun

3 Answers

4
votes

I must have read every existing site on this topic and just before giving up, came to this working code (win7 pro 64 bit, python 3.4)

import ctypes
SPI_SETDESKWALLPAPER = 0x14     #which command (20)

SPIF_UPDATEINIFILE   = 0x2 #forces instant update
src = r"D:\Downloads\_wallpapers\3D-graphics_Line_025147_.jpg" #full file location
#in python 3.4 you have to add 'r' before "path\img.jpg"

print(ctypes.windll.user32.SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, src, SPIF_UPDATEINIFILE))

It uses SystemParametersInfoW instead of SystemParametersInfoA (W instead of A).

Hope it helps you and many others who seem to have similar problems.

2
votes

If you are using Python 3 you should use ctypes.windll.user32.SystemParametersInfoW instead of ctypes.windll.user32.SystemParametersInfoA(W instead of A as this answer said). Another answer described that because in Python 3 the str type is in form of UTF-16 as wchar_t * in C.

What's more, please minimize the code like this:

import time;
import ctypes;
SPI_SETDESKWALLPAPER = 20

wallpapers = r"C:\Users\Owner\Documents\Wallpaper\%d.jpg"

localtime = time.localtime(time.time())
wkd = localtime[6]
ctypes.windll.user32.SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0, wallpapers%(wkd+1), 0)

Don't Repeat Yourself.

1
votes

This is not an answer to your question, but you can generally minify your program and remove redundancy by doing something like this instead:

import time;
import ctypes;
SPI_SETDESKWALLPAPER = 20

wallpapers = [
    r"C:\Users\Owner\Documents\Wallpaper\1.jpg",
    r"C:\Users\Owner\Documents\Wallpaper\2.jpg",
    r"C:\Users\Owner\Documents\Wallpaper\3.jpg",
    r"C:\Users\Owner\Documents\Wallpaper\4.jpg",
    r"C:\Users\Owner\Documents\Wallpaper\5.jpg",
    r"C:\Users\Owner\Documents\Wallpaper\6.jpg",
    r"C:\Users\Owner\Documents\Wallpaper\7.jpg",
]

localtime = time.localtime(time.time())
wkd = localtime[6]
ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, wallpapers[wkd], 0)