我正在尝试使用Python脚本来更改Windows 7计算机上的壁纸。如果重要的话,我会从 node-webkit 应用程序调用脚本。
缩短的脚本如下所示:
# ...
result = ctypes.windll.user32.SystemParametersInfoA(20, 0, path, 0)
通常情况下,它会起作用,但有时,看似随机,却不起作用。有什么方法可以让我检索到比状态代码(0 或 1)更多的错误信息?
我一直在尝试使用 GetLastError,有时在 ctypes 库中提到它,但无法提取任何错误信息。
ctypes 文档建议使用
use_last_error=True
以安全的方式捕获 GetLastError()
。请注意,您需要在引发时检索错误代码 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)
输出:
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.
所有这些工作的替代方法是使用 pywin32 并调用
win32gui.SystemsParametersInfo
。
如果您将壁纸设置为格式不受支持的现有文件,即使未设置壁纸,您也会收到“操作成功完成”。
这是我使用的代码,如果您输入不存在的路径,则会抛出错误。如果文件存在,但格式不受支持,该函数不会抛出错误。
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)
我通过在将图像设置为壁纸之前将图像转换为 .jpg 解决了这个问题。