Set Windows Background via Python

写了一个python脚本来爬取bing每日壁纸, 后又希望自动设置为桌面壁纸, 写了个小程序试了一下, 工作正常. 分享下设置壁纸的代码.

Google 搜索结果中有一些结果通过写 Windows 注册表来修改桌面壁纸, 但我测试了一下似乎不工作… 所以在 MSDN 上找了 Win32 API, 用 Python 包装下就可以用了.

Windows C++ 命令行版本

这是我最开始使用的版本, 新建一个 Windows 控制台程序项目, 我不会C++, 所以用 VS 默认的 c++ 文件模板, 然后试了一下是可以的.

需要注意 VS 的项目配置:

  • 不要指定字符集, 默认使用unicode将导致程序异常
  • VC++ 代码生成: /mt 静态链接, 避免其他系统对 VC Runtime 的依赖
#include "stdafx.h"
#include <Windows.h>
#include<iostream>
using namespace std;

int main(int argc, char* argv[])
{
  if (argc != 2)
  {
    return(1);
  }

  cout << argv[1];
  SystemParametersInfo(
    SPI_SETDESKWALLPAPER,
    0,
    argv[1],
    SPIF_UPDATEINIFILE
  );
    return 0;
}

使用方法也很简单, 直接将图片的路径作为生成的程序的第一个参数即可, 或者直接将图片拖到生成的 exe 上面.

注意: 不要传递相对路径进去!

Python 版

由于不熟悉 C++ 编程, 上面的 Windows C++ 版本 bug 不少, 比如不支持相对路径, 传递的参数不进行检查等. 而且 python 调用 os.system() 来设置背景的时候, 总会有一个黑色的 conhost 一闪而过很不爽 ( 虽然可以使用 subprocess 来避免 ).

#!python3
# coding = utf-8

import ctypes
import ctypes.wintypes as wintypes
import os

def set_windows_desktop_wallpaper(fpath: str) -> bool:
    """
    set Windows Desktop Wallpaper.

    BOOL WINAPI SystemParametersInfo(
      _In_    UINT  uiAction,
      _In_    UINT  uiParam,
      _Inout_ PVOID pvParam,
      _In_    UINT  fWinIni
    )

    :param fpath: path to background image file.
    :return:
    """
    fpath = os.path.abspath(fpath)
    SPI = ctypes.windll.User32.SystemParametersInfoW
    SPI_SETDESKWALLPAPER = wintypes.UINT(0x0014)
    SPIF_UPDATEINIFILE = wintypes.UINT(0x0001)

    return SPI(SPI_SETDESKWALLPAPER, 0, fpath, SPIF_UPDATEINIFILE)


if __name__ == "__main__":
  import sys
  imgf = os.path.abspath(sys.argv[1])
  if os.path.isfile(imgf):
    set_windows_desktop_wallpaper(imgf)

使用方法也很简单, 把图片拖到这个 py 文件上, 或者在其他 python 程序中 import 这个模块并调用 set_windows_desktop_wallpaper() 函数.

下载

我编译的 C++ 二进制程序和 python 源代码可以在这里 下载.

Miguel avatar
关于 Miguel
韭菜一棵...