Прежде всего, моя цель для этой программы - получить время начала и время окончания конкретного приложения.И это должно работать как услуга.
Я нашел этот код в интернете.Функция 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()
должен работать во время работы службы.
Пожалуйста, помогите мне, спасибо ввперед.