I'm trying to use a Python script to change the wallpaper on a windows 7 computer. If it matters, I'm invoking the script from a node-webkit application.
The shortened script looks as follows:
# ...
result = ctypes.windll.user32.SystemParametersInfoA(20, 0, path, 0)
Often, it works, but sometimes, seemingly randomly, it does not. Is there any way for me to retrieve more info about the error than the status code (0 or 1)?
I've been trying to use GetLastError which is sometimes mentioned in relation to the ctypes library, but have been unable to extract any error information.
The ctypes documentation recommends using use_last_error=True to capture GetLastError() in a safe way. Note you need to retrieve the error code when raising WinError:
from ctypes import *
SPI_SETDESKWALLPAPER = 0x0014
SPIF_SENDCHANGE = 2
SPIF_UPDATEINIFILE = 1
def errcheck(result, func, args):
if not result:
raise WinError(get_last_error())
user32 = WinDLL('user32',use_last_error=True)
SystemParametersInfo = user32.SystemParametersInfoW
SystemParametersInfo.argtypes = c_uint, c_uint, c_void_p, c_uint
SystemParametersInfo.restype = c_int
SystemParametersInfo.errcheck = errcheck
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, r'xxx', SPIF_UPDATEINIFILE | SPIF_SENDCHANGE)
Output:
Traceback (most recent call last):
File "C:\test.py", line 17, in <module>
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, r'c:\xxx', SPIF_UPDATEINIFILE | SPIF_SENDCHANGE)
File "C:\test.py", line 9, in errcheck
raise WinError(get_last_error())
FileNotFoundError: [WinError 2] The system cannot find the file specified.
An alternative to all this work is to use pywin32 and call win32gui.SystemsParametersInfo.
If you set the wallpaper to an existing file with an unsupported format you receive "The operation completed successfully" even though the wallpaper was not set.
Here is the code I used, which throws an error if you enter a path which does not exist. The function does not throw an error if the file exists, but the format is unsupported.
import ctypes, os, sys
from ctypes import WinError, c_int, WINFUNCTYPE, windll
from ctypes.wintypes import BOOL, HWND, LPCSTR, UINT
path = os.path.abspath(os.path.join(os.getcwd(), sys.argv[1]))
SPIF_SENDCHANGE = 2
SPIF_UPDATEINIFILE = 1
prototype = WINFUNCTYPE(BOOL, UINT, UINT, LPCSTR, UINT)
paramflags = (1, "SPI", 20), (1, "zero", 0), (1, "path", "test"), (1, "flags", 0)
SetWallpaperHandle = prototype(("SystemParametersInfoA", windll.user32), paramflags)
def errcheck (result, func, args):
if result == 0:
raise WinError()
return result
SetWallpaperHandle.errcheck = errcheck
try:
i = SetWallpaperHandle(path=str(path), flags=(SPIF_UPDATEINIFILE | SPIF_SENDCHANGE))
print(i)
except Exception as e:
print(e)
I solved the problem by converting images to .jpg before setting them as a wallpaper.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With