Uygulamanın Idle Modunu Yakalamak(C#, VB.NET)

“Idle” kavramı, bir uygulamanın tüm işlerini(process) bitirip atıl moda geçmesini temsil eder. Aynı kavram, işletim sistemleri için de kullanılarak işletim sisteminin tüm işlemlerini bitirip bekleme moduna geçmesi anlamına gelir. Birçoğumuzun kullandığı GTalk programında uzun süren bir hareketsizlik olduğu zaman kullanıcı idle durumuna geçirilir. Programımızın atıl durumdayken bazı özel işler yapmasını sağlamak için Idle olayı kullanılır. Programın atıl durumda olması demek, üzerinde herhangi bir klavye, mouse hareketi olmadığı için arka tarafta da kuyrukta herhangi bir processin işlenmiyor veya beklenmiyor olmasıdır. Kısacası programın tamamen, durağan moda geçmesidir. Windows uygulamaları, ne zaman Idle moduna geçtiklerini bilecek yeteneğe sahiptir. Özellikle gelişmiş programlama dillerinde uygulamanın Idle modunu yakalamak için belli componentler sunulur. Bu amaçla VB.NET, C# tarafında Windows formunu temsil eden Application nesnesinin Idle eventi mevcuttur. Uygulama tüm processlerini bitirip hareketsiz duruma geçtiği anda bu event tetiklenir. Bu event, herhangi bir kontrol tarafından değil doğrudan Windows tarafından tetiklenir.
Application.Idle eventini kullanmak çok kolay. Bunun için uygulama içerisinde bu event dolayısıyla çalışacak bir metod tanımlanır ve bu metodu delege aracılığıyla Idle eventine bağlanılır. Bu işlemi Main() metodu içerisinde yapabileceğimiz gibi formun Load() metodu içerisinde de yapabiliriz.

int Sayac = 0;
private void Form1_Idle(object sender, System.EventArgs e)
{
    Sayac++;
    this.Text = "Sayaç : "+ Sayac.ToString();
}//Form1_Idle

private void Form1_Load(object sender, System.EventArgs e)
{
    Application.Idle +=new EventHandler(Form1_Idle);
}//Form1_Load
Private Sayac As Integer = 0
Private Sub Form1_Idle(ByVal sender As Object, ByVal e As System.EventArgs)
    Sayac = Sayac + 1
    Me.Text = "Sayaç :" & Sayac.ToString()
End Sub 'Form1_Idle

Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
    AddHandler Application.Idle, New EventHandler(AddressOf Form1_Idle)
End Sub 'Form1_Load

Idle olayını test etmek için programın Titlebar’ından bir süre sabit tutalım. Bu sürede sayaçın sabitlendiğini yani Idle modundan çıktığını görmüş oluruz.
Idle eventinin en çok kullanıldığı alanlardan biri, virtual-key olarak tanımlanan karakterlerin (yön tuşları, PageDown ,PageUp, End, Home, NumLock, CapsLock . . .) durumunun denetlenmesi ve programın ne kadar uzun süredir hareketsiz kaldığının tespit edilmesidir. Örneğin kullanıcının CapsLock’ı açıp açmadığını veya Delete tuşunun basılıp basılmadığını denetlemek isteyebiliriz. Virtual-key’lerin özelliği ASCII kodlarının olmamasıdır. Özellikle CapsLock, NumLock tuşlarının durumunu uygulama içerisinde öğrenmek için Idle() metodunu kullanılır. Bu amaç için user32.dll kütüphanesinin GetKeyState API’si kullanılır. Bu fonksiyon, hexidecimal türünde parametre olarak aldığı tuşun basılı olup olmadığını döndürür. Uygulamamızda DllImport’u kullanmak için using System.Runtime.InteropServices namespace’yi import etmeliyiz.

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
    InitializeComponent();
}

//user32.dll kütüphanesini import edip GetKeyState() metodunu çağıralım
[DllImport("user32.dll")]
extern static int GetKeyState(int key);

string FormTitle = "";
public void Form1_Idle(object sender, EventArgs e)
{
    FormTitle = "";
    if (GetKeyState('\x14') == 1)
		FormTitle += "CAPS ";//CapsLock açık
	else
		FormTitle += "";

    if (GetKeyState('\x90') == 1)
        FormTitle += "NUM ";//NumLock açık
    else
        FormTitle += "";

    if (GetKeyState('\x91') == 1)
        FormTitle += "SCRL ";//ScrollLock açık
    else
        FormTitle += "";

    this.Text = FormTitle;
}//OnIdle

private void Form1_Load(object sender, EventArgs e)
{
    Application.Idle += new EventHandler(Form1_Idle);
}//Form1_Load

}//Form1

}//WindowsApplication1

Imports System.Runtime.InteropServices

Public Class Form1

‘user32.dll kütüphanesini import edip GetKeyState() metodunu çağıralım

Idle modunda ihtiyaç duyulan diğer konu da uygulamanın ne kadar süredir Idle modunda olduğudur. Bunu en doğru Windows’tan öğrenebiliriz. Bunun için aynı şekilde user32.dll kütüphanesi kullanılır. Bu kütüphanenin GetLastInputInfo() fonksiyonu, uygulamaya yapılmış en sonki input zamanını döndürür. Uygulamanın ne kadar süredir Idle modunda olduğunu öğrenmek için uygulamanın açık kaldığı süreden Idle modunda geçtiği andaki süreyi çıkarılır. Uygulamanın ne kadar süredir açık olduğu bilgisini System.Environment sınıfının TickCount property’siyle öğrenilebilir. Bu değerler millisaniye cinsindedir. Formun üzerindelabel1 isminde bir Label nesnesi ve bu nesneyi belli sürede güncellemek için tmrCheckIdleTime isminde bir Timer nesnesi kullanacağız.

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
    InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
    tmrCheckIdleTime.Start();
}//Form1_Load

internal struct LASTINPUTINFO
{
    public uint cbSize;
    public uint dwTime;
}//LASTINPUTINFO

[DllImport("user32.dll")]
private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

int idleTime = 0;
LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
int lastInputTick;
int envTicks;

private void tmrCheckIdleTime_Tick(object sender, EventArgs e)
{
    lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo);
    lastInputInfo.dwTime = 0;

    envTicks = Environment.TickCount;//Toplam geçen süre

    if (GetLastInputInfo(ref lastInputInfo))
    {
        lastInputTick = (int)lastInputInfo.dwTime;
        //En son yapılmış input'un time değeri

        idleTime = envTicks - lastInputTick;
    }
    label1.Text = "Toplam geçen süre : " + envTicks.ToString()
        + "\n Last input time : " + lastInputTick
        + "\n Idle süresi :" + idleTime;
}//tmrCheckIdleTime_Tick

}//Form1

}//WindowsApplication1

Public Class Form1

Structure LASTINPUTINFO
Public cbSize As System.UInt32
Public dwTime As System.UInt32
End Structure ‘LASTINPUTINFO


Bu örneği biraz daha geliştirip uygulamanın, belirlenecek süre kadar Idle moduna beklemesi durumunda bilgisayar lock edebiliriz. Bunun için User32.dll kütüphanesinin LockWorkStation() metodu kullanılabilir.
NOT : Managed code içerisinde hangi API’leri nasıl kullanacağımız konusunda http://pinvoke.net sitesi iyi bir doküman sunmaktadır.

Uygulamanın Idle Modunu Yakalamak(C#, VB.NET)” üzerine bir düşünce

  1. Zaim AKINÖZ

    Her makalene tek tek çok güzelmiş yazmak uzun süreceğinden, buraya yazıyorum: “Sitedeki tüm makalelerin çok faydalı, seni tebrik ediyor ve başarılarının devamını diliyorum.”

    Cevapla
  2. Hakan Fatih YILDIRIM

    Gercekten cok faydalı ve acıklaması cok güzel basarılar dilerim.Aynen devam.Hakan Fatih YILDIRIM
    MCP

    Cevapla
  3. goksenin

    Çok işime yaradı gerçekten başarılı bir makale.Başarılarının devamını dilerim

    Cevapla

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Time limit is exhausted. Please reload CAPTCHA.