Freddy Garcia Cala
Freddy Garcia Cala

Reputation: 414

user32.SwitchDesktop only works in debug mode - Python Windows service

I'm trying to create a Windows Service (from a Python script) that logs everytime the user locks and unlocks the workstation.

When I run the service in debug mode with python WinLockUnlock.py debug the service works as expected.

But if I start the service with python WinLockUnlock.py start The result variable (SwitchDesktop(hDesktop)) is always 0. The problem is only with the user32 functions, the service writes to the log file without any problem.

So, why the functions of user32 only work in debug mode?

(I already tried running the service with an administrator account but that didn't work)

The code in 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()

Upvotes: 1

Views: 611

Answers (1)

Freddy Garcia Cala
Freddy Garcia Cala

Reputation: 414

I added the error check and noticed an Access denied error. The error only occurred when I tried to OpenDesktop with the permission DESKTOP_SWITCHDESKTOP. Turns out a service can't interact with the user's desktop:

... Services now run their own session with their own workstation and desktop ... Getting access to the user desktop is no longer possible. It is a security feature, it prevents shatter attacks.

So I turned my script to a Windows application with Pyinstaller and added the shortcut in the Startup folder, now I have the same functionality without using a Windows service

Upvotes: 1

Related Questions