从ctypes windll获取错误消息

时间:2015-04-24 12:34:07

标签: python windows python-2.7 ctypes

我正在尝试使用Python脚本来更改Windows 7计算机上的壁纸。如果重要,我正在从node-webkit应用程序调用脚本。

缩短的脚本如下所示:

# ...
result = ctypes.windll.user32.SystemParametersInfoA(20, 0, path, 0)

通常,它有效,但有时,看似随机,但事实并非如此。有没有办法让我检索有关错误的更多信息而不是状态代码(0或1)?

我一直在尝试使用GetLastError,有时会提到ctypes库,但无法提取任何错误信息。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

如果您将壁纸设置为具有不受支持格式的现有文件,即使未设置壁纸,也会收到“操作已成功完成”。

这是我使用的代码,如果输入不存在的路径,则会抛出错误。如果文件存在,该函数不会抛出错误,但格式不受支持。

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来解决了这个问题。