Makale Özeti

Bu makalede System.ServiceProcess'i ve C# kullanarak WinXP'nin sahip oldugu işletim sistemi servislerini nasil başlatir, duraklatir veya durduruz onu ele alacagiz.

Makale

Merhabalar, pek sık ihtiyaç duymasakda bazı durumlarda Windows servislerinin çalışmalarına müdahale etmek isteyebiliriz. Hiç bir zaman ihtiyacımızın olmayacağını düşündüğümüz servisleri kapatmak, sistemimizin  performansını pozitif yönde etkileyebileceği gibi bazı durumlarda sistem karalığınada olumsuz katkıları olabilir.

 

Profesyonel kullanıcılar olarak gerekli anlarda Windows servislerine müdaheleyi “services.msc” yönetim konsolu ile değilde , C# ile yaptığımız basit bir uygulama ile nasıl yapabiliriz onu inceleyelim.

 

İlk önce makinamızda çalışan servisleri görmek icin çalıştır satırına “services.msc” yazıyoruz ve makinamızda bulunan tüm servisleri ve durumlarını buradan izleyebiliyor ve değiştirebiliyoruz.


 

Uygulamamızı geliştirmeye başlamadan önce hangi servislere müdahele etmek istiyoruz ona karar vermemiz gerekmektedir, çünkü programımızı ona gore şekillendireceğiz. Yada makinamızda çalışan bütün servisleride listeliyebiliriz. Ben bütün servisleri listeleme seçeneğine göre programımıza başlayacağım, sizde “serviceController”i kullanmayı öğrenince istediğiniz servis üzerine yoğunlaşabilirsiniz.

 

İlk olarak yeni bir proje açıp formumuzun üstüne 3 buton koyuyoruz, bu butonları sectiğimiz servisi başlatmak, duraklatmak veya tamamıyla durdurmak için kullanacağız.

 

 

Ben buttonlara iconlar kullanarak daha çok görsel anlam katmak istedim. Ayrıca formumuzada bir icon ekledim. Buna benzer programlarımızı daha hoş hale getirecek iconları, ücretsiz bir çok siteden indire bilirsiniz. Bizim gibi yazılım geliştiricelerin pek dikkatini çekmesede programımızı kullanacak kullanıcıların bu tür görsel temalar dikkatini çekmektedir.
Buttonlarımızın ismini ben “btn_start”,”btn_pause” ve “btn_stop” olarak koydum.
Sıra geldi şimdi Windows servisleri ile programımızda nasıl anlaşacağımıza, bunun için ilk önce “Toolbox” umuzdan ilk olarak bir “ServicesController” eklemeliyiz. Bu component sayesinde sistemimizde bulunan bütün servislere ulaşabileceğiz. Ekledikten sonra properties seçeneğinden direkt hitap etmek istediğimiz servisi seçebileceğimiz gibi eğer adını biliyorsak daha sonrada bu ServiceName’i belirtebiliriz.

Belirli bir servis seçmeyeceğimiz için ben aşağıdaki satır ile bütün servislerin adını alıyorum.

 

ServiceController[] hepsi= ServiceController.GetServices();

 

Aldığımız  bütün servisleri listeleyebilmek için ben bir ComboBox’u uygun gördüm, ve o ComboBox’a hepsini yerleştiriyoruz.

 

for(int i=0;i<=hepsi.Length-1;++i)

comboBox1.Items.Add(hepsi[i].ServiceName);

 

Dediğim gibi eğer bütün servisleri istemiyorsak ve yalnızca bir servise mesela Windows’un “Bluetooth” servisini veya bi “IIS” servisine hitap etmek istiyorsak, servis ismimizi Form_Load’da belirtmemiz gerekmektedir. Şu şekilde:

 

serviceController1.ServiceName="BthServ";

veya

serviceController1.ServiceName="IISAdmin";

veya

serviceController1.ServiceName="Messenger";

gibi.

 

Form1_Load da yapacaklarımız şimdilik bu kadar. Bu kodu çalıştırdığımızda bütün servisleri görebiliyor olmamız lazım. Şimdi ise seçtiğimiz servisin kontrolünü yapmak için, o servisi serviceController1’e göstermemiz lazım. Bu iş için combobox’ın “SelectedIndexChanged“ event’ini kullanıyoruz.

 

private void comboBox1_SelectedIndexChanged(object sender, System.EventArgs e)

            {

                  serviceController1.ServiceName=comboBox1.SelectedItem.ToString();

            }

 

Form_Load’da kullanacağımız servisi kendimiz belirttiysek tabii ki bu evente ihtiyacımız olmayacak.

 

Şimdik sıra geldi seçtigimiz servisin durumunu öğrenip butonlarımızı ona gore aktif edelim, yani çalışan bir servis için “Başlat” butonun aktif olmasına gerek yok, ayni şekilde “Durmuş” olan bir servis için de “Durdur” butonun aktif olmaması gerekli, bu şekillede servisin durumunu kullanıcımıza göstermiş olacağız. Diğer bir taraftan bazı servisler duraklatılamamaktadır.

Bunun icin ben bir fonksiyon hazırladım bu fonksiyonla secili olan servisin durumuna göre butonlarımızı aktif veya deaktif  yapacağız..

 

private void durumlar()

      {

      //servisimizin durumunu aliyoruz

      string servis_durumu =  serviceController1.Status.ToString();

 

      //servisimizin durumunu kontrol ediyoruz

      if (servis_durumu == "Running")

      {

            //eger servis duraklatila biliyor ise

            if (serviceController1.CanPauseAndContinue == true)

                  {

                        btn_pause.Enabled = true;

                  }

                  else

                  {

                        btn_pause.Enabled = false;

                  }

                        btn_stop.Enabled = true;

                        btn_start.Enabled = false;

      }

      else if(servis_durumu == "Paused")

            {

                  btn_start.Enabled = true;

                  btn_pause.Enabled = false;

                  btn_stop.Enabled = true;

            }

            else if (servis_durumu == "Stopped")

            {

                  btn_start.Enabled = true;

                  btn_pause.Enabled = false;

                  btn_stop.Enabled = false;

      }

}

 

 

Gördüğünüz gibi serviceController1.Status ile servisin durumunu aldık ve  CanPauseAndContinue özellikleri ilede koşullarımızı koyup butonlarımızı hazır hale getirdik.

 

Sıra geldi en önemli noktaya servislerimizi butonlarımızla başlatma, duarklatma veya durdurmaya. Durmuş olan servisi başlatmak için tek yapılması gereken

 

serviceController1.Start();

 

ama  burada şöyle bir sorunla karşılaşabiliriz. O servisin çalışması için başka bir servisinde çalışması gerekiyor olabilir. Yani o servisin bir veya daha fazla servise bağlılığı olabilir. İlk önce bunu kontrol etmemiz gerekmektedir. Bunun için:

 

private void btn_start_Click(object sender, System.EventArgs e)

      {

      //iki secenek var, ya pause'den baslatiyoruz yada stop'dan

      if(serviceController1.Status.ToString() == "Paused")

      {

            serviceController1.Continue();

      }

      else if(serviceController1.Status.ToString() == "Stopped")

            {

//baslamasi icin gerekli olan diger servisleri olabilir onlari alalim

      ServiceController[] baglilar = serviceController1.ServicesDependedOn;

 

//eger birden fazla ise

            if (baglilar.Length >= 1)

            {

            foreach(ServiceController bagli in baglilar)

                  {    

                  //bagli olduklarinin calistigina emin oluyoruz.

                  if(bagli.Status.ToString() != "Running" || bagli.Status.ToString() != "Paused")

                        {

 

                        if (MessageBox.Show("Çaliştirmak istediginiz servis'in bunada ihtiyaci var, onuda çaliştirmak istiyormusunuz?\n"+bagli.DisplayName, "Gerekli başka servis var", MessageBoxButtons.YesNo).ToString() == "Yes")

                        {

                        //Onuda baslatiyoruz

                        bagli.Start();

                  bagli.WaitForStatus(ServiceControllerStatus.Running);

                        }

                        else

                        {

                        //yoksa vazgeciyoruz.

                        return;

                        }

                        }

                  }

            }

            //kendisini calistiriyoruz

            serviceController1.Start();

      }

      serviceController1.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running);

      //butonlarin durumlarini ayarliyoruz

      durumlar();

}

 

Aynı güvenlik önlemleri servisleri durdurkende geçerli, ilk once o servisin durdurulabilir olduğuna bakıyoruz, daha sonra kendisine bağlı servislerin listesini alıyoruz, onları durdurduktan sonra, asıl servisimizi durduruyoruz, şöyle;

 

 

private void btn_stop_Click(object sender, System.EventArgs e)

{

//durdurulabilir olduguna emin olmak icin kontrol ediyoruz .

if (serviceController1.CanStop == true)

{

      //kendisine bagli servislerinde durmasi icin, onlari aliyoruz

      ServiceController[] baglilar = serviceController1.DependentServices;

     

      //birden fazla olabilir

      if (baglilar.Length >= 1)

            {

            foreach(ServiceController bagli in baglilar)

            {

            //o servisinde durduguna eminmiyizzz.

            if(bagli.Status.ToString() != "Stopped")

                  {

                                         if (MessageBox.Show("Kendisine bagli asagidaki servisde sonlandirilacak?\n"+bagli.DisplayName, "Ona bagli duracak olan servisimiz", MessageBoxButtons.YesNo).ToString() == "Yes")

                                               {

                                               //durduruyourzzzz

                                               bagli.Stop();

                                               bagli.WaitForStatus(ServiceControllerStatus.Stopped);

                                   }

                                          else

                                         {

                                               //iptal ediyoruz hepsini

                                               return;

                                         }

                                   }

                             }

                        }

                        //durduruyoruz servisi

                serviceController1.Stop();

                        serviceController1.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped);

                        durumlar();

                  }

            }

     

Çalışan bir servisi ise duraklatmak için yapmamız gerekenler daha kolay, ilk olarak duraklatılabilir mi ona bakıyoruz, daha sonra çalıştığından emin olup, duraklatıyoruz, en son olarakda butonların yeni şekillerini almasi için fonksiyonumuzu çagırıyoruz.

 

 

private void btn_pause_Click(object sender, System.EventArgs e)

{

//bu servisin pause'ye izin verip vermedigine bakiyoruz

      if (serviceController1.CanPauseAndContinue == true)

      {

            //caliştigindan emin isekk

            if(serviceController1.Status.ToString() == "Running")

                  {

                        serviceController1.Pause();

                  }

 

                        serviceController1.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Paused);

      durumlar();

      }

}

 

Ve son olarak olarak Form_Load’ımıza ilk olarak bir servisin seçili gelmesi icin combobox’umuzun 0 ıncı elemanını seciyoruz, Form_Load ın en son hali şöyle;

 

private void Form1_Load(object sender, System.EventArgs e)

{

      //butun servileri getiriyoruz

      ServiceController[] hepsi= ServiceController.GetServices();

 

      //onlari comboxa yerlestiriyoruz

      for(int i=0;i<=hepsi.Length-1;++i)

            comboBox1.Items.Add(hepsi[i].ServiceName);

 

      comboBox1.SelectedIndex=0;

      durumlar();

 

}

Formun en son hali ise yandaki gibidir. Projenin bütün kodları ektedir. Herkese iyi çalışmalar.

Not: Programda geliştirilebilir yani, sistemdeki servislerin çalıştırılamaması veya durdurulamaması durumunda bir hata vermemesidir. Bu gibi gerçekleştirilemeyen işlemler bir exception ile yakalanabilir. Ayrıca System.ServiceProcess namespacini eklemeyi unutmayın.

Çeliker Bahçeci
celiker@gmail.comÖrnek Dosyalar