简体   繁体   English

当程序直接运行时,更改 python 程序中的墙纸有效。 但在从服务运行时不起作用

[英]changing the wallpaper in python program works when the program is ran directly. but doesn't work when it's run from a service

I've been wanting to make a program that immediatly sets my wallpaper to 1 picture, waits 10 seconds, then sets it to the other.我一直想制作一个程序,立即将我的壁纸设置为 1 张图片,等待 10 秒,然后将其设置为另一张。

The program works just fine when running it from command prompt, or using the python interpreter.从命令提示符或使用 python 解释器运行时,该程序工作正常。 But as a service, it doesn't work.但作为一项服务,它不起作用。

I have used nssm (Non-Sucking Service Manager) to turn the script into a service.我已经使用 nssm(Non-Sucking Service Manager)将脚本变成服务。

Here's the wallpaper changing part of the code:这是代码的墙纸更改部分:

def change_wallpaper(filename):
    # Load the user32 library.
    user32 = ctypes.WinDLL('user32')

    # Set the wallpaper.
    result = user32.SystemParametersInfoW(
        win32con.SPI_SETDESKWALLPAPER, 0, filename, win32con.SPIF_UPDATEINIFILE
    )

    # Check the result.
    if not result:
        print("Failed to set wallpaper.")
    else:
        print("Successfully set wallpaper.")

I captured the I/O to a log file to find out if it had worked or not and it said "Failed to set wallpaper".我将 I/O 捕获到一个日志文件中,以确定它是否有效,但它显示“无法设置墙纸”。

So.. I'm kind of stuck.所以..我有点卡住了。 Thanks to anyone who can help.感谢任何能提供帮助的人。 :) :)


What I was expecting我所期待的

I was expecting it to change the wallpaper, then after 10 seconds change it to another.我原以为它会更改墙纸,然后在 10 秒后将其更改为另一个。

What actually happened究竟发生了什么

It reported that changing the wallpaper failed.报告更换壁纸失败。

Heads up, this is not my code.注意,这不是我的代码。 I've used a python wallpaper manager called superpaper before, and...it's a python wallpaper manager.我以前用过一个叫 superpaper 的 python 壁纸管理器,而且......它是一个 python 壁纸管理器。 The first rule of engineering is to not reinvent the wheel.工程的第一条规则是不要重新发明轮子。 Here is their project: https://github.com/hhannine/superpaper这是他们的项目: https://github.com/hhannine/superpaper

import ctypes
from typing import List
import pythoncom
import pywintypes
import win32gui
from win32com.shell import shell, shellcon
user32 = ctypes.windll.user32


def _make_filter(class_name: str, title: str):
    """https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enumwindows"""

    def enum_windows(handle: int, h_list: list):
        if not (class_name or title):
            h_list.append(handle)
        if class_name and class_name not in win32gui.GetClassName(handle):
            return True  # continue enumeration
        if title and title not in win32gui.GetWindowText(handle):
            return True  # continue enumeration
        h_list.append(handle)

    return enum_windows


def find_window_handles(parent: int = None, window_class: str = None, title: str = None) -> List[int]:
    cb = _make_filter(window_class, title)
    try:
        handle_list = []
        if parent:
            win32gui.EnumChildWindows(parent, cb, handle_list)
        else:
            win32gui.EnumWindows(cb, handle_list)
        return handle_list
    except pywintypes.error:
        return []


def force_refresh_syspar():
    user32.UpdatePerUserSystemParameters(1)


def enable_activedesktop():
    """https://stackoverflow.com/a/16351170"""
    try:
        progman = find_window_handles(window_class='Progman')[0]
        cryptic_params = (0x52c, 0, 0, 0, 500, None)
        user32.SendMessageTimeoutW(progman, *cryptic_params)
    except IndexError as e:
        raise WindowsError('Cannot enable Active Desktop') from e


def set_wallpaper_win(image_path: str, use_activedesktop: bool = True):
    if use_activedesktop:
        enable_activedesktop()
    pythoncom.CoInitialize()
    iad = pythoncom.CoCreateInstance(shell.CLSID_ActiveDesktop,
                                     None,
                                     pythoncom.CLSCTX_INPROC_SERVER,
                                     shell.IID_IActiveDesktop)
    iad.SetWallpaper(str(image_path), 0)
    iad.ApplyChanges(shellcon.AD_APPLY_ALL)
    force_refresh_syspar()

You would call it via你会通过

set_wallpaper_win('/path/to/image.png')

Another possible reason is that wallpapers are per user, and services don't necessarily run as the user.另一个可能的原因是壁纸是每个用户的,服务不一定以用户身份运行。 You want to set the service to run as the currently logged on user.您希望将服务设置为以当前登录的用户身份运行。 From NSSM's website (as of 2022-12-28):来自 NSSM 的网站(截至 2022-12-28):

Log on tab The Log on tab can be used to manage the user account which will run the service.登录选项卡 登录选项卡可用于管理将运行该服务的用户帐户。 nssm will automatically ensure that the account you choose has the necessary log on as a service permissions. nssm 将自动确保您选择的帐户具有必要的登录即服务权限。

登录设置

Equivalent commands:等效命令:

nssm set UT2003 ObjectName LocalSystem nssm set UT2003 Type SERVICE_WIN32_OWN_PROCESS Refer to the command line usage documentation for details on configuring an account and password on the command line. nssm set UT2003 ObjectName LocalSystem nssm set UT2003 Type SERVICE_WIN32_OWN_PROCESS 有关在命令行上配置帐户和密码的详细信息,请参阅命令行使用文档。 If you need to configure a blank password you must use the command line.如果需要配置空白密码,则必须使用命令行。

Additionally, it may be related to this question: Change wallpaper with service此外,它可能与这个问题有关: Change wallpaper with service

Personally, I would just choose not to make it a Windows Service, and instead opt for a tray service or background CLI application.就个人而言,我会选择不将其设为 Windows 服务,而是选择托盘服务或后台 CLI 应用程序。 You can just make a shortcut in a startup folder that will call python with the arguments to start your python script.您可以在启动文件夹中创建一个快捷方式,它将调用 python 和 arguments 以启动您的 python 脚本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 再次运行程序时,Python的pickle加载不起作用 - Python pickle load doesn't work when program is run again 通过运行打开时,python程序不起作用 - python program doesn't work when opened by run Python程序在Eclipse中工作,但在我直接运行时却没有(Unicode的东西) - Python program works in Eclipse but not when I run it directly (Unicode stuff) 从IDLE运行时,同一个程序运行良好,但直接运行时,同一个程序运行不正常 - Same Program Runs Fine when ran from IDLE but not when ran directly 从文件夹或桌面打开时,Python程序无法正确运行,但在IDLE中运行时,它可以正常运行 - Python program won't run correctly when opened from folder or desktop, but works fine when run in IDLE 通过终端运行时,Python脚本无法正常运行,但在Jupyter和Visual Studio中可以正常运行 - Python script doesn't work properly when ran through terminal, but works fine in Jupyter and Visual Studio Python Twitter bot是从解释器工作但不是作为程序运行时? - Python Twitter bot works from interpreter but not when run as program? 直接执行Python程序或从Makefile执行Python程序时找不到模块,但是使用“ python”运行时可以正常工作 - No module found when executing Python program directly or from a Makefile, but works fine when running using “python” 运行时 Python 中的程序错误(Python 2.7) - Program Error in Python When Ran (Python 2.7) 从另一个模块运行时,Python BackgroundScheduler程序崩溃 - Python BackgroundScheduler program crashing when ran from another module
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM