2026-06-11

Uygulama kilitlenince bildirim gelsin

Windows bir makine üzerinde çalışan bir uygulamamız var. Bu uygulama, nedendir bilinmez, bazen kilitleniyor. Böyle durumlar sonrasında yapmasını beklediğimiz işlemi yapamadığı için kesinti oluyor. Bunun önüne geçmek istiyorum.

Windows, uygulamanın bu şekilde kilitlendiği (Application hang) durumunda Uygulama olay günlüğüne 1002 kimliği ile bir kayıt düşüyor.

Logname = Application
ProviderName = Application Hang
Id = 1002

Bu olay kaydında kilitlenen uygulamanın başlatıldığı tarih ve saat bilgisi de yer alıyor. Bu bilgileri şimdilik eposta yoluyla bana atmasını istiyorum. Bu amaçla bir betik oluşturdum. Betik, son 1 dakika içinde oluşan bu tipteki bir olayları listeleyip sonuncusunu bir değişkene atıyor.

$ev1 = Get-WinEvent -FilterhashTable @{LogName='Application';ID=1002;StartTime=(Get-Date).AddMinutes(-1);ProviderName='Application Hang'} -ErrorAction SilentlyContinue |
    Where-Object {$_.Properties[0].Value -eq "uygulama.exe"} |
    Select-Object -First 1

Olay kaydı içinde şu bilgiler var:

Uygulama adı : $_.Properties[0]

Uygulama kimliği : $ev1.Properties[2].Value 

Başlangıç zamanı : $ev1.Properties[3].Value

Kilitlenme tipi : $ev1.Properties[9].Value

Ancak başlangıç zamanı şurada yazdığım gibi, FILETIME verisi. Bunu okunabilir bir şekle getirmek için

Get-Date -Format "yyyy-MM-dd HH:mm:ss" -Date ([datetime]::FromFileTimeUtc($ev1.Properties[3].Value))

kullanıyorum. Ayrıca gelen eposta içinde bilgisayarın başlatılma zamanı da olsa iyi olur. Bu sebeple CIM içinden bu bilgiyi de çekiyorum:

Bilgisayar açılış : (gcim win32_operatingsystem).LastBootUpTime

Tarih verilerini görüntülemede yyyy-MM-dd HH:mm:ss şeklinde format görmek istediğim için bunu da dönüştürüyorum:

Get-Date -Format "yyyy-MM-dd HH:mm:ss" -Date ((gcim win32_operatingsystem).LastBootUpTime)

Olay kaydında bir de sonlanma zamanı var, Properties[4] içinde, ama bu alanda hep  4294967295 verisi var. Bu da aslında aslında henüz süreç resmi olarak sonlanmadığı için 0xFFFFFFFF değerine eşit olan

[uint32]::MaxValue

Dolayısıyla bu alanı kullanmamıza gerek yok.

Bu betiği C:\Scripts\betik1.ps1 gibi bir konuma kopyaladıktan sonra zamanlanmış görevi oluşturmak için aşağıdaki kodu kullandım.

schtasks /Create
        /TN "Uygulama Sonlanma Bildirimi"
        /SC ONEVENT
        /EC "Application"
        /MO "*[System[Provider[@Name='Application Hang'] and (EventID=1002)]]"
        /TR "powershell.exe -ExecutionPolicy Bypass -File C:\Scripts\betik1.ps1"

Böyle bir durumda eposta göndermesin, sadece uygulamayı sadece yeniden başlatılsın denebilir. Bu durumda basit bir şekilde

ps uygulama.exe | kill
start uygulama.exe

gibi içeriğe sahip bir betik iş görür. 

Hiç yorum yok: