Python’da çalışan işlemlerin çalışma süresini veren bir script yazmaya çalışıyorum. Bu Python’da mümkün mü bilmiyorum fakat Powershell ile yapılabileceğini buldum. Bunu subprocess kullanarak 2 satır kodla halledebildim ama çıktı berbat oluyor. Bu Powershell komutu ile tek bir işlemi nasıl alabilirim ve bu çıktıyı nasıl daha düzenli bir hale getirebilirim?
Kod:
import subprocess
print(subprocess.check_output("powershell Get-Process opera | select starttime"))
Maalesef kodunuzda sıkıntı var. Kod not defterini açsa da zamanı göstermiyor hata veriyor.
Py3.7 kullanıyorum.
Hata:
Traceback (most recent call last):
File "C:\Users\Wyren\Desktop\deneme.py", line 48, in <module>
getProgramRunTime("notepad")
File "C:\Users\Wyren\Desktop\deneme.py", line 41, in getProgramRunTime
sys.stdout.write(out)
TypeError: must be str, not bytes
Yardımınız için teşekkürler. Peki bunu otomatik olarak yapabilir miyiz? Mesela kullanıcı Chrome’u açtı ve uygulama otomatikmen süreyi saymaya başladı. Sonra kullanıcı Chrome’u kapadı ve uygulama süreyi bir yere kaydetti.
Rica ederim. Bundan sonrası windows api programlamaya giriyor. Fikir vermesi açısından size şunu söyleyebilirim. Python ile process izleyici yaparsanız, yeni başlayan her process’i takip etme şansınız olur. WMI bu konuda size yardımcı olabilir sanırım.
Her yeni process başladığında bu process’e dair bilgileri ekrana yazan bir winapi programı. Sorularınız olursa hep beraber cevaplamaya çalışırız.
Şuan az çok bir şeyler yaptım. Hatta çalışma süresini verebilecek bir plan var aklımda ama nasıl yapabileceğimi bilmiyorum. Kısa bir deneme yanılmayla koddaki process_watcher = c.Win32_Process.watch_for("creation") kısmını process_watcher2 = c.Win32_Process.watch_for("deletion") yapabileceğimizi öğrendim. Bu da bu kodun uygulamaların kapanışını izlediğini gösteriyor. print(process_watcher) kodunu biraz bilgi edinebilmek için kullandım ve "deletion"ın ne zaman olduğunu tıpkı "creation"daki gibi CreationDate ile tespit edebildiğimizi keşfettim. Çalışma süresini bulmak için yaptığım şey şuydu:
Ama başarısız oluyordu. Anladığım kadarıyla uygulama kapanınca create_date değişkeninin içeriği sıfırlanıyor ve çıkarma işlemi başarısız oluyordu. Fakat print(create_date, close_date) yazınca düzgünce zamanları bastırıyor. Sizce bunun nedenleri ne olabilir?
Şöyle bir durum var. Sizin CreationDate diye aldığınız zaman bizim işimize yaramaz. Bunun yerine iki olayı da ayrı ayrı dinlemeniz gerekir. Yani process başladığında başlama zamanını bir sözlüğe kaydedin, sonra da sonlanma bilgisi gelince de sözlükten başlama tarihini alarak çıkarma yapın. İki olayı da aynı anda dinlemek için Thread kullanabilirsiniz. Taslak şu şekilde olabilir
sözlük = {}
def baslama():
# process başlangıçlarını dinleyen kısım
# burada, her process başlangıç zamanını sözlüğe process adıyla kaydedebilirsiniz
# yeni process başladığında
sözlük[process_adi] = simdiki_zaman
def sonlanma():
# sonlanan process ismini sözlükten veriyle beraber çekin ve şimdiki zamandan çıkarın
sonuc = simdiki_zaman-sözlük[process_adi]
Bu arada, bu konuyla ilgili daha fazla bilgi almak isterseniz şu kaynaklara bakabilirsiniz
Anlattığım algoritmaya göre programı yazdım. Ortaya şöyle bir sonuç çıktı.
# -*- coding: cp1254 -*-
import win32con
import win32api
import win32security
import wmi,time,threading
import pythoncom
sozluk = {}
class Process(object):
# Process'leri daha kolay kontrol etmek için bir sınıf oluşturduk
def __init__(self,process_id,process_path,start_time):
self.process_id = process_id
self.process_path = process_path
self.start_time = start_time
def onCreate():
# burası process oluşturulmasını dinleme
print("Dinleniyor...")
pythoncom.CoInitialize() # Thread içinde kullanılması önerilmiş. Bu yüzden kullandık
c = wmi.WMI()
process_watcher = c.Win32_Process.watch_for("creation")
while True:
try:
new_process = process_watcher()
executable = new_process.ExecutablePath
pid = new_process.ProcessId
sozluk[pid] = Process(pid,executable,time.time())
print("Yeni bir process başladı: {}".format(pid))
except:
pass
def onDestroy():
# burası process sonlanmasını dinleme
pythoncom.CoInitialize()
c = wmi.WMI()
process_watcher = c.Win32_Process.watch_for("deletion")
while True:
try:
new_process = process_watcher()
pid = new_process.ProcessId
process = sozluk.get(pid,None)
if(process != None):
sonuc = time.time()-process.start_time
print("[{}] {} programı {} saniye boyunca açık kaldı".format(pid,process.process_path,sonuc))
sozluk[pid] = None
except:
pass
th1 = threading.Thread(target = onCreate)
th2 = threading.Thread(target = onDestroy)
th1.daemon = True
th2.daemon = True
th1.start()
th2.start()
input("Programı sonlandırmak için Enter'a basın\n")
pythoncom.CoUninitialize()
Bazı programları açıp kapattım
Yeni bir process başladı: 5948
[5948] C:\Windows\system32\notepad.exe programı 5.886718034744263 saniye boyunca açık kaldı
Yeni bir process başladı: 3852
Yeni bir process başladı: 4724
[3852] C:\Windows\system32\dxdiag.exe programı 24.152343034744263 saniye boyunca açık kaldı
[4724] C:\Windows\system32\calc.exe programı 3.955077886581421 saniye boyunca açık kaldı
Çok teşekkürler. Bu arada en sondaki input("Programı sonlandırmak için Enter'a basın\n") biraz işi bozuyordu. Enter’a bastıktan sonra işlemlerin başlayıp sonlandığını gösteriyordu. Yani o kısım silinse çok daha iyi olabilir.
Yeni bir process başladı: 5948
[5948] C:\Windows\system32\notepad.exe programı 5.886718034744263 saniye boyunca açık kaldı
Yeni bir process başladı: 3852
Yeni bir process başladı: 4724
[3852] C:\Windows\system32\dxdiag.exe programı 24.152343034744263 saniye boyunca açık kaldı
[4724] C:\Windows\system32\calc.exe programı 3.955077886581421 saniye boyunca açık kaldı
yazılarını göstermiyordu. Enter’a bastıktan sonra göstermeye başlıyordu.