.NET Framework kategorisi blog kayıtları
HTML Application - [HTA Applications] Ümit Öncel

Yazar : Ümit Öncel

 

HTML Application ya da kısaca HTA, ilk olarak 1997 yılında Microsoft tarafından piyasaya çıkartılmış olan alternatif bir Windows uygulaması geliştirme dili. En güzel yanı ise Windows uygulamaları geliştirmek için sadece HTML bilmenin yeterli olması. Basit HTML komutları ile bir uygulama geliştirebileceğiniz gibi, hazırlamakta olduğunuz HTA?yı etkileşimli hale getirmek için script dillerini de kullanabilirsiniz. CSS desteği de sunan HTA, aynı zamanda kendine özgü bazı ek özelliklere de sahip.

Tüm bunlar sayesinde .hta uzantılı bu dosyalar bir HTML sayfasının sahip olduğu tüm avantajlara sahip olabiliyorlar. Daha da iyisi Windows tarafından güvenilir uygulamalar (Trusted Application) olarak kabul edilen HTA?lar, Web sayfalarından farklı olarak güvenlik ile ilgili kısıtlamalar ile karşılaşmadan çalışabiliyor. Eğer internet üzerinden veya farklı bir dış kaynaktan kullanılıyorsa, aynı EXE dosyalarında olduğu gibi kullanıcıya bir kez uygulamayı çalıştırmak mı yoksa kaydetmek mi istediği soruluyor. HTA dosyasını kendi bilgisayarınıza aldıktan sonra ise dilediğinizde sorunsuz olarak kullanabiliyorsunuz.

Bunun için tek yapmanız gereken hazırladığınız HTML dokümanını .hta uzantısı ile kaydetmek. Bundan sonra HTA?larınız, .exe uzantılı bir dosya gibi çalışmaya başlayacaktır.

 

C# veya VB gibi daha sofistike yazılım geliştirmeleri varken, HTML tabanlı bir Windows uygulaması geliştirmek pek çok kişiye ilk bakışta gereksiz gibi gelebilir. Ama özellikle geliştirmek istediğiniz uygulamalar çok karmaşık değilse, HTML?in basitliği size daha hızlı ve pratik bir yoldan işinizi tamamlama imkanı sunacaktır. Yapmak istediğiniz basit işlemler için C# veya VB gibi diller abartılı kaçabilir. Oysa HTA sayesinde sadece Not Defteri?ni kullanarak dilediğiniz script?i yazabilir, HTML?in avantajlarından faydalanarak basit ve göze hoş gelen bir arabirim hazırlayabilirsiniz. Üstelik tüm bunlar birkaç dakika içerisinde tamamlanabilir.

Şu anda tüm bunları bir HTML dokümanı ile de yapabileceğinizi düşünüyor olabilirsiniz, fakat ne yazık ki bu mümkün olamayacaktır. Internet Explorer veya benzer bir tarayıcıda pek çok güvenlik önlemi yer almaktadır. Hiç birimiz bir internet üzerinden eriştiğimiz bir sayfanın client-side script?ler çalıştırarak sistemimizi baştan aşağıya kendi istediği gibi yapılandırmasını istemeyiz. Dolayısıyla bir tarayıcı içerisinde çalışacak HTML sayfalarında bu tip script?ler çalıştırmak mümkün olmayacaktır. En iyi ihtimalle sayfada bir ActiveX kontrolü çalıştırılacağına dair bir uyarı ile karşılaşırız ve biz onaylamadan bu tip bir işlem gerçekleşemez.

Fakat aslında kökenlerini bir HTML sayfasından alıyor olmasına rağmen HTA?lar, tarayıcıların bu kısıtlamaları ile karşılaşmazlar. Bunun nedeni ise HTA dokümanlarının Internet Explorer ile değil, Microsoft tarafından sadece HTA dokümanlarını çalıştırmak üzere geliştirilen Mshta.exe ile çalıştırılmasıdır. Bu sayede HTA?lar client-side script?leri rahatlıkla çalıştırabilirler ve hiçbir uyarı ile de karşılaşmazlar. HTA?ların aynı EXE?lerde olduğu gibi okuma ve yazma iznine sahip olduklarını da hesaba katınca HTML?e göre bazı artıları olduğu daha iyi görülebiliyor.

Bunlar tabi ki Windows?un temel güvenlik önlemlerinin ortadan kaldırabileceği anlamına gelmez. Örneğin HTA ile kullanıcının izni olmayan hiçbir işlem gerçekleştirmek mümkün olmayacaktır.

 

 

 

 

 

 

Daha önce de söylediğimiz gibi HTA?ları hazırlamak son derece kolay. Not Defteri?ni açıp aşağıdakileri yazdıktan sonra .hta uzantılı olarak kaydederek ilk HTA?nızı hazırlayabilirsiniz.

 

<HTML> 
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-9">
<TITLE>İlk HTA Dokümanı</TITLE>
</HEAD>
<BODY>
HTA ile programlamaya başladınız bile?
</BODY>
</HTML>

 

Görüntüsü şu şekilde karşınıza gelmiş olmalı:

 

 

 

Gördüğünüz gibi bir HTML dokümanından hiçbir farkı olmamasına rağmen, internet tarayıcısında içerisinde açılmak yerine, bir Windows uygulaması olarak çalıştı. Bunu sağlayan dosyanın Windows tarafından tanınan .hta uzantısına sahip olması. HTA?nın kendine özgü özellikleri kullanabilmek için ise tek yapmanız gereken kodun <HEAD></HEAD> bölümleri arasında <HTA:APPLICATION etiketini eklemeniz.

 

Şimdi de yazmış olduğumuz kodu şu şekilde geliştirelim:

 

<HTML> 
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-9">
<TITLE>İlk HTA Dokümanı</TITLE>
 
<HTA:APPLICATION ID="Kimlik" 
APPLICATIONNAME="IlkHTA"
border="thick"
caption="yes" 
maximizeButton ="yes" 
minimizeButton ="yes"
showInTaskBar ="no"
singleInstance ="yes"
sysMenu ="yes"
windowState ="maximize">

</HEAD>
<BODY>
HTA ile programlamaya başladınız bile?
</BODY>
</HTML>

 

 

Görünüşte pek bir fark yok değil mi? Aslında son eklediğimiz satırlar ile birkaç önemli farka kavuşmuş oldu. İlk olarak bu kez program tam ekran açıldı. Çalıştırdığınızda görev çubuğunda yer almıyordu. Ve son önemli değişiklik ise sağ tuş ile tıkladığınızda karşınıza bir menü gelmiyor olmasıydı. Tüm bunları (ve biraz daha fazlasını) bu birkaç satır ile sağladık.

 

Aslında bu ufak gibi görünen detaylar, geliştireceğiniz bir uygulama için çok faydalı olabilir. Şimdi bu özel HTA komutlarının en önemlilerinin neler olduklarına bir göz atalım:

 

APPLICATION ID

Windows`un Script yorumlayıcısının kontrol edeceği kimlik bilgisi. Scipt?ler Id.applicationName şeklinde diğer özelliklerin kullanılabilmesini sağlarlar.


applicationName

Programınızın adı. Eğer SingleInstance kullanmak istiyorsanız, programın başka bir instance?ın çalışıp çalışmadığını kontrol edebilmesi için bir isim verilmesi şarttır.

 

border

Program çerçevesinin kalınlık değerini ifade eder. Thick (kalın), thin (ince), dialog(dialog pencesi), none (yok), normal olarak değer alabilir. Border değerinin ?none? olması başlık çubuğunu ve çubuktaki tüm öğeleri, çerçeve ile birlikte ortadan kaldırır. Border ?thin? olduğu zaman pencerenin boyutunu kenarlarından fare yardımı ile değiştirmek mümkün olmaz.


borderStyle

Programın içeriğindeki çerçevelerin stilini ifade eder. sunken(gömülü), raised(çıkıntılı), complex(aynı anda hem gömülü, hem çıkıntılı), static(standart) veya normal şeklinde değer alabilir.

 

caption

Programın başlık çubuğunu görüntülenip görüntülenmeyeceğine dair bir Boolean değer alır.

 

commandLine

Varsayılan bir değer taşımayan bu özellik, script ile kullanıldığında, .hta dosyasının çağırıldığı yolu taşıyan bir string döndür. alert("commandLine    = " + Id.commandLine) şeklinde kullanılabilir.

 

contextMenu

Sağ tuş ile tıklandığında ortaya çıkan menünün gösterilip gösterilmeyeceğine dair Boolen bir değer atanabilir.

 

icon

Programınızın sol üst köşesinde görünecek olan 32x32 piksel büyüklüğünde .ico uzantılı simgeyi tanımlamak için string türünden bir yol bilgisi atanabilir.

 

maximizeButton

Başlık çubuğunda büyütme simgesinin görüntülenmemesi için ?no? demelisiniz.


minimizeButton

Başlık çubuğundan programın küçültme imkanı vermek istemiyorsanız ?no? değeri vermelisiniz.

 

navigatable

Çalıştırılan ilk HTA dosyasının içerisinden, farklı HTML dosyalara verilen bağlantıların aynı pencere içerisinde kullanılıp, kullanılmayacağına dair string bir değer atanır. Eğer değer ?no? ise, bağlatı yeni bir tarayıcı içerisinde açılır. ?yes? ise HTA penceresi içerisinde görüntülenir.

 

scroll

Kaydırma çubuklarının kullanılıp kullanılmayacağını ifade eder. ?yes?, ?no? veya ?auto? olarak değer alabilir.

 

scrollFlat

Kaydırma çubuğunun üç boyutlu mu yoksa düz bir görüntüye mi sahip olacağını ifade eder.

 

selection

Fare veya klavye yardımıyla içeriğin seçili hale getirilip getirilemeyeceğini ifade eder. Varsayılan değeri ?yes?, yani seçime izin verme yönündedir.

 

showInTaskBar

Programın görev çubuğunda görünmesini istemiyorsanız ?no? yazmalısınız. Fakat bu durumda yine de ALT + TAB ile uygulamaya ulaşılabilir.


singleInstance

Bir kez çalıştırıldıktan sonra, yeniden farklı bir pencerede bir kez daha açılmasını istemiyorsanız buna da ?no? demelisiniz.

 

sysMenu

Programın başlık çubuğundaki, küçültme, büyütme ve kapatma simgelerini ortadan kaldırmak istiyorsanız ?no? yazmalısınız.

 

version

Hazırladığınız programın versiyon bilgisini taşımak için string bir değer atanabilir.


windowState

Program çalıştırıldığında açılacak olan pencerenin boyutunu belirler. Tam ekran açılması için ?maximize?, görev çubuğunda simge olarak açılması için ?minimize?, Internet Explorer?ın varsayılan büyüklüğünde açılması için ise ?normal? değeri atanabilir.

 

 

Bu özellikler ağırlıklı olarak, HTA?nın çalıştığı Windows penceresini kullanımına yönelik. Diğer yandan HTML ile yapılabilecekleri zaten biliyoruz. HTA?nın, HTML?den en büyük farkının script?leri kullanmak olduğunu söylemiştik. Dolayısıyla bu aşamadan sonra sıra scriptlerinizi eklemeye geldi.

Aynı HTML?de olduğu gibi bu da oldukça basit bir işlem. Tek yapmanız gereken <script></script> etiketleri içine kodunuzu yazmak. İşte VBScipt ile hazırlanmış ufak bir örnek. Bu örnek yardımıyla bilgisayarınızda çalışan işletim sistemi sayfaya yazdıracağız.

 

Aşağıdaki kodu çalıştırdığınızda karşınıza gelen görüntü şu şekilde olacak:

 

 

 

<head>
<title>HTA ile İşletim Sistemi Bilgisi Almak</title>
<HTA:APPLICATION 
     APPLICATIONNAME="IsletimSistemBilgisi"
     SCROLL="yes"
     SINGLEINSTANCE="yes"
</head>
 
<script language="VBScript">
    Sub IsletimSisteminiOgren
        strComputer = "."
        Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
 
        Set colOperatingSystems = objWMIService.ExecQuery _
            ("Select * from Win32_OperatingSystem")
 
        For Each objOperatingSystem in colOperatingSystems
            DataArea.InnerHTML = objOperatingSystem.Caption & " " & _
                objOperatingSystem.Version
        Next
 
    End Sub
</script>
 
<body>
<input type="button" value="İşletim Sistemi" name="run_button" onClick="IsletimSisteminiOgren">
<p>
<span id = "DataArea"></span>
</body>

 

Bu, HTA?yı kullanarak yapabileceklerinize dair basit bir örnek. İhtiyaçlarınız doğrultusunda bundan çok daha fazlasını yapmak mümkün. Fakat ne yazık ki HTA geliştirmek ile ilgili kaynak bulmak pek kolay değil. Eğer HTA?nızda script?leri nasıl kullanabileceğinize dair daha fazla yardıma ihtiyacınız varsa, oldukça faydalı örnek kodlar içeren HTA Helpomatic adlı aracı şu adresten temin edebilirsiniz:

http://www.microsoft.com/downloads/details.aspx?FamilyId=231D8143-F21B-4707-B583-AE7B9152E6D9&displaylang=en


IEnumerable ve IEnumerator Arayüzleri ve Kullanımı

          Bu makalemiz de IEnumerable ve IEnumerator Interfacelerinden bahsediyor olacağız. Makalemize şöyle bir soru ile başlayalım. Normal şartlar altında bir dizi ile veya bir ArrayList nesnesi ile  kullandığımız foreach döngüsünü kendi yazdığımız  sınıf için de kullanabilir miyiz ?

Cevap : Hayır J

 

int[] sayilar=new int[10];

ArrayList liste = new ArrayList();

 

Yukarıdaki nesnelerin hepsinde foreach döngüsü ile çalışabiliriz. Fakat sorumuz şu ki :

 

class Ogrenci

{

}

 

class Sinif

{

            Ogrenci[] ogrenciler = new Ogrenci[20];

}

 

Sinif liste = new Sinif();

foreach (Ogrenci ogr in liste)

{

            //Kodlarımız...

}

 

şeklinde kullanamayız. Bunun sebebi foreach döngüsü üzerinde gezineceği nesnenin IEnumerable ve IEnumerator dedigimiz interfaceler den implemente etmiş olmasını ister.

Foreach döngüsü koleksiyonlar ve diziler üzerinde ilerlemek üzere hazırlanmıştır. Peki ben kendi yazdığım sınıf ile foreach döngüsünü kullanmak istiyorsam ne olacak ?

 

            Makalenin bundan sonraki bölümüne örneğimiz üzerinden devam edelim. Örneğimizde Ogrenci adında  bir class ve bir de Sinif isminde bir class olacak.

 

Ogrenci.cs :

    public class Ogrenci

    {

        public string isim;

        public string soyisim;

 

        public Ogrenci(string Isim, string  SoyIsim)

        {

            this.isim = Isim;

            this.soyisim = SoyIsim;

        }

    }

 

Sinif.cs :

 

    public class Sinif:IEnumerator,IEnumerable

    {

        Ogrenci[] liste = new Ogrenci[0];

 

        public void OgrenciEkle(Ogrenci ogr)

        {

            Array.Resize(ref liste, liste.Length + 1);

            liste[liste.Length - 1] = ogr;

        }

 

        public Sinif()

        {

        }

 

        int ind = -1;

 

        #region IEnumerator Members

 

        public object Current

        {

            get { return liste[ind]; }

        }

 

        public bool MoveNext()

        {

            if (++ind < liste.Length)

                return true;

            else

                return false;

        }

 

        public void Reset()

        {

            ind = -1;

        }

 

        #endregion

 

        #region IEnumerable Members

 

        public IEnumerator GetEnumerator()

        {

            return (IEnumerator)this;

        }

 

        #endregion

    }

 

Hazırladığımız iki sınıfı açıklayalım. Birinci class yani Ogrenci ismindeki sınıf sadece öğrenci bilgilerini taşımakla görevli. Ikinci class yani Sinif ise Ogrenci türünden degerleri alıp bunları kendi içerisinde ki Ogrenci dizisinde saklamakla görevli. Fakat Sinif ismindeki sınıfımızı foreach içerisinde kullanmaya çalıştığımız da eğer IEnumerable ve IEnumerator interface lerinden implemente etmezsek derleme anında şöyle bir hata alacağız :

 

foreach statement cannot operate on variables of type 'IEnumeratorIEnumerable.Sinif' because 'IEnumeratorIEnumerable.Sinif' does not contain a public definition for 'GetEnumerator'

Bu hata da belirtilen Sinif class ımızın GetEnumerator isminde bir üyeye sahip olmadığıdır. Foreach döngüsü çalışabilmek için bu metotu istediginden dolayı sınıfımızı IEnumerable interface den implemente etmeliyiz. Bununda haricinde foreach döngüsü tarafından kullanılan özel bir interface daha vardır ve üzerinde döndüğü koleksiyonda IEnumerator interface inin üyelerini görmek ister bunlar ise örnekte açıkça belirtilen

 

·         Current

·         MoveNext

·         Reset

 

üye metotları ve property leridir. Bu üyeler sayesinde foreach, sınıfımızın üzerinde gezerken dizinin elemanlarına ulaşabiliyor olacaktır.

 

IEnumerator Interface i hakkında detaylı bilgi için bu makaleden yararlanabilirsiniz

 

Örneğin Current isminde ki property okunduğu zaman kendisine Ogrenci[] dizimiz içerisinden index olarak üzerinde durulan Ogrenci sınıfını vereceğiz.

 

        public object Current

        {

            get { return liste[ind]; }

        }

 

Bu property ile ind ismindeki degiskenin degeri örnegin 5 ise Ogrenci dizimizin 5 indexli gözündeki Ogrenci sınıfını kullanıcıya object türünden geri döndürüyoruz.

 

MoveNext metotu :

 

  public bool MoveNext()

        {

            if (++ind < liste.Length)

                return true;

            else

                return false;

        }

 

Foreach döngümüz sınıf içerisinde ileri yönlü hareket edebilmek için MoveNext ismindeki metotumuzu kullanacaktır. Boolean türden deger döndüren bu metot döngüye dizinin son elemanına gelinip gelinmediğini bildirir. Böylece döngü ilerleyebildim mi yoksa ilerleyemedim mi gibi bir soruyu rahatlıkla sorabilir.

 

Reset ismindeki metot ise foreach döngüsünü dizinin ilk gözüne konumlandıracak olan metottur.

 

Bu kuralları uyguladıktan sonra artık sınıfınızı aşağıdaki şekilde kullanabilirsiniz :

 

 

            Sinif liste = new Sinif();

            liste.OgrenciEkle(new Ogrenci("haydar", "bağrıyanık"));

            liste.OgrenciEkle(new Ogrenci("muhittin", "Windows"));

 

            foreach (Ogrenci ogr in liste)

            {

                MessageBox.Show("Adı : " + ogr.isim+"\nSoyadı : "+ogr.soyisim);

            }

Bir sonraki makalede görüşmek üzere hepinize iyi çalışmalar

 

Sorularınız için mail adresim :   

bora.burgucugil@bilgeadam.com

BilgeAdam BTA Beşiktaş

 

 


WebBrowser kontrolü içerisinde office dökümanlarını açmak

Kendi geliştirdiğiniz windows forms uygulamaları içerisinde, webbrowser kontrolü aracılığı ile bir office dökümanı açmak isterseniz aşağıdaki gibi bir kod işinize yarayacaktır :

webBrowser1.Navigate("Dökümanın path bilgisi");

Fakat bu kod sonucunda eğer döküman bir word dosyası ise Microsoft Word'ün eğer başka bir office uygulamasına ait ise o uygulamanın açıldığını ve sizin webbrowser kontrolünüzün boş kaldığını görürsünüz. Özetle dökümanın tamamen sizin kontrolünüzün içerisinde açılması için aşağıdaki Registry ayarlarını yapmanız gerekmektedir. Fakat bu dosya içerisindeki atamaların çok dikkatli yapılması gerektiğinden ilk önce bir full Registry backup almanızı öneriyorum. Problem çıkarsa hemen geri dönmeniz için :)

Registry ayarları :

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Word.Document.8]
"BrowserFlags"=dword:80000024

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Word.RTF.8]
"BrowserFlags"=dword:80000024

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Word.Document.12]
"BrowserFlags"=dword:80000024

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Word.DocumentMacroEnabled.12]
"BrowserFlags"=dword:80000024

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Excel.Sheet.8]
"BrowserFlags"=dword:80000A00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Excel.Sheet.12]
"BrowserFlags"=dword:80000A00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Excel.SheetMacroEnabled.12]
"BrowserFlags"=dword:80000A00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Excel.SheetBinaryMacroEnabled.12]
"BrowserFlags"=dword:80000A00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PowerPoint.Show.8]
"BrowserFlags"=dword:800000A0

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PowerPoint.Show.12]
"BrowserFlags"=dword:800000A0

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PowerPoint.ShowMacroEnabled.12]
"BrowserFlags"=dword:800000A0

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PowerPoint.SlideShow.8]
"BrowserFlags"=dword:800000A0

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PowerPoint.SlideShow.12]
"BrowserFlags"=dword:800000A0

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\PowerPoint.SlideShowMacroEnabled.12]
"BrowserFlags"=dword:800000A0

Not: Bu kodları kopyalayıp bir txt belgeye yapıştırın. Dosyayı reg uzantısı ile kayıt edin ve sonrada dökümanı çalıştırın. İşlem tamam :)


İnternet Explorer içerisindeki URL listesi

İnternet explorer içerisinde yazmış olduğunuz URL bilgilerini otomatik tamamlayan listeye ulaşmak için Registry içerisinden aşağıdaki yolu kullanabilirsiniz :


HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\TypedURLs :)

Installer Class Kullanımı

Bu makalemizde geliştirdiğimiz uygulamamızın müşterilerimize veya farklı lokasyonlara kurulumu sırasında ?nasıl olacak?? sorusuyla kafamızı karıştıran bir sorunun cevabına yani program kurulumundan önce SQL Server üzerinde veritabanımızı kurmaya değiniyor olacağız.

Visual Studio 2005 ile birlikte çok başarılı ve yetenekli olan setup projelerimize Installer Class dediğimiz sınıflar sayesinde istediğiniz her işlemi yaptırabilirsiniz. Konuyu biraz daha açarak ilerleyelim. Kurulum sırasında veritabanının otomatik olarak kurulması işlemi sanırım hepimiz için yeterince önemlidir J. Makalemizde bu kurulum işlemini veritabanımızın scriptini çıkartarak, yazacağımız bir class library ile çözeceğiz.Yani kurulum sırasında kendi yazdığımız bir windows formunu ekrana getirecek ve kullanımızdan server bilgilerini alacağız, sonrasında ise scriptleri çalıştırarak veritabanını oluşturacağız.

Bu kadar konuşmadan sonra makalemizin içeriğine geçelim. Veritabanımız aşağıdaki gibidir.

 

USE [master]

GO

CREATE DATABASE [SetupDB] ON  PRIMARY

( NAME = N'SetupDB', FILENAME = N'C:\\Program Files\\Microsoft SQL Server\\MSSQL.1\\MSSQL\\DATA\\SetupDB.mdf' , SIZE = 3072KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )

 LOG ON

( NAME = N'SetupDB_log', FILENAME = N'C:\\Program Files\\Microsoft SQL Server\\MSSQL.1\\MSSQL\\DATA\\SetupDB_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)

 COLLATE SQL_Latin1_General_CP1254_CI_AS

GO

 

Tablolarımız :

*Ürünler Tablosu*

USE [SetupDB]

GO

CREATE TABLE [dbo].[Urunler](

      [UrunId] [int] IDENTITY(1,1) NOT NULL,

      [KategoriId] [int] NOT NULL,

      [UrunAdi] [nvarchar](50) COLLATE SQL_Latin1_General_CP1254_CI_AS NOT NULL,

      [BirimFiyat] [decimal](18, 2) NOT NULL,

 CONSTRAINT [PK_Urunler] PRIMARY KEY CLUSTERED

(

      [UrunId] ASC

)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]

) ON [PRIMARY]

GO

*Kategoriler Tablosu*

USE [SetupDB]

GO

CREATE TABLE [dbo].[Kategoriler](

      [KategoriId] [int] IDENTITY(1,1) NOT NULL,

      [UstKategoriId] [int] NULL,

      [KategoriAdi] [nvarchar](50) COLLATE SQL_Latin1_General_CP1254_CI_AS NOT NULL,

 CONSTRAINT [PK_Kategoriler] PRIMARY KEY CLUSTERED

(

      [KategoriId] ASC

)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]

) ON [PRIMARY]

 

GO

                Veritabanımızın kodlarını oluşturduktan sonra artık kodlarımıza geçebiliriz.

Not : Bu makalede anlatilan konu installer class ile veritabanı kurulumu olduğundan dolayı kurulumu yapılacak olan windows application içerisinde sadece basit bir mesaj verilmektedir.

      Visual Studio içerisinden yeni bir blank solution açıyoruz, ismine ise SetupMakale adını verelim.

 

      Daha sonra bu çözüm içerisine bir windows application ekleyeceğiz. Ismini ?PaketProgramWin? olarak belirleyelim.Windows application içerisinde bir buton yerleştirip Click olayında ise basit bir mesaj çıkartalım.

Artık setup projemize geçebiliriz.Solution içerisine yeni bir proje daha ekleyeceğiz fakat bu sefer proje şablonu olarak Setup Project seçeceğiz.

Bu projemizde Installer class kullanımını inceleyeceğiz. Setup projelerinin detaylı kullanımına aşağıdaki linkten erişebilirsiniz.

http://www.yazilimuzmani.com/Articles/Details.aspx?aId=1000000417

Setup programımızı oluşturduktan sonra sıra windows projemizi yani hedef makinede çalışacak olan programımızın çıktısını setup projemize dahil etmeye geldi. Bu işlemi yapabilmek için Solution Explorer içerisinde Setup projeniz üzerinden Add à Project Output seçeneğini seçip karşımıza gelen ekrandan PaketProgramWin projemisinin Primary Output yani çıktısını setup paketimize dahil ediyoruz.

 

 

Bu işlemi yaptıktan sonra setup projemiz kuruluma hazır ama bizim istediğimiz şekilde değil. J Bu adımdan sonra veritabanımızı kuracak olan Class Library projemize geçiyoruz. Aynı solution içerisine yeni bir proje daha ekleyeceğiz. Bu sefer Class Library projesini seçip ismine SetupDBKurulum adını verelim.

Class library projemize öncelikle bir referans vermemiz gerekiyor, bunun için class library System.Windows.Forms namespace?ini referans veriyoruz. Daha sonra library projemize yeni bir windows formu ekliyoruz. Formun görüntüsü aşağıdadır :

Veritabanı oluştur butonuna kliklendiğinde çalışacak kodları yamaya başlıyoruz. Öncelikle veritabanını oluşturacak bir metot hazırlıyoruz.

SqlConnection cn;

void VeriTabaniOlustur()

{

      string conStr = "server=" + txtServer.Text + ";uid=" + txtKullaniciAdi.Text + ";pwd=" + txtSifre.Text;

      cn = new SqlConnection(conStr);

      SqlCommand cmd = new SqlCommand();

      cmd.Connection = cn;

      cmd.CommandText = "USE [master];";

      cmd.CommandText += "CREATE DATABASE [SetupDB] ON  PRIMARY ";

      cmd.CommandText += "( NAME = N'SetupDB', FILENAME = N'C:\\Program Files\\Microsoft SQL Server\\MSSQL.1\\MSSQL\\DATA\\SetupDB.mdf' , SIZE = 3072KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )";

      cmd.CommandText += "LOG ON ";

      cmd.CommandText += "( NAME = N'SetupDB_log', FILENAME = N'C:\\Program Files\\Microsoft SQL Server\\MSSQL.1\\MSSQL\\DATA\\SetupDB_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)";

      cmd.CommandText += "COLLATE SQL_Latin1_General_CP1254_CI_AS ";

 

      try

      {

          cn.Open();

          cmd.ExecuteNonQuery();

      }

      catch (SqlException ex)

      {

          MessageBox.Show("Hata : \n" + ex.Message);

      }

      finally

      {

          cn.Close();

      }

}

Daha sonra tablolarımızı oluşturacak bir metot hazırlıyoruz.

void TabloOlustur()

{

    bool sonuc = true;

    SqlCommand cmd = new SqlCommand();

    cmd.Connection = cn;

 

    #region Urunler Tablosu

    cmd.CommandText = "USE [SetupDB];";

    cmd.CommandText+="CREATE TABLE [dbo].[Urunler](";

    cmd.CommandText+="[UrunId] [int] IDENTITY(1,1) NOT NULL,";

    cmd.CommandText+="[KategoriId] [int] NOT NULL,";

    cmd.CommandText+="[UrunAdi] [nvarchar](50) COLLATE SQL_Latin1_General_CP1254_CI_AS NOT NULL,";

    cmd.CommandText+="[BirimFiyat] [decimal](18, 2) NOT NULL,";

    cmd.CommandText+="CONSTRAINT [PK_Urunler] PRIMARY KEY CLUSTERED (";

    cmd.CommandText+="[UrunId] ASC";

    cmd.CommandText+=")WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]";

    cmd.CommandText+=") ON [PRIMARY]";

    try

    {

        cn.Open();

        cmd.ExecuteNonQuery();

    }

    catch (SqlException ex)

    {

        sonuc = false;

        MessageBox.Show("Hata : \n" + ex.Message);

    }

    finally

    {

        cn.Close();

    }

    if (!sonuc)

        return;

    #endregion

   

    #region Kategoriler Tablosu

    cmd.CommandText = "USE [SetupDB];";

    cmd.CommandText += "CREATE TABLE [dbo].[Kategoriler](";

    cmd.CommandText += "[KategoriId] [int] IDENTITY(1,1) NOT NULL,";

    cmd.CommandText += "[UstKategoriId] [int] NULL,";

    cmd.CommandText += "[KategoriAdi] [nvarchar](50) COLLATE SQL_Latin1_General_CP1254_CI_AS NOT NULL,";

    cmd.CommandText += "CONSTRAINT [PK_Kategoriler] PRIMARY KEY CLUSTERED (";

    cmd.CommandText += "[KategoriId] ASC";

    cmd.CommandText += ")WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]";

    cmd.CommandText += ") ON [PRIMARY]";

    try

    {

        cn.Open();

        cmd.ExecuteNonQuery();

    }

    catch (SqlException ex)

    {

        sonuc = false;

        MessageBox.Show("Hata : \n" + ex.Message);

    }

    finally

    {

        cn.Close();

    }

   

    if (!sonuc)

         return;

    #endregion

}

      Bu adımdan sonra kalan tek şey button1 e kliklenince bu iki metotu tetiklemek

 

private void button1_Click(object sender, EventArgs e)

{

    VeriTabaniOlustur();

    TabloOlustur();

}

 

Artık sıra geldi bu formu ekrana getirecek olan Installer sınıfına. Öncelikle class library projemize System.Configuration.Install namespace ini refere ediyoruz. Böylece System.Configuration.Install.Installer sınıfını kullanabilir hale geliyoruz. Bu sınıf Setup projelerinde

  • Install
  • Commit
  • Rollback
  • Uninstall

aşamalarında çalışarak istediğiniz her türlü işlemi yaptırabileceğiniz bir sınıf olmakla beraber kendisinden türeyen sınıflara 5 adet virtual metot sunmaktadır. Bunlar :

  • public virtual void Commit(IDictionary savedState);
  • public virtual void Install(IDictionary stateSaver);
  • public virtual void Rollback(IDictionary savedState);
  • public virtual void Uninstall(IDictionary savedState);

Bu metotlar ile kurulum işleminin herhangi bir aşamasına ulaşığ istediğiniz program çalıştırabilir veya istediğiniz komutları işletebilirsiniz.

 

Class Library projesinde yapılması gereken en son adım class a RunInstaller Attribute bildirme işlemidir.

 

Class ın son görüntüsü aşağıdaki gibidir:

 

using System;

using System.Collections.Generic;

using System.Text;

using System.ComponentModel;

 

namespace SetupDBKurulum

{

    [System.ComponentModel.RunInstaller(true)]

    public class Kurucu:System.Configuration.Install.Installer

    {

        public override void Install(System.Collections.IDictionary stateSaver)

        {

            frmBilgi frm = new frmBilgi();

            frm.ShowDialog();

 

            base.Install(stateSaver);

        }

    }

}

 

Son olarak setup paketimize class library projemizin çıktısını project output olarak ekliyoruz.

 

      Artık setup projemizde iki adet program çıktısı bulunmakta.

Bir tanesi PaketProgramWin.exe, diğeri ise SetupDBKurulum.dll

 

Şimdi setup projemizde Solution Explorer üzerinde bulunan custom actions editor e geliyoruz.

 

 

Bu editör içerisinde Install aşamasına sağ klik ve Add Custom Action diyoruz. Karşımıza gelen pencerede Application Folder altında bulunan SetupDBKurulum isimli proje çıktısını seçip Ok diyoruz, böylece kurulum yapılırken Install aşamasının sonuna doğru bilgi formumuz ekrana gelecek ve veritabanı kurulacaktır.

 

Not : Bu işlemi yaptıktan sonra mutlaka Setup projenize Rebuild işlemini uygulayınız

 

Not : Install denemelerinizi her zaman solution explorer üzerinde setup projesine sağ klik yaparak Install seçeneği ile yapınız.

 

Yaptığımız Install Denemesinde göreceğiz ki Install aşaması tamamlanmadan hemen önce karşımıza tasarladığımız form çıkmakta ve DB kurulumunu yapmakta.

 

Böylece hazırladığınız paket programlar için veritabanını nasıl göndereceğim problemini çözmüş oluyoruz.

 

Bir sonraki makalede görüşmek üzere herkese iyi çalışmalar

 

 

Bora BURGUCUGİL

bora.burgucugil@bilgeadam.com

 

BilgeAdam BTA Beşiktaş

Microsoft Certified Trainer

 


.NET Framework kaynak kodları

Visual Studio 2008 ile birlikte .NET Framework kaynak kodları üzerinde debug yapabiliyorsunuz. Nasıl yapılacağını öğrenmek için buradaki linkte bulunan adımları uygulayabilir ve sonuçlarından faydalanabilirsiniz :)

 


OpenCD-Rom Drive

API ile CD-ROM kapağını açmak için gerekli olan ufak kod parçası aşağıdadır.

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Text;

using System.Windows.Forms;

using System.Runtime.InteropServices;

namespace OpenCDROM_API

{

   public partial class Form1 : Form

   {

      [DllImport("winmm.dll")]

       static extern Int32 mciSendString(String command,

         StringBuilder buffer, Int32 bufferSize, IntPtr hwndCallback);

      public Form1()

      {

               InitializeComponent();

      }

      public void OpenCD()

      {

            IntPtr ptr = IntPtr.Zero;

            StringBuilder returnstring = new StringBuilder();

            mciSendString("set CDAudio door open", returnstring, 127, IntPtr.Zero);

      }

      private void Form1_Load(object sender, EventArgs e)

      {

               this.OpenCD();

      }

   }

}

 

İyi çalışmalar


GAC  a dll eklerken yaşanan problemin çözümü için link
http://support.microsoft.com/kb/306149
Global Assembly Cache problemi

Global Assembly Cache içerisine yazmış olduğunuz dll i eklerken, dll i Global Assembly Cache e attıktan sonra yapmanız gereken en önemli ve son adım :

Regedit editörü içerisinden :

[HKEY_CURRENT_USER\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders

altına bir adet yeni key olusturmak

ve içerisine bir key eklemek. Değer olarak ise dll dosyanızın bulunduğu lokasyonu veriyorsunuz

"C:\\MyDllFolder\\" gibi

Ve herhangi bir proje içerisinden Add Reference dediğinizde artık dll karşınızda :)

İyi çalışmalar