2

This is what I'm trying:

import ctypes
import os
drive = "F:\\"
folder = "Keith's Stuff"
image = "midi turmes.png"
image_path = os.path.join(drive, folder, image)
SPI_SETDESKWALLPAPER = 20 
ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, image_path, 3)

Basicaly, this code is obviously supposed to set the desktop background to midi turmes.png, it changes the desktop, however, for some odd reason, it's always a green background (my personalized settings in windows is a green background behind the image) how do I fix this and make the desktop look like this?: https://i.stack.imgur.com/MRJ1H.png

Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
  • have you tried with a JPG image instead of a PNG? – Paulo Scardine Nov 13 '16 at 14:01
  • Python 2 or 3? Also try setting argtypes and restype for the function. – Mark Tolonen Nov 13 '16 at 14:02
  • yep, i tried that. and i'm using python 3.5.2 – BadArtistKeith Nov 13 '16 at 14:26
  • I'm playing with this on the shell. The command seems to change the background to solid color, instead of using the image (you can even open the background settings next to the shell and see it change live) – yuvi Nov 13 '16 at 14:29
  • I think it has to do with Windows 10. I'm playing with the script, but it doesn't work for me either. Your code pops up on a few questions here on SO, but they all use it the same as you. Since it isn't working for me either, it's possible the Microsoft changed something in Windows 10 (maybe even the last update) – yuvi Nov 13 '16 at 14:39
  • i actually have windows 8.1, but i still want this compatible for all windows OS's – BadArtistKeith Nov 13 '16 at 18:00

1 Answers1

5

The following works for me. I'm using Windows 10 64-bit and Python 3.

import os
import ctypes
from ctypes import wintypes

drive = "c:\\"
folder = "test"
image = "midi turmes.png"
image_path = os.path.join(drive, folder, image)

SPI_SETDESKWALLPAPER  = 0x0014
SPIF_UPDATEINIFILE    = 0x0001
SPIF_SENDWININICHANGE = 0x0002

user32 = ctypes.WinDLL('user32')
SystemParametersInfo = user32.SystemParametersInfoW
SystemParametersInfo.argtypes = ctypes.c_uint,ctypes.c_uint,ctypes.c_void_p,ctypes.c_uint
SystemParametersInfo.restype = wintypes.BOOL
print(SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, image_path, SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE))

The important part is to make sure to use a Unicode string for image_path if using SystemParametersInfoW, and a byte string if using SystemParametersInfoA. Remember that in Python 3 strings are default Unicode.

It is also good practice to set argtypes and restype as well. You can even "lie" and set the third argtypes parameter to c_wchar_p for SystemParametersInfoW and then ctypes will validate that you are passing a Unicode string and not a byte string.

Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
  • 5
    Can you point to a link that would explain what the hell? I've been writing scripts to do windows things for years, but the process always feels random. I try something, it doesn't work, then I google until I find a snippet that works. When I do this with most languages I actually learn something along the way, but with the weird names, convulted methods and horrifying mess that is the Windows API Docs I just can't make any sense of it – yuvi Nov 25 '16 at 15:17
  • Now, [win32gui.SystemParametersInfo(action, param, winIn)](http://timgolden.me.uk/pywin32-docs/win32gui__SystemParametersInfo_meth.html) 3 parameters [LinkodeImageSource](https://i.stack.imgur.com/1o3GR.png) – Darshan P. Apr 09 '23 at 09:25