1

I am fairly new to python, and have no experience with writing services for windows. I have tried to hack together a windows service based on afew tutorials i have found out there.

I need this service to constantly monitor a directory for changes and when it sees a change it runs a script. Here is what i have so far:

import win32service
import win32serviceutil
import time

class aservice(win32serviceutil.ServiceFramework):
    _svc_name_ = "aservice"
    _svc_display_name_ = "aservice - It Does nothing"

    def __init__(self,args):
        win32serviceutil.ServiceFramework.__init__(self,args)
        self.isAlive = True

    def SvcDoRun(self):
        import servicemanager
        while self.isAlive:
            # This is where i am trying to run my code...is that right?
            self.main()
            #servicemanager.LogInfoMsg("aservice - is alive and well")
            #time.sleep(5)
            #servicemanager.LogInfoMsg("aservice - Stopped")

    def SvcStop(self):
        import servicemanager
        servicemanager.LogInfoMsg("aservice - Recieved stop signal")
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        self.isAlive = False #this will make SvcDoRun() break the while loop at the next iteration.

    # This code monitors a directory for changes and calls a script when there is a change
    # At the moment, it creates a log file instead of calling the script
    def main(self):
        import os
        import win32file
        import win32con
        ACTIONS = {
            1: "Created",
            2: "Deleted",
            3: "Updated",
            4: "Renamed from something",
            5: "Ranamed to something"
        }

        FILE_LIST_DIRECTORY = 0x0001

        path_to_watch = "folder"
        hDir = win32file.CreateFile (
            path_to_watch,
            FILE_LIST_DIRECTORY,
            win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
            None,
            win32con.OPEN_EXISTING,
            win32con.FILE_FLAG_BACKUP_SEMANTICS,
            None
        )
        while 1:
            results = win32file.ReadDirectoryChangesW (
                hDir,
                1024,
                True,
                win32con.FILE_NOTIFY_CHANGE_FILE_NAME |
                win32con.FILE_NOTIFY_CHANGE_DIR_NAME |
                win32con.FILE_NOTIFY_CHANGE_ATTRIBUTES |
                win32con.FILE_NOTIFY_CHANGE_SIZE |
                win32con.FILE_NOTIFY_CHANGE_LAST_WRITE |
                win32con.FILE_NOTIFY_CHANGE_SECURITY,
                None,
                None
            )
            for action, file in results:
                #import script
                log = open ('log.txt', 'w')
                full_filename = os.path.join(path_to_watch)
                log.write(full_filename + ACTIONS.get(action, "Unknown"))
                log.close()

if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(aservice)

Any ideas on what i am doing wrong?

EDIT: Here is the event log error i am getting for it.

Event Type: Error
Event Source:   aservice
Event Category: None
Event ID:   3
Date:       21/01/2010
Time:       11:27:43 AM
User:       N/A
Computer:
Description:
The instance's SvcRun() method failed 
Traceback (most recent call last):
  File "C:\Python25\Lib\site-packages\win32\lib\win32serviceutil.py", line 806, in SvcRun
    self.SvcDoRun()
  File "D:\TEST\simpleservice2.py", line 35, in SvcDoRun
    self.main()
  File "D:\TEST\simpleservice2.py", line 72, in main
    None
error: (2, 'CreateFile', 'The system cannot find the file specified.') 
%2: %3
  • 1
    What's happening? Instead of going line-by-line through code it would be helpful to have some idea of what you're seeing that you don't expect, or some sort of diagnostic details. – Michael Greene Jan 21 '10 at 01:46

2 Answers2

2

One thing to keep in mind with Windows services is that by default, they run under the LOCAL_SYSTEM account. This means that permissions to local volumes apply (LOCAL_SYSTEM can certainly be denied access to any given folder), and that LOCAL_SYSTEM does not have any access to any network volumes.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • Hi, been a while since this but do you perhaps know how to give access that isn't there in this case? I'm having some trouble as well be it might be related to LOCAL instead of to a folder path. – Yafim Simanovsky Apr 04 '23 at 06:11
1

I'm not familiar with pywin32's ServiceFramework, but based on your code and the error message, I bet you have a problem with path_to_watch.

I assume you sanitized the folder name for your example, and you're not actually looking for folder.

How about:

  • Are you using the full path to the folder? The current working directory of the service may not be what you expect.
  • Are you escaping any backslashes in the folder path?

Try using:

path_to_watch = r"c:\foo\bar" + "\\" 
J.J.
  • 5,019
  • 2
  • 28
  • 26
  • Thanks for picking up on that, in my original script for testing i did just use "folder" as the path because it was in the same directory as the python script. All i had to do was fix that up and the path for the log file! Thanks you have solved my problem :) –  Jan 21 '10 at 03:52
  • 2
    You can't ever end a string with a single backslash as it escapes the final quote. Either miss off the final slash, use forward slashes which also work on Windows, remove the r and use double backslashes or make it r"c:\foo\bar" + "\\" – Tom Viner May 12 '10 at 09:29
  • Tom, great point. Thanks. I fixed the example for All Those Who Come After. – J.J. Apr 12 '11 at 02:24