【问题标题】:user32.SwitchDesktop only works in debug mode - Python Windows serviceuser32.SwitchDesktop 仅在调试模式下工作 - Python Windows 服务
【发布时间】:2018-12-05 23:20:17
【问题描述】:

我正在尝试创建一个 Windows 服务(来自 Python 脚本),该服务会在用户每次锁定和解锁工作站时进行记录。

当我使用python WinLockUnlock.py debug 在调试模式下运行服务时,服务按预期工作。

但是如果我用python WinLockUnlock.py start 启动服务,result 变量 (SwitchDesktop(hDesktop)) 始终为 0。问题仅在于 user32 函数,服务写入日志文件没有任何问题。

那么,为什么 user32 的功能只能在调试模式下工作呢?

(我已经尝试使用管理员帐户运行该服务,但没有成功)

WinLockUnlock.py:

中的代码
import time
from ctypes import WinDLL
from SMWinService import SMWinService


class WinLockUnlock(SMWinService):
    _svc_name_ = 'LockUnlock'
    _svc_display_name_ = 'Lock Unlock Script'
    _svc_description_ = 'Script que registra cuando se bloquea/desbloquea la sesión del usuario'

    def start(self):
        self.isrunning = True
        self.session_status = True
        self.writemsg('Service started')

    def stop(self):
        self.isrunning = False
        self.writemsg('Service stopped')

    def main(self):
        user32 = WinDLL('user32', use_last_error=True)
        OpenDesktop = user32.OpenDesktopW
        SwitchDesktop = user32.SwitchDesktop
        DESKTOP_SWITCHDESKTOP = 0x0100
        while self.isrunning:
            hDesktop = OpenDesktop('default', 0, False, DESKTOP_SWITCHDESKTOP)
            result = SwitchDesktop(hDesktop)
            self.writemsg('Test Result: {0}'.format(result))
            if result:
                if self.session_status == False:
                    self.session_status = True
                    self.writemsg('----------UNLOCKED----------')
            else:
                if self.session_status == True:
                    self.session_status = False
                    self.writemsg('----------LOCKED----------')
            time.sleep(2)

    def writemsg(self, msg):
        _date = time.strftime('%Y-%m-%d')
        _time = time.strftime('%H:%M:%S')
        filename = 'D:/Temp/TestPython/pyserv{0}.txt'.format(_date)
        with open(filename, 'a', newline='', encoding='utf-8') as file:
            file.write('{0} {1}: {2}\r\n'.format(_date, _time, msg))


if __name__ == '__main__':
    WinLockUnlock.parse_command_line()

【问题讨论】:

  • Windows 服务可能没有适当的权限与桌面交互。
  • 我已经尝试过设置域管理员来运行服务,但是没有成功
  • 您不检查函数返回值。这导致代码可能“无缘无故”地无法工作。您是否考虑过 GetLastError 以了解有关错误的更多信息?

标签: python ctypes pywin32


【解决方案1】:

我添加了错误检查并注意到 Access denied 错误。该错误仅在我尝试OpenDesktop 并获得DESKTOP_SWITCHDESKTOP 权限时发生。 Turns out某服务无法与用户桌面交互:

...服务现在使用自己的工作站和桌面运行自己的会话...不再可能访问用户桌面。这是一项安全功能,可防止破碎攻击。

所以我将我的脚本转换为带有Pyinstaller 的 Windows 应用程序,并在 Startup 文件夹中添加了快捷方式,现在我在不使用 Windows 服务的情况下拥有相同的功能

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-25
    • 1970-01-01
    相关资源
    最近更新 更多