Makale Özeti

Küçük bir program yazarak, C#.NET’de Threading, XML-XSL ve basit olarak bazı IO sınıflarına değineceğiz. Bilgisayarımızdaki Microsoft Word dökümanlarını bulan, özet bilgilerini ve döküman özelliklerini alıp, bir XML dosyasında depolayan ve bize sonuçları listeyerek görüntüleyen bir program yazalım.

Makale

Merhaba;

 

Küçük bir program yazarak, C#.NET’de Threading, XML-XSL ve basit olarak bazı IO sınıflarına değineceğiz.

 

Yazacağımız Program;


Bilgisayarımızdaki Microsoft Word dökümanlarını bulan, özet bilgilerini ve döküman özelliklerini alıp, bir XML dosyasında depolayan ve bize sonuçları listeyerek görüntüleyen bir program yazalım.

 

 

Plan / Senaryo;

 

Programı yazmaya başlamadan önce plan yapalım. Sonuca adım adım yaklaşalım.

 

  1. Döküman araştırma;
    Bir buton olsun, tıklayınca klasör seçme penceresi açılsın, klasör seçildikten sonra, seçilen klasör ve alt klasörlerindeki *.doc uzantılı tüm dosyaların adresleri alınsın. Adresler alındıktan sonra, ikinci adımı tetikleyen buton görünür hale gelsin.
  2. Görünür hale gelmiş olan bu butona tıklandığında, elde ettiğimiz sonuçlar ile  Microsoft.Office.Interop.Word namespace i içerisinde bulunan Microsoft.Office.Interop.Word.Document nesnesi ve özelliklerini kullanarak bulunan dökümanların bilgilerini alınsın. Bu işlem tamamlanınca bilgilerin kaydedilmesini ve görüntülenmesi olaylarını tetikleyen bir buton daha görünür hale gelsin.
  3. Kaydet ve Sonuçları Görüntüle butonuna tıklandığında, bilgileri XML’e kaydetsin ve sonuçları görüntülesin.

 

 

 

Başlayalım;

 

Yeni bir C# WindowsApplication oluşturalım, ben ‘Döküman Araştırıcısı’ adını verdim. ( Biraz kötü bir isim oldu ama, önemli değil. J )

İlk olarak bu 3 butonumuzu oluşturalım, ben ToolStrip kontrolü içerisinde butonları oluşturdum ve ‘arastir_btn’, ‘bilgial_btn’, ‘kaydetgoruntule_btn’ isimlerini verdim.

Üzerlerine yazılarını yazdım ve yazıların görünmesi için, bu ToolStrip butonlarının ‘DisplayStyle’ özelliklerini ‘Text’ olarak belittim. Sonradan görünür olacak olan ‘bilgial_btn’, ‘kaydetgoruntule_btn’ butonlarının ‘Visible’ özelliğini ‘false’ olarak belirttim.

O an gerçekleştirilen işlemleri kullanıcıya belirtmek için bir de Label ekledim ve ‘durum_lbl’ adını verdim.

‘Araştır’ butonumuza tıkladığımızda açılacak olan FolderBrowserDialog’u da ekledim ve ‘klasor_secme_dialog’ adını verdim.

 

 

 

Şimdi ilk işlemimiz olan dökümanları araştırma işlemine geçmeden önce:

using Microsoft.Office.Interop.Word;

using System.IO;

using System.Threading;
using System.Collections;


Namespaceleri tanımlamayı unutmayalım. (
Microsoft.Office.Interop.Word namespaceini kullanabilmek için, ‘Solution Explorer’ da sağ tuşa tıklayarak ‘Add Reference...’ diyelim. Açılan pencerede ‘COM’ bileşenleri sekmesinden ‘Microsoft Word 11.0 Object Library’ yi seçelim. Ve artık projemize eklendi.)

 

Class içerisine:

 

ArrayList bulunan_dokumanlar;

string arama_klasoru;

int aranan_klasor_sayisi = 0;

string xmlolusturulan;

 

Değişkenlerimizi tanımlayalım.

 

Ve artık ilk işlemimiz olan dökümanları araştırma işlemine geçebiliriz:

 

‘Araştır’ butonumuzun ‘Click’ olayına;

 

 

        private void arastir_btn_Click(object sender, EventArgs e)

        {

            bilgial_btn.Visible = false;

            kaydetgoruntule_btn.Visible = false;

 

            DialogResult klasor_secimi = klasor_secme_dialog.ShowDialog();

            if (klasor_secimi == DialogResult.OK)

            {

                durum_lbl.Text = "Lütfen Bekleyin Arama yapılıyor...";

                bulunan_dokumanlar = new ArrayList(); // Klasörlerde bulunacak yeni dökümanlar, bu diziye eklenecek.

                arama_klasoru = klasor_secme_dialog.SelectedPath; // Klasör seçme dialogundan, seçilen klasör alınıyor.

                aranan_klasor_sayisi = 0;

 

                ThreadStart klasor_arastirma_thread = new ThreadStart(klasor_arastir); // Arama işlemi başlıyor

                Thread islem = new Thread(klasor_arastirma_thread);

                islem.Start();

 

            }

 

        }

 

 

Gördüğünüz gibi, birazdan yazacağımız ‘klasor_arastir’ metodunu Thread kullanarak çalıştıracağız.

 

Thread bir programın aynı anda birden fazla işlem yapmasını sağlar. Aslında birden fazla işlem yapmaz, tüm işlemleri küçük küçük bir ondan bir bundan yaparak aynı anda yapılıyor gibi olmasını sağlar.

 

Soru : Biz burada neden Thread kullanacağız?

Bir arama işlemi yaptırmak istiyoruz, tahmin edeceğiniz gibi bu işlem her zaman saniyeler alacak bir işlem olmayacaktır. Büyük bir klasörde arama yapmak daha uzun sürecektir. Uzun sürecek bir arama işleminde Thread kullanmazsak programımız bu işlemi yaparken hiçbir şekilde tepki vermeyecektir, uzun süre tepkisiz kalan bir program kullanıcı tarafından, ‘ÇÖKTÜ!!’, ‘DONDU!!’, ‘HATA VERDİ!!’,... gibi tanımlanacak ve kapatılmaya zorlanacaktır. Bunu engellemek için programımızın arama işlemi sırasında kullanıcı ile iletişim halinde olmasını sağlamamız gerekir. Bir yandan arama yapılırken bir yandan da ‘aranılan klasör’, ‘bulunan döküman sayısı’ gibi bilgiler kullanıcıya belirtilir ise kullanıcı herşeyin normal olarak devam ettiğinden emin olacak ve programın işlemi bitirmesini bekleyecektir.

 

Devam edelim;

Birazdan ‘klasor_arastir’ metodunu yazacağız, bu metod ‘arastir’ metodunu çalıştıracak, ‘arastir’ metodu araştırma işlemini yapacak ve bir taraftan da ‘aranılan klasör’, ‘bulunan döküman sayısı’ gibi bilgileri Ana Thread’de oluşturulmuş olan formumuzdaki labellara yazacak. Ancak .NET 2005’de bu şekilde Thread kullanımı, çok Thread kullanıldığında başka bir Thread’de oluşturulmuş bir nesnenin başka bir Thread’den değiştirilmesi işlemlerde karışıklık, hata yada çakışma gibi senkronizasyon problemlerine yol açabileceği için engellemiştir.

Ama bizim şu andaki durumumuzda Ana Thread’den başka sadece bir tane Thread’imiz olduğu için basit olarak bu engelleme özelliğini iptal ederek işlemlerimize devam edebiliriz.

İptal etmek için, Formumuzun oluşturucu metoduna;

 

   Control.CheckForIllegalCrossThreadCalls = false;

 

Komutunu yazalım.

 

Ve nihayet, ‘klasor_arastir’ metodumuzu yazabiliriz.

 

 

        private void klasor_arastir()

        {

 

            arastir();

            // 'arastir' metodunu ilk kez burada çalıştırıyoruz. Bu metod sürekli kendi içinde çalışarak, tüm alt klasörleri tarayacak ve bunan dökümaları tanımladığımız ArrayList e ekleyecek.

            if (bulunan_dokumanlar.Count > 0)

            {

                bilgial_btn.Visible = true;

            }

            else

            {

                MessageBox.Show("Hiç Microsoft Word Dökümanı Bulunamadı!");

            }

            aranilan_klasor_lbl.Text = "";

 

        }

 

        private void arastir()

        {

            try

            {

                string[] aranan_klasor_kontrol = arama_klasoru.Split('\\');

                if (!(aranan_klasor_kontrol[1] == "Windows" || aranan_klasor_kontrol[1] == "RECYCLER" || aranan_klasor_kontrol[1] == "System Volume Information"))

                {

                    // O an bulunulan klasörün sistem klasörü olup olmadığı kontrol edildi.

 

                    aranan_klasor_sayisi++;

                    string[] dosyalar = Directory.GetFiles(@arama_klasoru); // Araman klasördeki dosyaları incele

                    aranilan_klasor_lbl.Text = @arama_klasoru;

                    // Bulunulan klasör içerisindeki dosyalardan, Microsoft Word dökümanı olanlar ArrayListe ekleniyor.

                    for (int i = 0; i < dosyalar.Length; i++)

                    {

                        if (dosyalar[i].EndsWith(".doc")) // Sonu '.doc' ile biten dosyalar kontrol ediliyor

                        {

                            string[] kontrol = dosyalar[i].Split('\\'); // Dosyanın adresi parçalanarak, adı alınıyor

                            if (!kontrol[kontrol.Length - 1].StartsWith("~$")) // Dosyasının adının başında '~$' var ise, bu Microsoft Word dökümanının o anki çalışma zamanında oluşturduğu dosyadır, böyle dosyaları almayacağız

                            {

                                bulunan_dokumanlar.Add(dosyalar[i]); // Bulunan döküman 'bulunan_dokumanlar' ArrayList'ine ekleniyor

                            }

                        }

                    }

 

                    // Bulunulan klasörün alt klasörleri araştırılıyor

                    string[] klasorler = Directory.GetDirectories(@arama_klasoru);

                    for (int i = 0; i < klasorler.Length; i++)

                    {

 

                        arama_klasoru = klasorler[i]; // Araştırılacak klasör adresi, 'arama_klasoru' değişkenine eşitleniyor.

                        arastir(); // Metod kendi içinde tekrar çalıştırılıyor. 'arama_klasoru' değişkeninin eşitlendiği adresi tarayacak.

 

                    }

 

                    durum_lbl.Text = "Toplam " + aranan_klasor_sayisi.ToString() + " klasör arandı, " + bulunan_dokumanlar.Count.ToString() + " tane Microsoft Word dökümanı bulundu.";

                }

 

            }

            catch (Exception hata)

            {

                // Çeşitli hatalar olabilir

            }

        }

 

 

Thread olarak çalıştırdığımız ‘klasor_arastir’ metodu, ‘arastir’ metodunu çalıştırıyor, ‘arastir’ metodu, ilk başta bir folderBrowserDialog olan ‘klasor_secme_dialog’ nesnesi ile seçilen klasörü ve alt klasörlerini araştırıyor, eğer bir işletim sistemi klasörü ile karşılaşırsa araştırmadan geçiyor. Araştırdığı klasörlerde bulduğu dökümanları bir ArrayList olan ‘bulunan_dokumanlar’ a ekliyor ve araştırdığı klasörün alt klasörlerini araştırmak için kendisini yine çalıştırıyor, yeni çalışan ‘arastir’ metodu da aynı işlemleri yaparak o da alt klasörünü araştırmak üzere bir tane daha kendisinden çalıştırıyor eğer daha derine inmek için başka alt klasör kalmadı ise, işi bitiyor, ve kendisini çalıştıran ‘arastir’ metodundaki for döngüsünde argüman 1 artarak ikinci alt klasörü araştırmak için kendisinden bir tane daha çalıştırıyor. Tüm klasörler araştırıldığında ‘arastir’ metodunun işi bitiyor ve ‘klasor_arastir’ metodunda bir sonraki komut çalışıyor, eğer hiç döküman bulunamadı ise, bir uyarı penceresi açılıyor ve ‘Hiç Microsoft Word Dökümanı Bulunamadı!’ mesajını veriyor, bulundu ise, ikinci butonumuz olan ‘Döküman Bilgilerini Al’ butonu görünür hale geliyor. Araştırılan klasörün belirtildiği Label’ın yazısı siliniyor.

 

 

Ve ilk işlemimiz olan araştırma işlemimizi tamamlamış oluyoruz.

 

Geriye kalan, dökümanların bilgilerini alma ve sonuçları görüntüleme kısımlarına, makalemizin 2.bölümünde devam edeceğiz.

 

Teşekkürler.

 

Alper Özçetin
alperozcetin@gmail.com

alper@grupbf.com

Ornek Kodlar