Сервис для наблюдения за запущенным приложением с использованием python - PullRequest
0 голосов
/ 24 сентября 2019

Прежде всего, моя цель для этой программы - получить время начала и время окончания конкретного приложения.И это должно работать как услуга.

Я нашел этот код в интернете.Функция foreach_window() возвращает объект работающего приложения:

import ctypes
import win32process
import win32con
import win32gui
import time
import psutil
from datetime import datetime

import os
import json

EnumWindows = ctypes.windll.user32.EnumWindows
EnumWindowsProc = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.POINTER(ctypes.c_int),     ctypes.POINTER(ctypes.c_int))
GetWindowText = ctypes.windll.user32.GetWindowTextW
GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW
IsWindowVisible = ctypes.windll.user32.IsWindowVisible

excludeExe = []
excludeTitle = []

processes = {}
processGlobal = {}
def foreach_window():

    process = {}

    def callback(hwnd, lParam) :
        if IsWindowVisible(hwnd):
            length = GetWindowTextLength(hwnd)

            if(length > 0) :

                buff = ctypes.create_unicode_buffer(length + 1)
                GetWindowText(hwnd, buff, length + 1)
                #titles.append(buff.value)

                hwndx = win32gui.FindWindow(None, buff.value)
                pid = win32process.GetWindowThreadProcessId(hwndx)
                proc_name = psutil.Process(pid[1]).name()
                create_time = psutil.Process(pid[1]).create_time()

                item = {}
                item["pid"] = pid[1]
                item["name"] = proc_name
                item["window_title"] = buff.value
                item["create_time"] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(create_time))
                item["end_time"] = ""

                process_id = pid[0]
                if not proc_name in excludeExe and buff.value != "" and not buff.value in excludeTitle:
                    if not process_id in processGlobal :
                        process[process_id] = item

    EnumWindows(EnumWindowsProc(callback),0)
    return process



def runServiceWatch() : 

    win_list = foreach_window()
    todayObject = datetime.now()
    dateFilename = todayObject.strftime("%d-%b-%Y")
    dir_path = os.path.dirname(os.path.realpath(__file__))
    path = '{}\{}.{}'.format(dir_path,dateFilename,'json')
    with open(path, 'w') as json_file:
        json.dump(win_list, json_file)

Она работает отлично, но когда я добавила простой сервис, я не получила результат.foreach_window() возврат пустого объекта.

Вот мой полный код:

import servicemanager
import win32event
import win32service
import win32serviceutil
import win32timezone
import sys
import subprocess
import threading


import ctypes
import win32process
import win32con
import win32gui
import time
import psutil
from datetime import datetime

import os
import json

EnumWindows = ctypes.windll.user32.EnumWindows
EnumWindowsProc = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.POINTER(ctypes.c_int),     ctypes.POINTER(ctypes.c_int))
GetWindowText = ctypes.windll.user32.GetWindowTextW
GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW
IsWindowVisible = ctypes.windll.user32.IsWindowVisible

excludeExe = []
excludeTitle = []

processes = {}
processGlobal = {}
def foreach_window():

    process = {}

    def callback(hwnd, lParam) :
        if IsWindowVisible(hwnd):
            length = GetWindowTextLength(hwnd)

            if(length > 0) :

                buff = ctypes.create_unicode_buffer(length + 1)
                GetWindowText(hwnd, buff, length + 1)
                #titles.append(buff.value)

                hwndx = win32gui.FindWindow(None, buff.value)
                pid = win32process.GetWindowThreadProcessId(hwndx)
                proc_name = psutil.Process(pid[1]).name()
                create_time = psutil.Process(pid[1]).create_time()

                item = {}
                item["pid"] = pid[1]
                item["name"] = proc_name
                item["window_title"] = buff.value
                item["create_time"] = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(create_time))
                item["end_time"] = ""

                process_id = pid[0]
                if not proc_name in excludeExe and buff.value != "" and not buff.value in excludeTitle:
                    if not process_id in processGlobal :
                        process[process_id] = item

    EnumWindows(EnumWindowsProc(callback),0)
    return process



def runServiceWatch() : 

    k = processes

    win_list = foreach_window()
    y = win_list

    todayObject = datetime.now()
    dateFilename = todayObject.strftime("%d-%b-%Y")
    dir_path = os.path.dirname(os.path.realpath(__file__))
    path = '{}\{}.{}'.format(dir_path,dateFilename,'json')
    with open(path, 'w') as json_file:
        json.dump(win_list, json_file)

    #watcher logic later

def threadTask(job_function):
    job_thread = threading.Thread(target=job_function)
    job_thread.start()

class ClientService(win32serviceutil.ServiceFramework):
    _svc_name_ = "Process Util"
    _svc_display_name_ = "Process Util"

    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)
        self.isrunning = False
        isStarted = False
    def checkLoop(self) :

        pass

    def SvcDoRun(self):
        self.isrunning = True


        self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
        rc = None
        while rc != win32event.WAIT_OBJECT_0:
            try:
                self.ReportServiceStatus(win32service.SERVICE_RUNNING)
                runServiceWatch()
            except Exception:
                self.SvcStop()
                self.ReportServiceStatus(win32service.SERVICE_STOPPED)

            rc = win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)

if __name__ == '__main__':

    if len(sys.argv) == 1:
        servicemanager.Initialize()
        servicemanager.PrepareToHostSingle(ClientService)
        servicemanager.StartServiceCtrlDispatcher()
    else:
        win32serviceutil.HandleCommandLine(ClientService)

runServiceWatch() должен работать во время работы службы.

Пожалуйста, помогите мне, спасибо ввперед.

...