从 ctypes Windll 获取错误消息

问题描述 投票:0回答:2

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

缩短的脚本如下所示:

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

通常情况下,它会起作用,但有时,看似随机,却不起作用。有什么方法可以让我检索到比状态代码(0 或 1)更多的错误信息?

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

python windows python-2.7 ctypes
2个回答
5
投票

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


2
投票

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.