I'm trying to create a windows service by using the code below. The global variables are defined, and the imports are properly imported. The main bulk of the code is:
class MyHandler(FileSystemEventHandler):
def __init__(self):
self.changed_files = {}
def on_any_event(self, event):
if event.is_directory or event.event_type == 'modified':
root, dirs, files = next(os.walk(folder_to_monitor))
for file_name in files:
file_path = os.path.join(root, file_name)
if event.is_directory or file_name in self.changed_files.get(root, set()):
self.changed_files[root] = {file_name}
for dir_path in dirs:
self.changed_files[os.path.join(root, dir_path)] = set()
elif event.event_type == 'deleted' or event.event_type == 'created':
root, file_name = os.path.split(event.src_path)
self.changed_files[root].add(file_name)
def should_upload_files(self):
return len(self.changed_files) > 0
def get_changed_files_dict(self):
return self.changed_files
class CloudService(win32serviceutil.ServiceFramework):
_svc_name_ = global_service_name
_svc_display_name_ = global_service_name
_svc_account_ = global_service_account
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.stop_event = win32event.CreateEvent(None, 0, 0, None)
self.is_running = False
self.svc_account = _svc_account_
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.stop_event)
self.is_running = False
def SvcDoRun(self):
self.is_running = True
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
while self.is_running:
event_handler = MyHandler()
observer = Observer()
observer.schedule(event_handler, folder_to_monitor, recursive=True)
observer.start()
while self.is_running:
if event_handler.should_upload_files():
changed_files = event_handler.get_changed_files_dict()
# upload_files_to_server(changed_files)
with open("log.txt", "w") as f:
f.write(str(changed_files))
event_handler.changed_files.clear()
time.sleep(1)
if __name__ == '__main__':
# Delete the service
subprocess.call(["sc", "delete", global_service_name])
# Create the service
python_path = sys.executable
service_path = os.path.abspath(__file__)
# print(python_path)
subprocess.call(
[
'sc',
'create',
global_service_name,
f'binPath="{python_path} {service_path}"',
'start=auto',
]
)
print(f'\nService "{global_service_name}" created.\n')
# Set up the service
win32serviceutil.HandleCommandLine(CloudService)
The goals are:
automatically delete the service (reset for testing), then re-create it, with a specific name/description and to have it be in status of "Running".
When monitoring a folder, any modification or change will be logged in a .txt file on the desktop (for testing)
At the moment the service is being created in the services.msc
list, but the status is empty, and manually starting it produces errors:
Error 2: The system cannot find the file specified.
or
Error 1053: The service did not respond to the start or control request in a timely fashion.
Solutions attempted:
Tried looking in the forum and saw some answers as to copying the python.dll to site-packages folder but that didn't work.
using admin terminal to manually install the .py file, generates same output...
in depth conversation with chat-gpt3.5 about possible solutions :) didn't help in the end..
EDIT
After browsing again through some tutorials such as:
https://thepythoncorner.com/posts/2018-08-01-how-to-create-a-windows-service-in-python/
and looking at posts here such as
I am still stuck. My modified, hopefully simpler code now is:
class CloudService(win32serviceutil.ServiceFramework):
_svc_name_ = global_service_name
_svc_display_name_ = global_service_name
_svc_description_ = global_service_description
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
socket.setdefaulttimeout(60)
def SvcStop(self):
self.stop()
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
self.start()
servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, ''))
self.main()
def main(self):
# do some stuff
if __name__ == '__main__':
if len(sys.argv) == 1:
servicemanager.Initialize()
servicemanager.PrepareToHostSingle(CloudService)
servicemanager.StartServiceCtrlDispatcher()
else:
win32serviceutil.HandleCommandLine(CloudService)
If I use terminal with admin to python CloudService.py install
then the service appears, which also happened before, but when I try to Start it, I still get the error again:
Error 1053: The service did not respond to the start or control request in a timely fashion.
Any ideas on what this could be...? I'm guessing it's something with user permissions but not clear on what exactly is happening.
I think you're missing a space after
binPath=
. Try:From the documentation:
Another possible issue is that this script is deleting the service as it's being created. That might cause an exception which means
win32serviceutil.HandleCommandLine(CloudService)
will never be reached. Maybe add another argument to the script and when it's specified don't delete+create the service?