feat: implement Windows service for Intrusion Detection Flask web app

This commit is contained in:
zwitschi committed 2026-08-11 11:17:06 +02:00
1 parent 67576e3c69
commit af5da6c332
2 files changed
+87 -1

No files matched your search

+85
View File
@@ -0,0 +1,85 @@
"""Windows service that runs the Intrusion Detection Flask web app.
Serves the web UI on localhost using the configured defaults
(``http://127.0.0.1:54666`` from ``app.utils.constants``; the ``WEB_HOST``
and ``WEB_PORT`` environment variables or a local ``.env`` override them).
Manage with (from the project root, in an activated venv):
python intrusion-detection-service.py install
python intrusion-detection-service.py start
python intrusion-detection-service.py stop
python intrusion-detection-service.py remove
"""
import os
import sys
import threading
import servicemanager
import win32event
import win32service
import win32serviceutil
# Ensure the project root is importable. When the SCM launches the service
# the working directory may be C:\\Windows\\System32, not the project dir.
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from app.utils.constants import WEB_HOST, WEB_PORT # noqa: E402
class IntrusionDetectionService(win32serviceutil.ServiceFramework):
_svc_name_ = "IntrusionDetectionWebUI"
_svc_display_name_ = "Intrusion Detection Web UI"
_svc_description_ = (
"Serves the Intrusion Detection Flask web app on localhost "
f"(http://{WEB_HOST}:{WEB_PORT})."
)
def __init__(self, args):
win32serviceutil.ServiceFramework.__init__(self, args)
self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
self._flask_thread = None
def SvcStop(self):
# Report STOP_PENDING, then signal the main loop; the SCM marks the
# service STOPPED once SvcDoRun returns (after Flask shuts down).
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.hWaitStop)
def SvcDoRun(self):
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STARTED,
(self._svc_name_, '')
)
try:
self.main()
finally:
servicemanager.LogMsg(
servicemanager.EVENTLOG_INFORMATION_TYPE,
servicemanager.PYS_SERVICE_STOPPED,
(self._svc_name_, '')
)
def main(self):
from app.web import serve
# Flask's app.run() blocks, so run it on a daemon thread and keep the
# service alive here until SvcStop signals the stop event. serve()
# passes use_reloader=False, which is required under the service host
# (the reloader would spawn a child process and break the service).
self._flask_thread = threading.Thread(
target=serve,
kwargs={"host": WEB_HOST, "port": WEB_PORT},
daemon=True,
name="flask-web",
)
self._flask_thread.start()
win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)
if __name__ == '__main__':
# Handles both the service-host launch and command-line control
# (install / start / stop / remove).
win32serviceutil.HandleCommandLine(IntrusionDetectionService)
+2 -1
View File
@@ -1,3 +1,4 @@
flask
paramiko
python-dotenv
flask
pywin32