Bir alt satırdaki processi kapatıyor

Merhaba, aşşagıdaki resimde göreceginiz üzere bir process takip sistemim var ve açık olan processleri text’de listeliyorum yanında bulunan mavi kapat yazısına tıklayınca ise kapatıyor herşey normal düzgün gibi gözüksede 1. satırda bulunan Calculator.exe kapat bölümüne tıklıyorum ama 2. satırdaki Mspaint.exe bölümünü kapatıyor sebebini anlayamadım yardımcı olursanız sevinirim.

KOD

# -*- coding: utf-8 -*-
from tkinter import messagebox

import win32con
import win32api
import win32security
import wmi, time, threading
import pythoncom
import os
from apscheduler.schedulers.background import BackgroundScheduler
import datetime
from time import gmtime, strftime

sozluk = {}




class Process(object):
    # Process'leri daha kolay kontrol etmek için bir sınıf oluşturduk

    def __init__(self, process_id, name, start_time):
        self.process_id = process_id
        self.name = name
        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()
            pid = new_process.ProcessId
            name = new_process.Name
            if name.__contains__('Calc') or name.__contains__('paint'):
                sozluk[pid] = Process(pid, name, time.time())
                print(f"{pid} pid numaralı {name} programı çalışmaya başladı")
                kontrol()
        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:
            process = process_watcher()
            pid = process.ProcessId
            name = process.Name
            process = sozluk[pid]
            sozluk.pop(pid)
            print(
                f"{pid} pid numaralı "
                f"{name} programı "
                f"{int(time.time() - process.start_time)} "
                f"saniye çalıştı."
            )
            kontrol()

        except:
            pass



def kontrol():
    text.delete("1.0", END)
    for key, value in sozluk.items():
        process = sozluk[key]
        süre = str(datetime.timedelta(seconds=int(time.time() - process.start_time)))
        text.tag_config("tag2", foreground="green")
        text.insert(END, process.name, "tag2")
        text.insert(END,
            f" {süre} "
        )
        text.insert(END, "Kapat", "tag")
        text.tag_config("tag", foreground="blue")
        text.tag_bind("tag", "<Button-1>", lambda event: threading.Thread(target=os.kill,args=(int(process.process_id),9)).start())
        text.insert(END, "\n")




if __name__ == '__main__':
    global text
    from tkinter import*
    gui= Tk()
    sched = BackgroundScheduler(daemon=True)
    gui.resizable(width=0,height=0)
    gui.pack_propagate(0)
    gui.geometry("300x400")
    th1 = threading.Thread(target=onCreate)
    th2 = threading.Thread(target=onDestroy)
    th1.daemon = True
    th2.daemon = True
    th1.start()
    th2.start()
    pythoncom.CoUninitialize()
    sched.start()
    scroll = Scrollbar(gui, width=17)
    scroll.pack(side=RIGHT, fill=Y)
    Button(gui,text="Yenile",command=kontrol).pack(side=TOP,anchor=SW)
    text = Text(gui,font=('Arial',10,'bold'),yscrollcommand=scroll.set,cursor="arrow")
    text.pack(side=BOTTOM)
    scroll.config(command=text.yview)
    gui.mainloop()

Merhaba.

for döngüsünde lambda kullandığımız zaman, lambda'ya döngünün son elemanı eklenir. Bunun sebebi değişkenlerin lambda'da değil for döngüsünün bulunduğu scope’ta tanımlı olması.

Bknz: https://docs.python.org/3/faq/programming.html#why-do-lambdas-defined-in-a-loop-with-different-values-all-return-the-same-result

Döngüdeki lambda için yeni bir argüman oluşturmalısınız ve döngünün her bir adımında process.process_id'yi lambda'ya argüman olarak paslamanız gerekiyor ve lambda içindeki fonksiyonun da bu argümanı kullanması lazım.

Yani yazdığınız kodlar şuna benziyor:

x = [lambda: print(i) for i in range(10)]

for f in x:
    f()

Bu kodlar 10 defa 9 yazısının ekrana yazılmasını sağlar.

Sayıların 0’dan 9’a kadar yazdırılması için lambda fonksiyonunda argüman oluşturmamız ve bu argümana döngü değişkenini atamamız gerekiyor.

x = [lambda arg=i: print(arg) for i in range(10)]

for f in x:
    f()

Ayrıca her seferinde aynı tag ismiyle text widgetine satır ekliyorsunuz. Dolayısıyla ilgili tag en son eklenen satıra ait oluyor. Bu yüzden tag'lar her satır için ayrı bir isme sahip olmalı.

Aşağıdaki kodları inceleyin isterseniz:

Not: Paylaştığınız kodlarda sık kullanılmayan bir 3. parti kütüphane varsa, o kütüphanenin yüklenme şeklini de paylaşırsanız, okuyucuya kolaylık sağlamış olursunuz. Mesela okuyucu win32con kütüphanesini pip install win32con şeklinde indirmeye kalkabilir. Bu indirme girişiminin başarısız olduğunu gördüğünde, win32con'u google’da aratıp, kütüphanenin hangi isimle indirilebilir olduğunu araştırmak zorunda kalabilir.

Kodlar:

# -*- coding: utf-8 -*-

from tkinter import messagebox
from tkinter import *

import win32con
import win32api
import win32security
import wmi, time, threading
import pythoncom
import os
from apscheduler.schedulers.background import BackgroundScheduler
import datetime
from time import gmtime, strftime

sozluk = {}


class Process(object):
    # Process'leri daha kolay kontrol etmek için bir sınıf oluşturduk

    def __init__(self, process_id, name, start_time):
        self.process_id = process_id
        self.name = name
        self.start_time = start_time


def onCreate(text):
    # 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()
            pid = new_process.ProcessId
            name = new_process.Name
            # if name.__contains__('Calc') or name.__contains__('paint'):
            sozluk[pid] = Process(pid, name, time.time())
            print(f"{pid} pid numaralı {name} programı çalışmaya başladı")
            kontrol(text)
        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:
            process = process_watcher()
            pid = process.ProcessId
            name = process.Name
            process = sozluk[pid]
            sozluk.pop(pid)
            print(
                f"{pid} pid numaralı "
                f"{name} programı "
                f"{int(time.time() - process.start_time)} "
                f"saniye çalıştı."
            )
            kontrol(text)
        except:
            pass


def kontrol(text):
    text.delete("1.0", END)
    for key, value in sozluk.items():
        process = sozluk[key]
        süre = str(datetime.timedelta(seconds=int(time.time() - process.start_time)))
        text.tag_config(f"tag{key}-1", foreground="green")
        text.insert(END, process.name, f"tag{key}-1")
        text.insert(END,
            f" {süre} "
        )
        text.tag_config(f"tag{key}-2", foreground="blue")
        text.insert(END, "Kapat", f"tag{key}-2")
        
        text.tag_bind(f"tag{key}-2", "<Button-1>", lambda event, process_id=process.process_id: threading.Thread(target=os.kill,args=(int(process_id),9)).start())
        text.insert(END, "\n")
        

if __name__ == '__main__':
    gui= Tk()
    Button(gui,text="Yenile",command=lambda: kontrol(text)).pack(side=TOP,anchor=SW)
    scroll = Scrollbar(gui, width=17)
    scroll.pack(side=RIGHT, fill=Y)
    text = Text(gui,font=('Arial',10,'bold'),yscrollcommand=scroll.set,cursor="arrow")
    text.pack(side=BOTTOM)
    scroll.config(command=text.yview)
    sched = BackgroundScheduler(daemon=True)
    gui.resizable(width=0,height=0)
    gui.pack_propagate(0)
    gui.geometry("300x400")
    th1 = threading.Thread(target=lambda: onCreate(text))
    th2 = threading.Thread(target=onDestroy)
    th1.daemon = True
    th2.daemon = True
    th1.start()
    th2.start()
    pythoncom.CoUninitialize()
    sched.start()
    gui.mainloop()
2 Beğeni

Cevabınız için teşekkür ediyorum attıgınız kodları inceledim fakat anlamadıgım bir bölüm oldu {key}-1
{key}-2 gibi bunlar nedir ne anlama geliyor acaba

Bir önceki mesajımda bahsetmeye çalıştım. Her bir programın pid değeri sözlük'ün key değeri ve her bir pid için ayrı bir tag oluşturmanız gerekiyor. Çünkü belli bir tagButton-1'e bağlarken, sadece o tag'a sahip olan programın kapatılmasını sağlamak istiyoruz. Siz bütün programlar için aynı tag'ı kullanırsanız, o tag ile text widgetine ismi eklenmiş olan son program kapatılır.

f"tag{key}-1", rengi yeşil yapan tag'a, f"tag{key}-2" ise Button-1 ile yapılan bağlamada kullanılan tag'a verilen isimler. Aslında f"tag{key}-1" bütün programlar için aynı olabilirdi, çünkü bütün programların isimlerinin yeşil renkte olması isteniyor ve bu tag ile renklendirme dışında herhangi bir işlem de yapılmıyor. Onu fazladan yazmışım, ama zararı yok. Öte yandan f"tag{key}-2"'nin bu şekilde olması gerekiyor.

isimlendirme amaçlımı {key} bölümünü kullanıyoruz her sonraki tag için

Aynen öyle.

peki {key} yerine i = 0 for döngüsünün dışına koyulup for her deger döndürdügünde i +=1 yaparak {key} yerine {i} yapamazmıydık

Yapabilirsiniz, yeter ki her bir program ismi için farklı tag isimleri seçilmiş olsun.

benim bu isimlendirme şekli daha çok ilgimi çekti bu tarz kullanmayı düşünüyorum o yüzden aklıma takılan diger bölümü sormak istiyorum tag içerisinde belirttigimiz {key} ile sözlük içersinide bulunan [key] aynı degil sanıyorum ama orda {key-1} kullanıyoruz hangi degerden -1 çıkartıyor acaba

Hayır, çıkartma yapmıyoruz orada. Koda dikkatli bakarsanız -1 ve -2, küme parantezinin dışında kalıyor. Yani, key değeri 1234 olduğunda f"tag{key}-1", tag1234-1'e ve f"tag{key}-2" ise tag1234-2'ye eşit oluyor.

Sözlük içerisinde bulunan key ile, tag için kullandığımız key aynı key.

Bu son kısmı tam olarak anlamadım gibi ama zamanla çözerim umarım :slight_smile:
Herşey için çok teşekkürler :heart_eyes:

tag'a isim verirken aşağıdakine benzer bir iş yapıyoruz aslında.

sozluk = {1234: "value1", 5678: "value2"}

for key, value in sozluk.items():
    tag = f"tag{key}-1"
    print(tag)

Ben sözlük yapısına tam hakim olmadıgım için key ve value’in işlevini tam bilmiyordum ama örnek sonrası yukarıdaki koda tekrar baktıgımda benim kullandıgım sözlügün key’i aslında pid bölümü dolayısıyla her birinin tag bölümündeki {key} ismi farklı oluyor ama -1 bölümünün geregini halen anlamadım sadece tag {key} şeklinde yapsakta zaten isimleri farklı olacak -1 ne geregi kalıyor

-1 ve -2 karakterlerini sizin kodlarınıza göre düzenledim ben. Siz, 1. tag için text.tag_config("tag2", foreground="green") satırını yazmıştınız. 2. tag için de text.tag_config("tag", foreground="blue") satırını yazmıştınız.

Bu iki tag birbirinden farklı olsun diye birine -1 diğerine -2 karakterlerini ekledim. Buradaki -1 karakterlerini, Örnek-1 gibi bir ifadeyi kullanmaya alışmış olduğum için kullandım aslında.

1 Beğeni

Zaman ayırıp anlattıgınız için çok teşekkür ediyorum :heart_eyes:
Net olarak anladım rahat uyuyabilirim :slight_smile:

1 Beğeni

Rica ederim kolay gelsin.

1 Beğeni