Ana Sayfa | English Blog | Seminer TV | Dil Cookie Sil  Blog'u Mail ile takip et!       
Daron Yöndem - September, 2008
bir yazılımcının tasarıları...
 Tuesday, September 30, 2008

Özellikle XLINQ ile beraber XML kullanımının daha da arttığını itiraf etmem gerek. XPATH yerine XML veriyi LINQ ile sorgulayabiliyor olmak yazılım geliştiricilerin çok daha cesurca XML kullanmaya yönelmesine neden oldu. Bu çerçevede Debug işlemlerinde de sıkça XML değişkenlerini incelemek durumunda kalıyoruz. Peki bu süreçte aşağıdaki gibi araçlarımız olsa işimiz kolaylaşmaz mıydı?

Hoş Geldin XML Visualizer

Visual Studio içerisinde ek bir Debug Visualizer olarak eklenen XML Visualizer ile beraber XML değişkenlerinde Debug modunda daha kolay bir inceleme ortamı sağlanıyor.

XML Visualizer iş başında.
XML Visualizer iş başında.

XML Visualizer'ın kendi ekranında ise birçok seçenek bulunuyor. Ekran ilk açıldığında XML kodlarını doğrudan Internet Explorer'ın motoru ile gösterdiği için Ctrl+F gibi arama işlemlerini kullanabiliyoruz.

XML Visualizer aslında IE'nin motorunu kullanıyor.
XML Visualizer aslında IE'nin motorunu kullanıyor.

İsterseniz görüntüye bir XSLT dosyası bağlayabileceğiniz gibi isterseniz farklı XPATH sorguları yazarak doğrudan elinizdeki XML'i sorgulayabilirsiniz de.

XPATH sorguları Debug verilerinde!
XPATH sorguları Debug verilerinde!

Nasıl yüklenir?

Hemen http://www.codeplex.com/XmlVisualizer adresinden XmlVisualizer.dll dosyasını bilgisayarınıza indirerek bilgisayarınızda C:\Users\Daron\Documents\Visual Studio 2008\Visualizers adresine kopyalayın. Bu adres tabi ki sizin bilgisayarınızdaki kullanıcıların adına göre değişecektir. Artık Visual Studio'yu tekrar açtığınızda yukarıdaki bahsettiğimiz tüm işlevleri kullanabileceksiniz.

Hepinize kolay gelsin.

Tuesday, September 30, 2008 12:37:08 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Visual Studio 2008  | 
 Monday, September 29, 2008

CETURK ile düzenlediğimiz "Microsoft Teknolojileri" günündeki WPF seminerimin video kaydını da sonunda hazırlayabildim. Bu sefer farklı bir taktik deneyerek hem bilgisayarımın ekranını kaydettim hem de kamera ile semineri kaydettik ve sonrasında bu iki görüntüyü birleştirerek çok kameralı bir görüntü oluşturdum :) Epey uğraştırdığını itiraf etmeliyim.

Edit (25.10.2009) : Bu video artık çok eski tarihli bilgiler içerdiği için blogumdan kaldırdım. Daha yeni videolar için SeminerTV bölümünü inceleyebilirsiniz.

Monday, September 29, 2008 11:21:43 AM (GTB Standard Time, UTC+02:00)  #    Comments [2]   Seminer | WPF  | 
 Sunday, September 28, 2008

Bu yazımızda Silverlight 2.0 RC0 ile Silverlight uygulaması içerisinde minik bir ekran koruyucusu yapacağız. Aslında amacımız ekran korumak değil tabi ki, istediğimiz şey kullanıcı Silverlight uygulamasını kullanmadığında farklı bir içerik göstermek. Bu belki bir reklam, belki farklı bir "Ekrana Geri Dön Kullanıcı" sesli mesajı veya çok daha farklı bir uyarı sistemi olabilir. Özellikle veritabanı üzerinden veri alarak bu veriyi düzenleyen bir Silverlight uygulamasını düşünürsek belki de kullanıcı uzun süre ekran başında değilse verileri sunucuya göndererek kaydetmek için doğru zamanı yakalamışız demektir. Bu sistemin kullanılabileceği diğer örnekleri sizin hayal gücünüze bırakıyorum.

Animasyonlarımızı hazırlayalım

Örneğimizde görsel olarak herhangi bir ek öğe yer almayacak. Kullanıcı fareyi hareket ettirmezse bir süre sonra uygulamanın ana Grid'inin rengini siyaha çevireceğiz. Kullanıcı fare ile herhangi bir hareket yaptığı anda ise tekrar söz konusu Grid'i beyaza çevireceğiz. Siz örneklerinizde çok daha farklı işlemler yapabilirsiniz. Şimdi gelin bu iki animasyonla beraber oluşan XAML kodumuza göz atalım.

<UserControl x:Class="SilverlightApplication2.Page"

            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

            Width="400"

            Height="300">

  <UserControl.Resources>

    <Storyboard x:Name="Gitti">

      <ColorAnimationUsingKeyFrames BeginTime="00:00:00"

                                    Storyboard.TargetName="LayoutRoot"

                                    Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">

        <SplineColorKeyFrame KeyTime="00:00:01"

                            Value="#FF000000"/>

      </ColorAnimationUsingKeyFrames>

    </Storyboard>

    <Storyboard x:Name="Geldi">

      <ColorAnimationUsingKeyFrames BeginTime="00:00:00"

                                    Storyboard.TargetName="LayoutRoot"

                                    Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">

        <SplineColorKeyFrame KeyTime="00:00:01"

                            Value="#FFFFFFFF"/>

      </ColorAnimationUsingKeyFrames>

    </Storyboard>

  </UserControl.Resources>

  <Grid x:Name="LayoutRoot"

        Background="White">

 

  </Grid>

</UserControl>

Gördüğünüz gibi kodumuzda yer alan iki animasyon da LayoutRoot adındaki Grid'in rengini bir saniyede değiştirmeyi hedefliyor. Animasyonlardan Geldi adındaki Storyboard Grid'in rengini beyaza alırken, Gitti adındaki ise Siyah'a götürüyor. Kullanıcı fareyi hareket ettirmediğinde yani ekran başından gittiğinde Gitti, geri geldiğinde ise Geldi animasyonunu oynatacağız.

DispatcherTimer yetiş imdadımıza!

Farenin kullanıcı tarafından hareket ettirilip ettirilmediği sürekli kontrol etmek yerine aslında bizim ana bir Timer'a ihtiyacımız var. Varsayalım ki beş saniye boyunca herhangi bir hareket olmamışsa ekranı karartacağız. Bu durumda farenin oynatıldığı son harekette bu beş saniyelik sayacı başlatmamız gerek. Biz hangi fare hareketinin son hareket olduğunu anlayamayacağımız için aslında farenin her hareketinde sayacımızı başlatmalıyız fakat sonrasında eğer fare tekrar hareket ettirilirse sayacı durdurup baştan başlatmamız gerek.

İlk olarak Timer olarak kullanacağımız DispathcerTimer'ı global olarak tanımlayalım.

[VB]

WithEvents Kontrol As New System.Windows.Threading.DispatcherTimer

[C#]

System.Windows.Threading.DispatcherTimer Kontrol = new System.Windows.Threading.DispatcherTimer();

Uygulama ilk olarak istemciye yüklendiğinde hemen elimizdeki Timer'ın Interval yani tekrar aralığını düzenleyerek Timer'ı başlatmamız gerekiyor.

[VB]

    Private Sub Page_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded

        Kontrol.Interval = New TimeSpan(0, 0, 5)

        Kontrol.Start()

    End Sub

[C#]

        void Page_Loaded(object sender, RoutedEventArgs e)

        {

            Kontrol.Interval = new TimeSpan(0, 0, 5);

            Kontrol.Start();

        }

Eğer fare hareket etmezse yukarıdaki Timer sonuna kadar çalışacak ve doğal olarak Timer'ın Tick event'ı çalıştırılacaktır. Fakat bu süreçte eğer fare oynatılırsa bizim bu Timer'ı durdurup baştan başlatmamız gerek ki sayacımızı da bir anlamda sıfırlamış olalım. Uygulamamızın MouseMove durumunu yakalamamız yeterli olacaktır.

[VB]

    Private Sub Page_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Input.MouseEventArgs) Handles Me.MouseMove

        Kontrol.Stop()

        Kontrol.Start()

    End Sub

[C#]

        void Page_MouseMove(object sender, MouseEventArgs e)

        {

            Kontrol.Stop();

            Kontrol.Start();

        }

Sıra geldi Timer'ın Tick eventına gerekli kodu yazmaya. Aslında bu noktada yazacağımız tek kod bizim Gitti animasyonunu çalıştıracak olan kod olacak. Böylece uygulama kullanıcının fareyi beş saniyedir oynatmadığını algılamış ve gerekli işlemi yapmış olacak.

[VB]

    Private Sub Kontrol_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Kontrol.Tick

        Gitti.Begin()

        Gitmis = True

    End Sub

[C#]

        void Kontrol_Tick(object sender, EventArgs e)

        {

            Gitti.Begin();

            Gitmis = true;

        }

Kod içerisinde ilginizi çeken nokta eminim ki Gitmis değişkenidir. Gitmis değişkeni uygulamamızda global olarak tanımlayacağımız bir Boolean değişkeni. Bu değişkeni ScreenSaver yapımızın çalışıp çalışmadığını kontrol etmek için kullanacağız. Böylece MouseMove durumunda daha önce eğer ekran karartılmış ise ekranı aydınlatabileceğiz. Gelin MouseMove durumundaki yeni kodumuzu da inceleyelim.

[VB]

    Private Sub Page_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Input.MouseEventArgs) Handles Me.MouseMove

        Kontrol.Stop()

        Kontrol.Start()

        If Gitmis Then

            Gitmis = False

            Geldi.Begin()

        End If

    End Sub

[C#]

        void Page_MouseMove(object sender, MouseEventArgs e)

        {

            Kontrol.Stop();

            Kontrol.Start();

            if (Gitmis)

            {

                Gitmis = false;

                Geldi.Begin();

            }

        }

Gördüğünüz gibi fare her oynatıldığında sayacımızı sıfırlarken daha önce ekran karartılmış mı kontrol ediyoruz. Eğer karartılmış ise hemen aydınlatma işlemini başlatıyoruz ve tabi ki Gitmis değişkenimizi de False olarak ayarlıyoruz.

Uygulamamızın tam kodu aşağıdaki şekilde sonlanıyor;

[VB]

Partial Public Class Page

    Inherits UserControl

 

    Public Sub New()

        InitializeComponent()

    End Sub

 

    WithEvents Kontrol As New System.Windows.Threading.DispatcherTimer

    Dim Gitmis As Boolean = False

 

    Private Sub Page_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded

        Kontrol.Interval = New TimeSpan(0, 0, 5)

        Kontrol.Start()

    End Sub

 

    Private Sub Page_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Input.MouseEventArgs) Handles Me.MouseMove

        Kontrol.Stop()

        Kontrol.Start()

        If Gitmis Then

            Gitmis = False

            Geldi.Begin()

        End If

    End Sub

 

    Private Sub Kontrol_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Kontrol.Tick

        Gitti.Begin()

        Gitmis = True

    End Sub

End Class

[C#]

using System;

using System.Collections.Generic;

using System.Linq;

using System.Net;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Animation;

using System.Windows.Shapes;

 

namespace SilverlightApplication3

{

    public partial class Page : UserControl

    {

        System.Windows.Threading.DispatcherTimer Kontrol = new System.Windows.Threading.DispatcherTimer();

        bool Gitmis;

 

        public Page()

        {

            InitializeComponent();

            this.Loaded += new RoutedEventHandler(Page_Loaded);

            this.MouseMove += new MouseEventHandler(Page_MouseMove);

            this.Kontrol.Tick += new EventHandler(Kontrol_Tick);

        }

 

        void Kontrol_Tick(object sender, EventArgs e)

        {

            Gitti.Begin();

            Gitmis = true;

        }

 

        void Page_MouseMove(object sender, MouseEventArgs e)

        {

            Kontrol.Stop();

            Kontrol.Start();

            if (Gitmis)

            {

                Gitmis = false;

                Geldi.Begin();

            }

        }

 

        void Page_Loaded(object sender, RoutedEventArgs e)

        {

            Kontrol.Interval = new TimeSpan(0, 0, 5);

            Kontrol.Start();

        }

 

    }

}

Hepinize kolay gelsin.

Sunday, September 28, 2008 8:30:35 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Silverlight 2.0  | 
 Saturday, September 27, 2008

Silverlight 2.0 RC0 çıktıktan sonra DeepZoom Composer ile proje yaratmayı denediyseniz göreceksiniz ki DeepZoom Composer hala Beta 2 projeleri yaratıyor. Aslında arada çok büyük farklar olduğunu söyleyemem ama bu dönemde eğer DeepZoom Composer ile uygulama hazırlayabilmek istiyorsanız DeepZoom Composer'ın kullandığı proje şablonlarını yenilemeniz gerekiyor.

DeepZoom Composer Silverlight 2.0 RC0 Proje Şablonu - 27092008_1.zip (21,85 KB)

Yukarıdaki dosyayı bilgisayarınıza indirdikten sonra içindekileri doğrudan C:\Program Files\Deep Zoom Composer\ adresine kopyalayın. Eğer siz DeepZoom Composer'ı farklı bir konuma yüklediyseniz tabi ki sizin bilgisayarınızdaki yükleme yerine kopyalamanız gerekecek.

Hepinize kolay gelsin.

Saturday, September 27, 2008 5:58:01 PM (GTB Standard Time, UTC+02:00)  #    Comments [1]   Silverlight 2.0  | 
 Friday, September 26, 2008

INETA Summer Hit üzerinden uzun bir zaman geçti gibi hissettiğimiz bu günlerde yeni bir aktivite serisi ile tekrar karşınızdayız. Bu sefer İstanbul değil Anadolu'nun merkezi, Başkentimiz Ankara'da olacağız.

INETA Capital Hit Afişi

Dikkat ederseniz İstanbul'daki Summer Hit sonrası içeriğimizi de epeyce değiştirdik. Tabi bunda sizlerin doldurmuş olduğu değerlendirme formlarının etkisi çok büyük. Bu sefer çok daha sıkışık ve yoğun bir tempomuz olacak. Hediyelerimiz daha fazla (hatta çok ilginç beklenmedik şeyler var :)) ve içecek sorununu da hallettik (:))

İlk gün sabah yine SL 2.0 ile başlayıp sonra benim çok önem verdiğim IIS 7'ye geçeceğiz. IIS 7.0 üzerinde ASP.NET ve PHP tarafında çok güzel yenilikler var. Sonrasında her zamanki gibi bir sohbet panelimiz olacak. Son olarak LINQ ile ilk günümüzü kapatacağız. İkinci gün WPF ile başlayarak ADO.NET Data Services konusunu inceleyeceğiz. Heyecanlandığınızın farkındayım :) Sonrasında IE 8.0 ile gelen yazılımcı ve tasarımcıları ilgilendiren yenilikler ve yeni uygulama platformlarını inceleyerek WCF dünyasına da atılarak iki günü sonlandıracağız.

Aktiviteye üniversite girişinde güvenlik sorunları yaşamamak adına kayıt olmanız şart.

Kayıt adresi: http://daron.yondem.com/kayit/

Emeklerinden dolayı buradan sevgili MSP, Çağrı Erdoğan'a çok teşekkür ediyorum.

Aktiviteyi duyururken geçen sefer güzel bir başarı elde etmiştik. Bu sefer de yine aşağıdaki bannerı kullanabilirsiniz. Banner'a tıklandığında link olarak da kayıt adresini verebilirsiniz.

INETA Capital Hit Banner

Hepinizi bekliyorum ;)

Friday, September 26, 2008 8:59:59 AM (GTB Standard Time, UTC+02:00)  #    Comments [23]   .NET Framework 3.5 | ASP.NET 3.5 | Expression Blend | IIS 7.0 | LINQ | Seminer | Silverlight 2.0 | Visual Basic 2008 | Visual Studio 2008 | WCF | WPF  | 
 Thursday, September 25, 2008

Silverlight'ın RTW (Release To Web) olmasına yani tam olarak son haline gelmesine çok az kaldı. Bugün RC0 (Release Candidate) sürümü sadece yazılım geliştiricilerin kullanımına sunuldu. Yani eğer yazılım geliştirme işlemi yapmıyorsunuz bu RC'yi bilgisayarınıza yüklemenize gerek yok. Aslına bakılırsa bu durum daha önceki Beta sürümleri için de kullanıcılar tarafında geçerli bir davranıştı :)

Nasıl başlarız?

İster sıfırdan Silverlight dünyasına giriyor olun ister uzun süredir Beta 1 ve Beta 2 ile uğraşıyor olun tabi ki artık yeni yüklemelere ihtiyacınız olacak. Eğer sanal makine kullanıyorduysanız sıfır bir makine işinizi görecektir, aksi halde tüm eski Beta 2 ve Beta 1 yüklemelerinin tamamen bilgisayarınızdan silmeniz gerekiyor.

Makinenizde ön şart olarak Visual Studio ve üzerine de .NET Framework 3.5 ve Visual Studio 2008 SP1 yüklü olması gerekiyor. Sonrasında ilk olarak Expression Blend tarafındaki sorunları çözmemiz gerek. Hatırlarsanız Silverlight 2.0 Beta 2 için Expression Blend 2.5 Preview sürümleri yayınlanmıştı. Microsoft bu yoldan vaz geçti ve Silverlight 2.0 development için Blend 2.5 değil 2.0 üzerinden devam edilmesini uygun gördü. Tabi Expression Blend 2.0 şu an satışta olan bir ürün olunca yeni eklenecek Silverlight 2.0 özelliklerini de bir Service Pack ile çözmeye karar verdiler. Sonuç olarak eğer Silverlight 2.0 RC0 ile uygulama hazırlayacaksanız bilgisayarınıza Expression Blend 2 yüklü olması ve üzerine de uygun Service Pack 1'i yüklemeniz gerekiyor.

Expression Blend 2 SP1 RC Preview (17.8MB)

Blend ile olan işimizi hallettikten sonra Visual Studio 2008 için de gereken eklentileri yüklememiz gerek. Silverlight Tool paketi yenilenmiş hali ile karşımızda.

Microsoft® Silverlight™ Tools for Visual Studio 2008 SP1 (RC0) (71,6MB)

Yeni neler var?

Yenilikler ve düzeltmeler gerçekten heyecan verici. Kişisel olarak da SL ekibine raporladığımız çoğu sorunun giderilmiş olması süper.

  • Sonunda Combobox kontrolümüz var!
  • PasswordBox geldi. Çakallıklar yapıp ayrı password fontları bağlamaya artık gerek kalmayacak :)
  • ProgressBar kontrolü karşınızda. Zor değildi aslında, hemen yapıyorduk elle ama olsun ;)
  • generic.xaml içerisinde tüm varsayılan stiller yenilendi.
  • MessageBox.Show geldi, oh be! JavaScript çağırmaktan bıkmıştık gerçekten.
  • HTML Object taglarındaki Type bilgisi son halini aldı ve x-silverlight-2-b2 'den x-silverlight-2'e değişti.
  • Embedded Font'lar artık Resource olarak Assembly içerisinde bulunmak zorunda. XAP içinde font saklama sistemi artık desteklenmiyor. Güvenlik...
  • System.Windows.Controls.Extended.dll değişti, artık System.Windows.Controls.dll var.

Bunlar dışında daha bir sürü değişiklik var :) Önemli olduğunu düşündüklerimi zaman içerisinde blogdan sizlerle detaylı olarak paylaşacağım. Şimdi taze Silverlight 2.0 RC0 kurduğum sanak makineme dönmem gerekiyor ;)

Hepinize kolay gelsin.

Thursday, September 25, 2008 5:27:07 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Silverlight 2.0  | 
 Wednesday, September 24, 2008

Bugün sizinle ufak bir ipucu paylaşmak istiyorum. Bir projenin gerekleri nedeniyle hazırladığımız bir Windows uygulamasının bilgisayara bağlı ikinci ekranda açılmasını istiyorduk. Bu ekranlara Windows'un Extended Desktop mantığı ile görüntü aktarılıyor. Nasıl yaparım diye uğraşırken bir anda kafamın üzerinde bir ampul gördüm. Evet ampul yanıyordu :)

"Extended Desktop" kullanırken bir programı ikinci ekrana almak için ne yaparız? Fare ile onu tutar ve yan tarafa taşırız. Sonra eğer o programın ikinci ekranda tam ekranı kaplamasını istiyorsak zaten doğal olarak Maximized şeklinde ufak bir ayar işi görecektir. Bu durumda neden bu işi programatik olarak uygulama başlangıcında yapmayalım?

[VB]

        System.Windows.Forms.Screen.AllScreens(0).Bounds.Width

        Me.WindowState = WindowState.Maximized

[C#]

System.Windows.Forms.Screen.AllScreens[0].Bounds.Width;

this.WindowState = WindowState.Maximized;

İşte bu kadar. Yapmamız gereken iş aslında açılan formu ekranın sağ tarafına doğru itip diğer ekrana geçecek konuma getirmek. Sonra artık bu formu Maximized yaptığınız kendi ekranında büyüyecektir. Çözünürlüklerden bağımsız olarak sürekli bu işlemin çalışabilmesi için de ilk ekranın genişliğini almak yeterli olacaktır.

Hepinize kolay gelsin.

Wednesday, September 24, 2008 5:47:17 PM (GTB Standard Time, UTC+02:00)  #    Comments [2]   .NET Framework 3.5 | Visual Basic 2008 | Visual Studio 2008 | WPF  | 
 Tuesday, September 23, 2008

Başlık olarak “Reflection” yazdıktan sonra ardına sayfalarca açıklama ve örnek konulabilir. Hatta bu konuda ayrı bir kitap bile yazılabilir. Reflection’ın çok farklı kullanımlar var. Özetleyerek hızlı bir şekilde tanımlamak istersek aslında Reflection bize hakkında bilgi sahibi olmadığınız programatik nesnelerle ilgili çalışma zamanında (run-time) bilgi alabilmemize olanak tanıyan bir metottur. Peki böyle bir şeye neden ihtiyacımız olsun? En basit örnek gerçek zamanlı olarak uygulamalara farklı DLL dosyalarının bağlandığı durumları gösterebiliriz. Böyle bir durumda kaynak konumdaki sınıflar veya metotlar ile ilgili herhangi bir bilgi bulunmaz. Söz konusu bu bilgilerin program çalışırken elde edilerek kullanılması gerekir. Gelin ilk olarak Reflection’ın yapısını ve sistemini tanımak adına tek bir uygulama içerisinde nasıl kullanılabileceğimize göz atalım. Örnek uygulamamızda aşağıdaki şekli ile tanımlanmış bir Urun sınıfı kullanacağız.

[VB]

Public Class Urun

 

    Private PAdi As String

    Public Property Adi() As String

        Get

            Return PAdi

        End Get

        Set(ByVal value As String)

            PAdi = value

        End Set

    End Property

 

    Sub New()

 

    End Sub

 

    Sub New(ByVal adi As String)

        Me.Adi = adi

    End Sub

 

    Function Uyari() As String

        Return "Ürünün adı: " & Me.Adi

    End Function

End Class

[C#]

public class Urun

{

 

    private string PAdi;

    public string Adi

    {

        get { return PAdi; }

        set { PAdi = value; }

    }

 

    public Urun()

    {

 

    }

 

    public Urun(string adi)

    {

        this.Adi = adi;

    }

 

    public string Uyari()

    {

        return "Ürünün adı: " + this.Adi;

    }

}

Uygulamamız içerisinde iki adet düğme yer alacak ve kullanacağımız Windows penceresinde global olarak tanımlanmış bir de Object tipinde değişkenimiz bulunacak.

[VB]

Dim BirUrun As Object   

[C#]

object BirUrun;

Uygulama içerisindeki düğmelerden birine basıldığında global BirUrun değişkenimiz yeni bir Urun değişkenine dönüştürülecek.

[VB]

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

    BirUrun = New Urun

End Sub

[C#]

    private void button1_Click_1(object sender, EventArgs e)

    {

        BirUrun = new Urun();

    }

Programımız içerisinde diğer düğmeye basıldığında BirUrun adındaki değişkenimizin Adi özelliğini değiştirerek Uyari adındaki metodunu kullanmak istiyoruz. Fakat Visual Studio içerisinde maalesef ki BirUrun adındaki değişkenle beraber Urun tipine ait Intellisense desteği gelmeyecektir. Aslında bu durumun haklı bir nedeni var. İkinci düğmeye basıldığında BirUrun adındaki değişkenin tipininin Object mi yoksa Urun mü olacağı belli değil. İşte tam da istediğimiz ortamı yaratmış olduk. Kullanacağımız nesnenin tipi belirsiz ve biz ona ait bazı özellikleri kullanmak istiyoruz. Bu durumda ilk olarak ikinci düğmeye basıldığında gerçekten BirUrun değişkeninin tipi Urun mü yoksa değil mi sorusunu kontrol etmemiz lazım.

[VB]

       If TypeOf (BirUrun) Is Urun Then

 

        End If

[C#]

        if ((BirUrun) is Urun)

        {

 

        }

Buraya kadar her şey çok kolay. Bundan sonra eğer IF kontrollerimize olumlu sonuç dönüyorsa ilk olarak gidip nesnenin Adi özelliğini bulmamız ve ona bir değer aktarmamız gerekiyor.

[VB]

BirUrun.GetType.GetProperty("Adi").SetValue(BirUrun, "Daron", Nothing)

[C#]

BirUrun.GetType().GetProperty("Adi").SetValue(BirUrun, "Daron", null);   

Yukarıdaki kod ile elimizdeki nesnenin tipini bilmeden onun Adi adındaki özelliğini (property) yakalayarak değerini Daron olarak değiştiriyoruz. Kodumuzu detaylı olarak adım adım bakacak olursak ilk aşamada nesnenin tipini GetType ile alıyoruz. Sonrasında ise tipini yakaladığımız nesnenin GetProperty ile Adi adındaki özelliğini alarak SetValue ile söz konusu özelliğin değerini değiştiriyoruz. SetValue metodu toplam üç parametre alıyor; bunlardan ilki değer değişikliği yapılacak nesnenin kendisi, ikincisi yeni atanacak olan değer, üçüncüsü ise eğer değiştirilecek olan özellik (property) indeksli ise söz konusu indeks değeri. Bizim örneğimizde indeksli bir özellik olmadığı için bu parametreyi boş geçiyoruz.

Değer atamamızı tamamladığımıza göre bu sefer de sıra geldi BirUrun değişkenimize ait Uyari metodunu çalıştırmaya. Metodumuz bize bir String döndürecek biz de onu doğrudan bir mesaj kutusu ile kullanıcıya göstereceğiz.

[VB]

BirUrun.GetType.InvokeMember("Uyari", Reflection.BindingFlags.InvokeMethod, Nothing, BirUrun, Nothing)

[C#]

BirUrun.GetType().InvokeMember("Uyari", System.Reflection.BindingFlags.InvokeMethod, null, BirUrun, null).ToString();

Reflection kullanarak türü bilinmeyen bir nesnenin bir metodunu çalıştırmak için InvokeMember metodundan faydalanmamız gerekiyor. InvokeMember aslında çok geniş kullanımı olan bir metod, biz şimdilik sadece bir çeşit kullanımına değineceğiz. Örneğimizde InvokeMember bir metod çalıştıracağı için ilk parametresinde çalıştırılacak olan metodun adını ikincisinde BindingFlags.InvokeMethod ile bir Metod çalıştırılacağını belirtiyoruz. Üçüncü parametre bizim şimdilik kullanım alanımız dışında kalan Binding’lerle ilgili, aynı şekilde beşinci parametre de boş bırakılarak geçilecek. Dördüncü parametrede ise hedef nesnemiz olan BirUrun değişkenimizi atayacağız. Böylece metodumuzu da çalıştırmış olduk.

Dinamik DLL Kullanımı

Kabaca Reflection’ın nasıl kullanılabildiğine dair bir örnek yaptıktan sonra artık sıra geldi harici bir DLL dosyasının çalışma anında programımıza ekleyerek içerisindeki yapıları kullanmaya. Bu çeşit bir işlevselliği özellikle gerçek zamanlı DLL derlemesi ile birleştirdiğinizde çok farklı bir dünyaya kapı açmış olacaksınız. Hedef olarak kullanacağımız DLL dosyasını aşağıdaki kodlardan yaratacağız.

[VB]

Public Class Deneme

    Function Metin() As String

        Return "Çalışıyor"

    End Function

End Class

[C#]

    public class Deneme

    {

        string Metin()

        {

            return "Çalışıyor";

        }

Yarattığımız DLL dosyasını uygulamamız ile aynı konuma yerleştirdikten sonra aşağıdaki kod ile DLL’imizi kullanmaya başlayabiliyoruz.

[VB]

Dim BirAssembly As Reflection.Assembly = Reflection.Assembly.LoadFrom("ornek2.dll")

[C#]

System.Reflection.Assembly BirAssembly = System.Reflection.Assembly.LoadFrom("ornek2.dll");

Artık yukarıda tanımladığımız Assembly üzerinden Reflection kullanarak ilerleyebiliriz. İlk olarak Deneme adında sınıfımızdan bir instance almamız gerekecek. Bunun için Deneme tipini bulmamız lazım.

[VB / C#]

BirAssembly.GetModule("Ornek2.dll").GetType("Deneme")

Assembly üzerinden modülümüzü yakalıyor sonra da Deneme adındaki tipinizi buluyoruz. Tabi tipi bulmak yeterli değil, söz konusu tipte bir değişken yaratmamız gerekiyor. Activator sınıfını kullanarak bu tip üzerinden bir instance yaratarak Sinif adında bir değişkene aktaracağız.

[VB]

Dim Sinif = Activator.CreateInstance(BirAssembly.GetModule("Ornek2.dll").GetType("Deneme"))   

[C#]

object Sinif = Activator.CreateInstance(BirAssembly.GetModule("Ornek2.dll").GetType("Deneme"));

Yarattığımız sınıfın maalesef özellikleri otomatik olarak gelmeyecek. O nedenle Metin adındaki metodumuzu da elle bularak çalıştırmak zorundayız.

[VB]

BirAssembly.GetModule("Ornek2.dll").GetType("Deneme").GetMethod("Metin").Invoke(Sinif, Nothing)

[C#]

BirAssembly.GetModule("Ornek2.dll").GetType("Deneme").GetMethod("Metin").Invoke(Sinif, null)

Yine Assembly üzerinden yola çıkarak bu sefer daha da ileri gidiyoruz. Deneme sınıfımızı bulduktan sonra içerisinde Metin adındaki metodumuzu buluyor ve doğrudan Invoke ile söz konusu metodu çalıştırıyoruz. Invoke metodu bizden iki parametre istiyor; bunlardan ilki ana sınıfın kendisi. Bir önceki adımda yakaladığımız sınıfı buraya parametre olarak aktarıyoruz. Diğeri ise bizim kullanmayacağımız Binding parametresi.

Metin metodumuz çalıştırıldığında geriye bir String değişkeni döndürüyor. Bu değişkeni de bir mesaj kutusu ile kullanıcıya göstermek istersek uygulamamızın tam kodunun aşağıdaki şekilde sonlanması gerekiyor.

[VB]

Public Class Form2

 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim BirAssembly As Reflection.Assembly = Reflection.Assembly.LoadFrom("ornek2.dll")

 

        Dim Sinif = Activator.CreateInstance(BirAssembly.GetModule("Ornek2.dll").GetType("Deneme"))

        MsgBox(BirAssembly.GetModule("Ornek2.dll").GetType("Deneme").GetMethod("Metin").Invoke(Sinif, Nothing))

    End Sub

End Class

[C#]

namespace CSReflection

{

    public partial class Form2 : Form

    {

        public Form2()

        {

            InitializeComponent();

        }

 

        private void button1_Click(object sender, EventArgs e)

        {

            System.Reflection.Assembly BirAssembly = System.Reflection.Assembly.LoadFrom("ornek2.dll");

 

            object Sinif = Activator.CreateInstance(BirAssembly.GetModule("Ornek2.dll").GetType("Deneme"));

            MessageBox.Show(BirAssembly.GetModule("Ornek2.dll").GetType("Deneme").GetMethod("Metin").Invoke(Sinif, null).ToString());

        }

    }

}

Böylece harici bir DLL dosyasını yükleyerek istediğimiz metodu dinamik olarak kullanabildik. Farklı durumlarda isterseniz bir DLL içerisinde tüm metod, sınıf ve özelliklerin listelerini alabilir hatta bunları LINQ sorguları ile tarayabilirsiniz.

[VB]

Dim Metodlar = From Gelenler In BirAssembly.GetModule("Ornek2.dll").GetTypes Where Gelenler.GetMethod("Metin") IsNot Nothing

[C#]

var Metodlar = from Gelenler in BirAssembly.GetModule("Ornek2.dll").GetTypes() where Gelenler.GetMethod("Metin") != null select Gelenler;

Örneğin yukarıdaki LINQ sorgumuz ile harici DLL dosyası içerisinde Metin adında metodu olan tüm sınıfların bir listesini alıyoruz.

Hepinize kolay gelsin.

Tuesday, September 23, 2008 6:51:06 PM (GTB Standard Time, UTC+02:00)  #    Comments [8]   .NET Framework 3.0 | .NET Framework 3.5 | ASP.NET | ASP.NET 3.5 | LINQ | Silverlight 2.0 | Visual Basic 2005 | Visual Basic 2008 | Visual Studio 2005 | Visual Studio 2008 | WCF | WF | WPF  | 
 Monday, September 22, 2008

Windows Vista ile beraber karşımıza çıkan UAC (User Account Control) aslında Winforms programcılığında çok şey değiştirdi. Özetle artık istediğimiz gibi herhangi bir klasöre dosya yazamıyoruz veya Registry içerisinde istediğimiz değişiklikleri yapamıyoruz. Ya uygulamamıza verilen haklar çerçevesinde hareket etmek zorundayız ya da kullanıcıdan ek haklar istemeliyiz.

Bu yazıda hızlı bir şekilde Vista ile gelen UAC'nin yazılım geliştirme esnasındaki kullanımına değinerek farklı çözümler geliştireceğiz.

Dosyaları diskte nereye yazmalı?

Programınızın ürettiği bir dosya var ve onu istediğiniz yere yazamadığınızın farkında vardınız. Eğer dosyanın yazılacağı yeri kullanıcıdan bir SaveFileDialog ile alıyorsanız zaten bu prosesi Vista kendisi halledecek ve kullanıcıyı Admin hakkı gerektiğine dair uyaracaktır fakat eğer dosyayı siz programatik olarak doğrudan yazmak istiyorsanız maalesef hakkınız olan bir yer bulmanız gerek.

Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)

Yukarıdaki kod ile kolaylıkla yazma hakkınız olan bir alana ulaşabilirsiniz. Tabi bunun haricinden kullanıcının Desktop veya MyDocuments gibi alanlara da doğrudan Admin hakkı gerekmeksizin ulaşması hakkı vardır. Tüm bu klasörlere de rahatlıkla ulaşabilirsiniz fakat genelde bu noktalara yazılımlarla ilgili özel dosyaların saklanması doğru olmaz.

Environment.GetFolderPath(Environment.SpecialFolder.Desktop)

Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)

Admin haklarını nasıl alırız?

Eğer hazırladığınız uygulamanın kesinlikle Admin haklarına ihtiyacı varsa uygulamayı UAC'yi çağıracak şekilde düzenlemelisiniz. Böylece program ilk açıldığında kullanıcıdan Admin hakları isteyecektir, aksi halde program açılmayacaktır. Tüm bu ayarları projelerinizdeki app.manifest dosyası içerisinde yapabilirsiniz. Bu dosyaya kolay şekilde ulaşmak için Visual Studio içerisindeki Solution Explorer içerisinde projeye sağ tıklayarak kelen menüden "Properties"i seçip "Application" tabında "View UAC Settings" demeniz yeterli olacaktır.

<?xml version="1.0" encoding="utf-8"?>

<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>

  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">

    <security>

      <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">

        <requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

      </requestedPrivileges>

    </security>

  </trustInfo>

</asmv1:assembly>

Bu dosya içerisinde normalde asInvoker yazan yere yukarıdaki gibi requireAdministrator yazarsanız bir sonraki  Build ile oluşturulan uygulama artık UAC'den admin hakları isteyerek çalışacaktır. Bu da uygulamanıza her yere ulaşım hakkı verildiği anlamına gelir.

Hepinize kolay gelsin.

Monday, September 22, 2008 1:56:59 PM (GTB Standard Time, UTC+02:00)  #    Comments [2]   Vista | Visual Studio 2008  | 
 Sunday, September 21, 2008

Bir uygulama düşünün kendini programlayabilen. Konumuz “Star Trek” veya “Geleceğe Dönüş” değil. Emin olun gerçek dünyadan ve yapılabileceklerden bahsediyorum. Uygulamalarınızın dış sistemlerle ciddi bir bağlantı içerisinde olduğu durumlarda bazen kendi içlerinde dış sistemlere uygun kodlar üreterek kullanmaları gerekebilir. Bunu bazen uygulamaların kendi içlerindeki yapay zeka ile yapabilecekleri gibi bazen ise başka bir dış kaynaktan aldıkları yeni parametrelerden yola çıkarak kendi kodlarında değişiklik yapabilirler. Eğer bunların hiçbiri size gerçekçi gelmiyorsa başka bir seçenek olarak da harici uygulamaların kullanabileceği DLL dosyaları yaratacak bir uygulama yazmak istediğinizde yapmanız gerekenlerden bahsedebiliriz. Aslında her ikisi de aynı kapıya çıkıyor.

Bize dinamik olarak uygulamalar tarafından kullanılabilecek DLL dosyaları yaratacak bir kod lazım. Kullanacağımız nesnelerin çoğunun bulunduğu esas namespace System.CodeDom.Compiler olacak. Bunun haricinde C# veya VB için ayrı ayrı uygun namespace’leri kullanmamız gerek. Eğer VB kodu derleyecekseniz VB sınıflarını C# kodu derleyecekseniz tabi ki C# sınıflarını kullanmalısınız. Çapraz işlem yaparak C# kodunuz ile VB kodundan DLL üretme şansınız da var. Biz örneklerimizde C# ile C#’dan derleme, VB kodu ile de VB’den derleme yapacağız.

[VB]

Dim KodUretici As New Microsoft.VisualBasic.VBCodeProvider

Dim Derleyici As System.CodeDom.Compiler.CodeCompiler = KodUretici.CreateCompiler()

 

Dim Referanslarim As String() = {"System.dll"}

Dim AssemblyAdi As String = "Ornek.dll"

[C#]

Microsoft.CSharp.CSharpCodeProvider KodUretici = new Microsoft.CSharp.CSharpCodeProvider();

System.CodeDom.Compiler.ICodeCompiler Derleyici = KodUretici.CreateCompiler();

 

String[] Referanslarim =  {"System.dll"};

String AssemblyAdi= "Ornek.dll";

Kodumuzun başlangıcında ilk olarak birer CodeProvider nesnesi yaratıyoruz. Elimizdeki hazır kodu derleyecek olan nesneler olarak bu sınıflar VB ve C# için farklılaşıyor. CodeProvider’lar üzerinden birer de derleyici nesnesi aldıktan sonra sıra geliyor derleyeceğimiz kodun referanslarına karar vermeye. Referansları DLL isimleri ile bir String dizisine aktarmanız şart. Windows uygulamalarında en azından System.dll’in web uygulamalarında da System.Web.dll’in referans alınmış olması gerekiyor. Son olarak üreteceğimiz DLL dosyasının adını da başka bir değişkene aktararak yolumuza devam edelim.

[VB]

Dim DerlemeParametreleri As New System.CodeDom.Compiler.CompilerParameters(Referanslarim, AssemblyAdi)

DerlemeParametreleri.GenerateExecutable = True

DerlemeParametreleri.GenerateInMemory = False

[C#]

System.CodeDom.Compiler.CompilerParameters DerlemeParametreleri = new System.CodeDom.Compiler.CompilerParameters(Referanslarim, AssemblyAdi);

DerlemeParametreleri.GenerateExecutable = false;

 DerlemeParametreleri.GenerateInMemory = false;

Derleme işlemini yaparken yapmamız gereken ayarlar var. Bu ayarları derleyicimize bir CompilerParameters nesnesi olarak aktaracağız. DerlemeParametreleri değişkenimizi yaratırken referanslarımızı ve DLL adını aktardıktan sonra özel olarak GenerateExecutable özelliğini false olarak ayarlıyoruz. Böylece derleyicimiz bize tek başına çalışabilir bir dosya yaratmaktansa bir DLL dosyası yaratacak. Bir sonraki adımda da GenerateInMemory özelliğini false yaparak yaratılacak dosyanın uygulamamız ile aynı konuma, diske yazdırılmasını sağlıyoruz. Aksi halde yaratılan Assembly sadece hafızada tutulacak ve diske yazılmayacaktır. Sıra geldi dinamik olarak derlemeyeceğimiz kodu bir değişkene aktarmaya.

[VB]

Dim Kodum As String = <Kod>Public Class Deneme

    Function Metin() As String

        Return "Çalışıyor"

    End Function

End Class</Kod>.Value

[C#]

System.IO.StreamReader Okuyucu = new System.IO.StreamReader("Class1.cs");

string Kodum = Okuyucu.ReadToEnd();

Okuyucu.Close();

Bu noktada VB ile C# arasında farklı işlemler yaptım. VB’de doğrudan yaratacağım kodu uygulamanın içerisine gömerken C#’da derleyeceğim C# kodunu harici bir Class1.cs dosyasından çektim. Siz kendi uygulamalarınızda ister bu kodları farklı dosyalardan çekin ister metin işlemleri ile dinamik kod yaratın. İhtiyaçlarınıza göre uygun çözümü üretmek tamamen size kalmış. Önemli olan tek nokta aslında bu kodlarda hiçbir hatanın olmaması gerektiği, aksi halde derleme işlemi yapılamayacaktır.

[VB]

Dim Sonuc As System.CodeDom.Compiler.CompilerResults = KodUretici.CompileAssemblyFromSource(DerlemeParametreleri, Kodum)

[C#]

System.CodeDom.Compiler.CompilerResults Sonuc = KodUretici.CompileAssemblyFromSource(DerlemeParametreleri, Kodum);

Tüm ayarlarımız tamamlandığında göre doğrudan CodeProvider nesnemizin CompileAssemblyFromSource metodunu kullanarak derleme işlemini başlatabiliriz. Tabi bu esnada daha önce hazırlamış olduğumuz DerlemeParametrelerini de metoda parametre olarak aktarıyoruz. Derleme işlemimizi baştan sona tamamlayan kodumuzu bir bütün olarak inceleyelim.

[VB]

Dim KodUretici As New Microsoft.VisualBasic.VBCodeProvider

Dim Derleyici As System.CodeDom.Compiler.CodeCompiler = KodUretici.CreateCompiler()

 

Dim Referanslarim As String() = {"System.dll"}

Dim AssemblyAdi As String = "Ornek.dll"

 

Dim DerlemeParametreleri As New System.CodeDom.Compiler.CompilerParameters(Referanslarim, AssemblyAdi)

        DerlemeParametreleri.GenerateExecutable = True

        DerlemeParametreleri.GenerateInMemory = False

 

Dim Kodum As String = <Kod>Public Class Deneme

    Function Metin() As String

        Return "Çalışıyor"

    End Function

End Class</Kod>.Value

 

Dim Sonuc As System.CodeDom.Compiler.CompilerResults = KodUretici.CompileAssemblyFromSource(DerlemeParametreleri, Kodum)

[C#]

Microsoft.CSharp.CSharpCodeProvider KodUretici = new Microsoft.CSharp.CSharpCodeProvider();

System.CodeDom.Compiler.ICodeCompiler Derleyici = KodUretici.CreateCompiler();

 

String[] Referanslarim =  {"System.dll"};

String AssemblyAdi= "Ornek.dll";

 

System.CodeDom.Compiler.CompilerParameters DerlemeParametreleri = new System.CodeDom.Compiler.CompilerParameters(Referanslarim, AssemblyAdi);

DerlemeParametreleri.GenerateExecutable = false;

DerlemeParametreleri.GenerateInMemory = false;

 

System.IO.StreamReader Okuyucu = new System.IO.StreamReader("Class1.cs");

string Kodum = Okuyucu.ReadToEnd();

Okuyucu.Close();

 

System.CodeDom.Compiler.CompilerResults Sonuc = KodUretici.CompileAssemblyFromSource(DerlemeParametreleri, Kodum);

Dinamik olarak DLL dosyası derlemek işte bu kadar kolay. Dinamik kod yaratma araçları son dönemde çok popüler. Veritabanına bağlanarak veritabanındaki nesneleri algılayıp uygun “Veri Katmanı” kodunu dinamik olarak oluşturan hazır uygulamalar olduğu gibi bazı durumlarda özel kodlar yazmak da gerekebiliyor. Böyle bir durumda artık siz de uygulamalarınıza farklı kaynaklardaki şartlara uygun kodu dinamik olarak üretebilir ve bir DLL olarak farklı uygulamalara aktarabileceğiniz gibi kendi uygulamalarınızda da kullanabilirsiniz. Yarattığınız DLL dosyasını hemen uygulamanızda kullanmak isterseniz bu sefer dinamik olarak Assembly kullanımını ve Reflection konusuna eğilmenizde fayda var.

Hepinize kolay gelsin.

Sunday, September 21, 2008 7:04:21 PM (GTB Standard Time, UTC+02:00)  #    Comments [3]   .NET Framework 3.0 | .NET Framework 3.5 | ASP.NET | ASP.NET 3.5 | Silverlight 2.0 | Visual Basic 2005 | Visual Basic 2008 | Visual Studio 2005 | Visual Studio 2008 | WCF | WPF  | 
 Saturday, September 20, 2008

Bugün Microsoft Türkiye binasında INETA üyelerinden CETURK'ün tam gün yazılım seminerleri etkinliğini gerçekleştirdik. Daha önce sizlere duyurusu aktardığım etkinliğin başında ben WPF anlatırken bu sefer diğer WPF seminerlerime kıyasla biraz daha kod tarafına geçtim ve kod ile animasyon yaratmanın yollarına da değindik. Özel istek alarak 5 dakikalık bir LINQ semineri yaptık :)

INETA CETURK WPF Seminerimden bir kare...
INETA CETURK WPF Seminerimden bir kare...

Sonrasında sevgili Aykut Taşdelen Reporting Services, Eralp Erat da F# anlattı. F# sunumu gerçekten ilginçti. F# web development veya winforms tarafında günlük hayatımıza girecek nitelikte olmasa da özellikle akademik dünyanın bazı ihtiyaçlarını karşılayabilecek gibi gözüküyor. Bakalım F#'ın geleceği ne olacak.

Katılan herkese çok teşekkürler. İstanbul içi seminerlerimiz devam edecek ;)

Saturday, September 20, 2008 11:14:06 AM (GTB Standard Time, UTC+02:00)  #    Comments [2]   .NET Framework 3.5 | Seminer | Visual Studio 2008 | WPF  | 
 Friday, September 19, 2008

İster VB olsun ister C#, ister web ister Windows uygulaması olsun yazdığımız tüm kodların derlenerek (Compile) bir EXE veya DLL haline dönüştürüldüğünü biliyoruz. Aslında .NET içerisinde yapılan işlem sizin yazdığınız herhangi bir .NET dilindeki kodun MSIL (Microsoft Intermediate Language)’a çevrilmesidir. İşte tam bu noktada akla gelen ilk soru; acaba bu çeviri işleminin tersini yapmak mümkün mü? Yani elimizdeki DLL veya EXE dosyasından yola çıkarak VB veya C# kodumuzu geri alabilir miyiz? Cevap: Evet.

Şu andan itibaren yapacaklarımız hedef olarak kullanacağınız uygulamanın lisans sözleşmesine göre yeri geldiğinde suç teşkil edebilir. O nedenle sizi özellikle uyarmak istiyorum. Çoğu zaman De-Compile işlemleri yaparkenki amacımız yazdığımız kodun nasıl derleyici tarafında MSIL’e çevrildiğini incelemek veya kaynak kodunu kaybettiğimiz ve bize ait olan bir uygulamanın kodlarına ulaşmak olacaktır. Diğer yandan lisans sözleşmesi ile aykırı düşmediği sürece farklı uygulamaları da De-Compile ederek arka planda farklı işlemlerin nasıl yapıldığını inceleme şansınız da olabilir.

.NET tarafına geçtiğimizde herhangi bir DLL veya EXE’nin aslında MSIL kodları içerdiğinden bahsetmiştik. Tabi ki bu MSIL kodları doğrudan bilgisayarlar tarafından çalıştırılabilir kodlar değiller. O nedenle içerisinde MSIL bulunan bir .NET yapısının çalışabilmesi için hedef makinede .NET Framework’ün yüklü olması gerekiyor. .NET Framework içerisindeki CLR (Common Language Runtime) bizim MSIL kodumuzu makine diline çevirerek çalışmasını sağlayacaktır. Kabaca baktığımızda De-Compile yolunda bizim ilk olarak elimizdeki DLL veya EXE içerisinden MSIL kodunu alarak çıkarmamız gerekecek. Bunun için doğrudan .NET Framework SDK paketi ile beraber gelen MSIL DisAssembler (ILDASM) uygulamasını kullanabiliriz.

IL DASM Kullanımı

Bilgisayarınıza .NET Framework SDK paketini kurduktan sonra doğrudan “Başlat” menüsünden ulaşabileceğiniz ILDASM programını Visual Studio yükleme konumu içerisinde SDK klasörü altında da bulabilirsiniz. Programı açtıktan sonra “File / Open” menüsünden istediğiniz bir .NET DLL veya EXE dosyasını açma şansınız olacaktır.Deneme amaçlı olarak gelin mini bir Windows uygulaması yazalım ve ILDASM ile açarak alacağımız sonucu görelim. Uygulamamız içerisinde birer TextBox, Button ve Label bulunacak. Basit bir şekilde düğmeye basıldığında TextBox içerisindeki değeri Label içerisine aktaracağız.

[VB]

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Label1.Text = TextBox1.Text

    End Sub

End Class

[C#]

namespace WindowsFormsApplication1

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

 

        private void button1_Click(object sender, EventArgs e)

        {

            label1.Text = textBox1.Text;

        }

    }

}

Yukarıda yazdığımız kodlar ile oluşturduğumuz uygulamayı ILDASM ile açarak sonucu inceleyelim. Uygulamanın ilk açılan penceresinde bizim EXE’ye ait tüm sınıflar ve namespace’ler gözüküyor olacaktır. Eğer herhangi bir nesnenin tanımı veya metodu ile ilgili MSIL kodunu görmek isterseniz doğrudan çift tıklayarak yeni bir pencerede kodların açılmasını sağlayabilirsiniz.

ILDASM içerisinde EXE’mizin MSIL kodları açıkça gözüküyor
ILDASM içerisinde EXE’mizin MSIL kodları açıkça gözüküyor

Hazırladığımız örnek uygulamanın Button_Click durumundaki MSIL kodunu bulduğumuzda aşağıdaki sonuç ile karşılaşıyoruz.

[MSIL]

.method private instance void  Button1_Click(object sender,

                                            class [mscorlib]System.EventArgs e) cil managed

{

  // Code size       23 (0x17)

  .maxstack  8

  IL_0000:  ldarg.0

  IL_0001:  callvirt   instance class [System.Windows.Forms]System.Windows.Forms.Label WindowsApplication1.Form1::get_Label1()

  IL_0006:  ldarg.0

  IL_0007:  callvirt   instance class [System.Windows.Forms]System.Windows.Forms.TextBox WindowsApplication1.Form1::get_TextBox1()

  IL_000c:  callvirt   instance string [System.Windows.Forms]System.Windows.Forms.TextBox::get_Text()

  IL_0011:  callvirt   instance void [System.Windows.Forms]System.Windows.Forms.Label::set_Text(string)

  IL_0016:  ret

} // end of method Form1::Button1_Click

Yukarıdaki MSIL kodu normal şartlarda CLR tarafından makine koduna çevrilerek hedef ortamda çalıştırılıyor. Artık MSIL kodumuzu aldığımıza göre bu kodu VB veya C# koduna çevirmemiz lazım. Tabi bu iş o kadar kolay değil ve tek tek elle yapılabilecek bir iş de değil. O nedenle bu sefer de farklı bir araç kullanacağız.

Reflector iş başında

Lutz Roeder tarafından yazılmış bir program olarak Reflector’ı http://www.red-gate.com/products/reflector/ adresinden bilgisayarınıza indirebilirsiniz. Program aslında bir önceki adımda anlattığım MSIL çözme işlemini de kendi içinde yapabiliyor. Bununla kalmayıp çözdüğü MSIL kodunu istediğiniz .NET diline de çevirebiliyor.

Programı çalıştırdıktan sonra “File / Open” menüsünden istediğiniz bir EXE veya DLL dosyasını seçebilirsiniz. Uygulamanın ana penceresindeki sınıf listesine hemen seçtiğiniz program da gelecektir.

Reflector ile kaynak kodunu görebiliyoruz.
Reflector ile kaynak kodunu görebiliyoruz.

Ufak bir gezinti ile istediğiniz sınıfın veya metodun koduna doğrudan ulaşabilirsiniz. Reflector arayüzündeki “Programlama Dili” seçeneğinde VB, C#, Delphi ve IL seçenekleri bulunuyor. Bir önceki bölümde hazırladığımız uygulamamızı açarak Button.Click durumundaki kodu farklı dillerde Reflector ile alıp inceleyelim.

[VB]

Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs)

    Me.Label1.Text = Me.TextBox1.Text

End Sub

[C#]

private void Button1_Click(object sender, EventArgs e)

{

    this.Label1.Text = this.TextBox1.Text;

}

Yazdığımız kodlar ile Reflector’ın bize verdiği kodlar tam olarak aynı değil. Bu durum zaten çok normal. Çünkü MSIL koduna çeviri esnasında aslında çoğu şey değişiyor. Örneğin tanımladığımız değişkenlerin bize özel olan isimlendirmeleri yok oluyor veya bizim kullandığımız bazı kısa metotlar uzun şekilleri ile yazılabiliyor. Hatta özellikle VB içerisindeki casting kolaylıkları Compile esnasında farklı değişikliklere neden olabiliyor. Bu durumda De-Compile ile aldığımız kod da yazdığımız koddan biraz farklı oluyor. Yine de elimizde çalışır durumda bir kod olduğuna kesin gözü ile bakabiliriz.

Nasıl engelleriz? Obfuscation!

Herhalde çoğunuz “tüm kodlarımız gözler önünde” endişesi içerisindesiniz. Aslında durum gerçekten de öyle. Tabi bu durumun birçok faydası var. Kişisel olarak itiraf etmek gerekirse farklı yazılımları De-Compile ederek çok şey öğrendiğimi söyleyebilirim. Bir defasında da kendi ürettiğimiz bir yazılımı De-Compile etmemiz gerekmişti, gerçekten hayat kurtarmıştı. Peki bunu nasıl engelleyebiliriz? İlk olarak şunu açıkça belirtiyim, herhangi bir .NET uygulamasından MSIL kodunun alınmasını engellemenin hiçbir yolu yok. Yapabileceğimiz tek şey MSIL kodunun okunabilirliliğini azaltmak için işlevsel olarak aynı işi gören fakat daha karışık bir MSIL kodu yaratmak. Bu işlem obfuscation olarak adlandırılıyor.

Obfuscation ile ilgili sektörde çok sayıda ücretli yazılım bulabilirsiniz. Biz bunlardan Xenocode'aait Postbuild 2008 adındaki ticari yazılımı kullanarak obfuscation ile neler yapabildiğimize bakacağız. XenoCode’u ilk açtığımızda karşımıza hemen bir uygulama listesi geliyor. Bu listeye bir önceki adımda kendi hazırladığımız EXE dosyasını ekleyerek uygulamanın üst menüsünden “Protect” tabına geçiyoruz. Burada sadece Windows’da çalışacak EXE dosyalarına uygulanabilecek özel bir koruma yöntemi olan “Surpress ILDASM” seçeneğinin işaretini kaldırmamız gerek. Bu seçenek DLL’lere zaten uygulanamayacaktır. Ekranın sağ tarafında korumak istediğimiz sınıfların ve metodların bir listesini işaretleyebiliyoruz. Tüm ayarları tamamladıktan sonra uygulamanın sağ altındaki “XenoCode Application” düğmesine basıyoruz.

Obfuscation işlemi için yollardayız
Obfuscation işlemi için yollardayız

Obfuscation işlemini tamamladıktan sonra sıra geldi testlerimizi yapmaya. İlk olarak uygulamamızı ILDASM ile açarak bakalım MSIL kodumuz ne hale gelmiş.

[MSIL]

.method private instance void  x44d0c0526a414989(object xe0292b9ed559da7d,

                                                class [mscorlib]System.EventArgs xfbf34718e704c6bc) cil managed

{

  // Code size       23 (0x17)

  .maxstack  8

  IL_0000:  ldarg.0

  IL_0001:  callvirt   instance class [System.Windows.Forms]System.Windows.Forms.Label WindowsApplication1.xaa4f033827d75b4d::get_x029e304eb4c44750()

  IL_0006:  ldarg.0

  IL_0007:  callvirt   instance class [System.Windows.Forms]System.Windows.Forms.TextBox WindowsApplication1.xaa4f033827d75b4d::get_x77691a2cfb8f8048()

  IL_000c:  callvirt   instance string [System.Windows.Forms]System.Windows.Forms.TextBox::get_Text()

  IL_0011:  callvirt   instance void [System.Windows.Forms]System.Windows.Forms.Label::set_Text(string)

  IL_0016:  ret

} // end of method xaa4f033827d75b4d::x44d0c0526a414989

Gördüğünüz gibi aslında çok büyük bir değişiklik yok. Sadece sınıfların ve metodların isimleri değiştirilerek karışık isimler verilmiş. Aynı uygulamayı Reflector ile açtığımızda ise aşağıdaki kodları elde ediyoruz.

[VB]

Private Sub x44d0c0526a414989(ByVal xe0292b9ed559da7d As Object, ByVal xfbf34718e704c6bc As EventArgs)

    Me.x029e304eb4c44750.Text = Me.x77691a2cfb8f8048.Text

End Sub

[C#]

private void x44d0c0526a414989(object xe0292b9ed559da7d, EventArgs xfbf34718e704c6bc)

{

    this.x029e304eb4c44750.Text = this.x77691a2cfb8f8048.Text;

}

Kodlar epey okunurluluğunu kaybetmiş durumda. Bizim örneğimizde sadece tek bir satır kod bulunduğu için neyin ne olduğunu anlamak çok zor olmuyor. Fakat binlerde satırdan oluşan uygulamaların kodlarından anlaşılabilir bir sonuç çıkarmak neredeyse imkânsız olacaktır.

Hepinize kolay gelsin.

Friday, September 19, 2008 6:27:11 PM (GTB Standard Time, UTC+02:00)  #    Comments [11]   .NET Framework 3.0 | .NET Framework 3.5 | ASP.NET | ASP.NET 3.5 | Silverlight 2.0 | Visual Basic 2005 | Visual Basic 2008 | Visual Studio 2005 | Visual Studio 2008  | 
 Thursday, September 18, 2008

WPF ile beraber özellikle video uygulamalarının programlanmasındaki kolaylık sonucunda artık Multimedya alanında da sıkça .NET ile programlanmış uygulamalar görebiliyoruz. Bu yolda WPF içerisindeki MediaElement'in katkısı tabi ki yadsınamaz. Bu yazımızda WPF içerisinde açtığımız bir video dosyasından bir kare (thumbnail) almayı deneyeceğiz.

Bu işlemi yapmak için normal şartlarda C++ ile DirectShow üzerine çalışmak gerekiyor. Diğer .NET dilleri için Managed Provider'lar bağımsız yazılımcılarca yazılmış olsa da kolay bir çözüm maalesef ki yok. Bu nedenle biz kendi kodumuzda MediaPlayer ile bir video dosyasını açacak ve istediğimiz saniyesine giderek o anki kareyi yakalayacağız. Kodumuz MediaPlayer'in yani uygulamanın çalıştığı bilgisayarda Media Player'ın oynatabildiği her video ile çalışacaktır, herhangi bir kodek sınırımız olmayacak.

Dikkat: MediaPlayer / Media Player ve MediaElement farklı şeylerdir. MediaPlayer doğrudan System.Windows.Media.MediaPlayer sınıfını tanımlarken, Media Player ise yazı boyunca bir bilgisayarda yüklü olan uygulama olarak Media Player'ı anlatacaktır. Diğer yandan MediaElement ise System.Windows.Controls.MediaElement sınıfını tanımlar. MediaElement ile MediaPlayer sınıfları arasındaki en büyük fark MediaPlayer'ın görsel olarak bir WPF formunda doğrudan video gösterememesidir. Videonun ne şekilde nerede gösterileceğine MediaPlayer için kod ile karar vermek gerekir.

Önce videomuzu bir oynatalım.

Uygulamamızda ilk olarak bir MediaPlayer yaratmamız ve sonrasında da istediğimiz video dosyasını söz konusu MediaPlayer içerisinde oynatmamız gerekiyor. Tüm bunları kodlarla yapacağız.

[VB]

        Dim birMediaPlayer As New MediaPlayer

        birMediaPlayer.Open(New Uri("C:\Users\Public\Videos\Sample Videos\Bear.wmv", UriKind.Absolute))

        birMediaPlayer.Play()

        birMediaPlayer.IsMuted = True

        birMediaPlayer.Position = New TimeSpan(0, 0, 5)

[C#]

            MediaPlayer birMediaPlayer = new MediaPlayer();

            birMediaPlayer.Open(new Uri(@"C:\Users\Public\Videos\Sample Videos\Butterfly.wmv"));

            birMediaPlayer.Play();

            birMediaPlayer.IsMuted = true;

            birMediaPlayer.Position = new TimeSpan(0, 0, 5);

Yukarıdaki kodumuzda birMediaPlayer adını verdiğimiz MediaPlayer değişkenimize bilgisayardaki bir video dosyasını açtırıyoruz. Sonrasında hemen videoyu oynatmaya başlıyoruz aksi halde herhangi bir görsel elde etme şansımız kalmaz. Bu esnada videodan ses gelmemesi için sesini de kısıp doğrudan videonun beşinci saniyesine zıplıyoruz.

[VB]

        System.Threading.Thread.Sleep(5000)

        Dim RenderTarBitmap As New RenderTargetBitmap(1600, 1200, 1 / 96, 1 / 96, PixelFormats.Pbgra32)

        Dim DVisual As New DrawingVisual

        Dim DContext As DrawingContext = DVisual.RenderOpen

        DContext.DrawVideo(birMediaPlayer, New Rect(0, 0, 1600, 1200))

        DContext.Close()

        RenderTarBitmap.Render(DVisual)

        birMediaPlayer.Stop()

        Dim BMPFrame As BitmapFrame = BitmapFrame.Create(RenderTarBitmap)

[C#]

            System.Threading.Thread.Sleep(5000);

            RenderTargetBitmap RenderTarBitmap = new RenderTargetBitmap(1600, 1200, 1 / 96, 1 / 96, PixelFormats.Pbgra32);

            DrawingVisual DVisual = new DrawingVisual();

            DrawingContext DContext = DVisual.RenderOpen();

            DContext.DrawVideo(birMediaPlayer, new Rect(0, 0, 1600, 1200));

            DContext.Close();

            RenderTarBitmap.Render(DVisual);

            birMediaPlayer.Stop();

            BitmapFrame BMPFrame = BitmapFrame.Create(RenderTarBitmap);

İşte bu adımda gördüğünüz kod aslında uygulamamızın kalbi. Hemen ilk satırdaki 5 saniyelik uyku modu dikkatinizi çekmiştir. Maalesef MediaPlayer'ın içerisinde bir video yükleyip oynatmaya başlamış olsak da bu işlemin tam olarak gerçekleşip gerçekleşmediğini anlama şansımız yok. Video dosyasının büyüklüğüne bağlı olarak dosyanın açılması uzun sürebilir. MediaPlayer'In MediaOpened event'ı ise tam olarak tahmin ettiğiniz şekilde çalışmıyor. Sonuç olarak en iyi seçecek 5 saniyelik bir bekleme süresi ile disk işlemlerinin tamamlanmasını beklemek. Tabi unutmamak gerek ki tüm bu yukarıdaki kodları harici bir Threat içerisinde yapmazsanız bu beş saniyelik sürede programınız kilitlenecektir.

Sonraki aşamalarda biraz daha karışık bir yapı kullanarak MediaPlayer'ın içerisinde görselliği almaya çalışıyoruz. RenderTargetBitmap sınıfı hem oluşturulacak olan görüntünün boyutlarını piksel olarak alıyor, hem de görüntünün dikey ve yatay olarak DPI (çözünürlük) değerini istiyor. RenderTargetBitmap'in son parametresi ise oluşturulacak olan görseldeki renk kanalları ile ilgili, bizim örneğimizde RGB ve Alpha kanallarını tek tek 8bit toplam 32 bit olarak alıyoruz.

Bir DrawingVisual nesnesi yaratıp Render işlemini de RenderOpen ile başlatarak o anki DrawingContext'i ele alıyoruz. DrawingContext'in DrawVideo metodu doğrudan bir MediaPlayer alarak o anki görüntüsüyü belirtilen bir alana çizebiliyor. Son olarak RenderTargetBitmap'in Render metodu ile eldeki Visual'dan bir bitmap yaratıyoruz. En sonda elde ettiğimiz BitmapFrame artık videodan almış olduğumuz son görüntüyü temsil ediyor. Sıra geldi bu görüntüyü JPEG olarak uygun bir dosyaya yazmaya.

[VB]

        Dim BMPEncoder As BitmapEncoder = New JpegBitmapEncoder

        Dim FStream As New IO.FileStream("C:\Users\Public\Videos\Sample Videos\Butterfly.jpg", IO.FileMode.Create)

        BMPEncoder.Frames.Add(BMPFrame)

        BMPEncoder.Save(FStream)

        FStream.Flush()

        FStream.Close()

[C#]

            BitmapEncoder BMPEncoder = new JpegBitmapEncoder();

            System.IO.FileStream FStream = new System.IO.FileStream(@"C:\Users\Public\Videos\Sample Videos\Butterfly.jpg", System.IO.FileMode.Create);

 

            BMPEncoder.Frames.Add(BMPFrame);

            BMPEncoder.Save(FStream);

            FStream.Flush();

            FStream.Close();

JpegBitmapEncoder sınıfı bizim için JPEG sıkıştırma işlemlerini halledecektir. Tek yapmamız gereken bir de FileStream yaratarak Encoder'a elimizdeki BitmapFrame'i ekleyerek FileStream'e eldeki veriyi Save metodu ile kaydetmek. Böylece dosyamız artık hazır, videodan karemizi istediğimiz çözünürlükte alabildik.

ASP.NET ile video dosyasından kare almak?

Konumuzla herhangi bir alakası yok gibi gözükebilir fakat aslında ASP.NET ile bir video dosyasından kare (thumbnail) alabilmek de bir başka işkencedir. İşin güzel tarafı .NET Framework içerisindeki tüm sınıflar aslında siz onları referans olarak almanız şartı ile sizin kullanımınıza açıktır. Özetle, yukarıdaki kod aynı şekilde ASP.NET'te de çalışır :) Nasıl mı?

Yukarıdaki kodumuz içerisinde kullandığımız sınıflardan MediaPlayer sınıfı .NET Framework içerisinde PresentationCore.DLL dosyasında bulunur. Kullandığımız diğer sınıflar ve PresentationCore.DLL'in Dependecy assembly'si olan bir diğer DLL'te WindowsBase.DLL dosyasıdır. Tüm bu dosyalar bilgisayarınızda C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0 adresinde bulunur. Yarattığınız herhangi bir ASP.NET sitesine bu DLL'leri referans olarak ekledikten sonra kodunuz aynı şekilde çalışacaktır.

Hepinize kolay gelsin.

Thursday, September 18, 2008 5:55:50 PM (GTB Standard Time, UTC+02:00)  #    Comments [2]   ASP.NET 3.5 | WPF  | 
 Wednesday, September 17, 2008

Internet Explorer 8.0 ile beraber yazılımcılar olarak karşılaştığımız bir diğer uygulama geliştirme alanı da "Accelerators" yapısı. Accelerator'lar ile tarayıcı içerisinde kullanıcıların farklı konumlarda sadece sağ tuşa tıklayarak hızlıca bazı içeriklere veya işlevselliklere ulaşmasını sağlayabiliyoruz. Gelin ilk olarak canlı bir örnek üzerinden bir Accelerator'ın ne olduğuna göz atalım.

Accelerator nedir?

Internet Explorer'ı bilgisayarınıza ilk yüklediğinizde varsayılan ayarları ile beraber LiveMaps'in Accelerator eklentisi de yüklenmiş olacaktır. Bu Accelerator bize herhangi bir web sitesine bir adresi seçip sağ tıkladığımızda o adresin doğrudan hızlı bir şekilde haritada görebilmemizi sağlıyor. Bu işlem için herhangi bir şekilde LiveMaps web sitesine gitmemiz gerekmiyor. Eğer ki adresi doğrudan LiveMaps'de görmek isterseniz bu sefer de herhangi bir adresi seçip sağ tuş ile gelen LiveMaps Accelerator'ını seçmeniz yeterli. Böylece hızlı bir şekilde kullanıcının LiveMaps gibi bir uygulamaya herhangi bir site adresi yazmadan kullanabilmesini sağlayabiliyoruz.

LiveMaps Accelerator uygulaması.
LiveMaps Accelerator uygulaması.

Kendi Accelerator'ımızı yazalım.

Yapacağımız uygulamayı öğrenirken konu mankeni olarak zargan.com sitesini kullanalım. İngilizceden Türkçeye ve Türkçeden İngilizceye çeviri yapan sitede herhangi bir kelimeyi arattığınız aşağıdaki şekilde bir adres ile karşılaşıyoruz.

http://www.zargan.com/sozluk.asp?Sozcuk=deneme

Aslında bizim farklı aramalar yaptırabilmemiz için siteye bu şekilde adresler göndermemiz yeterli olacaktır. Zargan'ın sistemini anladıktan sonra şimdi geçelim Accelerator'ların yapısını incelemeye ve eldeki siteye uygun bir Accelerator nasıl yazarız sorusunu cevaplamaya.

Her Accelerator bir XML dosyası içerisinde "OpenService Format" denilen bir standarda uygun şekilde yazılır. Accelerator'ın tüm çalışma yapısı bu XML içerisinde saklıdır. Hemen sizinle Zargan için çalışacak olan XML'i paylaşacağım.

<?xml version="1.0" encoding="UTF-8"?>

<openServiceDescription

    xmlns="http://www.microsoft.com/schemas/openservicedescription/1.0">

    <homepageUrl>http://www.zargan.com/</homepageUrl>

    <display>   

        <name>Zargan ile cevir</name>

        <icon>http://www.zargan.com/favicon.ico</icon>

    </display>

    <activity category="translate">

        <activityAction context="selection" >

            <preview action="http://www.zargan.com/sozluk.asp">

                <parameter name="Sozcuk" value="{selection}" />

            </preview>

            <execute action="http://www.zargan.com/sozluk.asp">

                <parameter name="Sozcuk" value="{selection}" type="text" />

            </execute>

        </activityAction>

    </activity>

</openServiceDescription>

Yukarıdaki gibi bir XML'i accelerator.xml gibi bir dosyaya kaydedip sitenize koyduktan sonra artık tek yapmanız gereken bu XML'in bir Accelerator olarak yüklenmesini sağlayacak JavaScript kodunu yazmak.

        <button onclick="window.external.addService('accelerator.xml')">Zargan Accelerator Ekle</button>

Artık kullanıcılar yukarıdaki düğmeye tıkladıklarında doğrudan Accelerator'ı yükleyebilecek ve Internet Explorer içerisinde herhangi bir metni seçip sağ tuşa bastıklarında gelen "Zargan ile çevir" komutunu verirlerse seçtikleri kelimenin çevirisini gösteren zargan.com sayfası otomatik olarak açılacaktır.

Daha da ileri gidip eğer "Zargan ile çevir" menüsünün üzerinde biraz dururlarsa ufak bir pencere içerisinde aynı LiveMaps Accelerator'ında olduğu gibi seçilen kelimenin arandığı sayfa da gösterilecektir. Tabi şu an için Zargan'ın bahsettiğimiz çerçeveye uygun tasarımda bir sayfası olmadığı için ortaya pek hoş bir manzara çıkmıyor fakat önemli olan bizim uygulayabilmiş olmamız.

Peki nedir bu XML'dekilerin anlamı?

Şimdi gelin çalışan XML'i parçalayarak bölüm bölüm neyin ne olduğuna ve ne anlama geldiğine bir göz atalım. İlk olarak XML'in ana yapısındaki hizmet sağlayıcı ile ilgili bilgileri içeren kısma bir bakalım.

<?xml version="1.0" encoding="UTF-8"?>

<openServiceDescription

    xmlns="http://www.microsoft.com/schemas/openservicedescription/1.0">

    <homepageUrl>http://www.zargan.com/</homepageUrl>

    <display>   

        <name>Zargan ile cevir</name>

        <icon>http://www.zargan.com/favicon.ico</icon>

    </display>

    <activity category="translate">

        <activityAction context="selection" >

            <preview action="http://www.zargan.com/sozluk.asp">

                <parameter name="Sozcuk" value="{selection}" />

            </preview>

            <execute action="http://www.zargan.com/sozluk.asp">

                <parameter name="Sozcuk" value="{selection}" type="text" />

            </execute>

        </activityAction>

    </activity>

</openServiceDescription>

homepageUrl içerisinde hizmeti sağlayan sitenin tam adresini girmemiz gerekiyor. Bu adres kullanıcılar Accelerator'ı sistemlerine eklerken göreceklerin adresin ta kendisi, bir anlamda hizmet sağlayıcının kimliğinin bir kanıtı olarak da kabul edebiliriz. Name tagları arasında yer alan metin doğrudan Accelerator'ın sağ tuş ile gelen menülerde gözükecek olan adı. Aynı şekilde icon tagları arasında adresi verilen ikon da sağ tuş ile gelen menülerde gösterilecektir.

Gelelim Accelerator'ımızın yapacağı işlere. Bizim Accelerator örneğimiz sayfada seçili olan metni alarak http://www.zargan.com/sozluk.asp adresine Sozcuk parametresi olarak göndermekle yükümlü. Bunun için ilk olarak Accelerator altında bir Activity tanımlıyoruz.

<?xml version="1.0" encoding="UTF-8"?>

<openServiceDescription

    xmlns="http://www.microsoft.com/schemas/openservicedescription/1.0">

    <homepageUrl>http://www.zargan.com/</homepageUrl>

    <display>   

        <name>Zargan ile cevir</name>

        <icon>http://www.zargan.com/favicon.ico</icon>

    </display>

    <activity category="translate">

        <activityAction context="selection" >

            <preview action="http://www.zargan.com/sozluk.asp">

                <parameter name="Sozcuk" value="{selection}" />

            </preview>

            <execute action="http://www.zargan.com/sozluk.asp">

                <parameter name="Sozcuk" value="{selection}" type="text" />

            </execute>

        </activityAction>

    </activity>

</openServiceDescription>

Yarattığımız activity tagının category özelliğine farklı değerler verebiliyoruz. Bu değerler Internet Explorer'ın kategoriye göre Accelerator'ları sıralayabilmesini sağlıyor. Kendi istediğiniz değerleri verebileceğiniz gibi olabildiğince genel geçer olması olası değerleri vermekte fayda var. Şu an için map (harita), blog (günlük), define (ansiklopedi), add (Bookmarking) ve translate (Çeviri) gibi kategoriler genel olarak kullanılanlar arasında.

<?xml version="1.0" encoding="UTF-8"?>

<openServiceDescription

    xmlns="http://www.microsoft.com/schemas/openservicedescription/1.0">

    <homepageUrl>http://www.zargan.com/</homepageUrl>

    <display>   

        <name>Zargan ile cevir</name>

        <icon>http://www.zargan.com/favicon.ico</icon>

    </display>

    <activity category="translate">

        <activityAction context="selection" >

            <preview action="http://www.zargan.com/sozluk.asp">

                <parameter name="Sozcuk" value="{selection}" />

            </preview>

            <execute action="http://www.zargan.com/sozluk.asp">

                <parameter name="Sozcuk" value="{selection}" type="text" />

            </execute>

        </activityAction>

    </activity>

</openServiceDescription>

Bir sonraki adımda bir activityAction tanımlıyoruz. activityAction'ın context değeri için farklı seçenekler mevcut. Bizim örneğimizde herhangi bir metin seçilerek sağ tuşa basıldığında işlem yapılacağı için selection değeri atanmış durumda. İsterseniz buraya link değerini de verebilirsiniz, böylece herhangi bir linke tıklandığında yapılacak işlemi belirleyebilirsiniz.

<?xml version="1.0" encoding="UTF-8"?>

<openServiceDescription

    xmlns="http://www.microsoft.com/schemas/openservicedescription/1.0">

    <homepageUrl>http://www.zargan.com/</homepageUrl>

    <display>   

        <name>Zargan ile cevir</name>

        <icon>http://www.zargan.com/favicon.ico</icon>

    </display>

    <activity category="translate">

        <activityAction context="selection" >

            <preview action="http://www.zargan.com/sozluk.asp">

                <parameter name="Sozcuk" value="{selection}" />

            </preview>

            <execute action="http://www.zargan.com/sozluk.asp">

                <parameter name="Sozcuk" value="{selection}" type="text" />

            </execute>

        </activityAction>

    </activity>

</openServiceDescription>

Sıra geldi execute tagları ile artık doğrudan yapılacak işleme karar vermeye. Sağ tuş ile tıklanarak gelen menüden Accelerator'a tıklandığında çalıştırılacak olan işlem bir POST veya GET olabilir. Execute taglarına method özelliği vererek POST ve GET arasında bir seçim yapabilirsiniz. Varsayılan değeri GET olduğu için ve bizim örneğimize bu seçenek uyduğu için method özelliğini ayarlamamıza gerek kalmadı. Action kısmına ise gidilecek adresi veriyoruz. Geriye Zargan'a gönderilecek olan parametre kaldı. Parametrenin adı (Name) Sozcuk, tipi (Type) metin (text) değeri ise kullanıcının seçtiği metin ({selection}) olmalı. Böylece XML içerisinde yapıyı da sanırım aydınlatmış olduk.

Seçili metni {selection} ile alarak parametre haline getirebildiğiniz gibi daha bir çok bilgiyi de elde edebilirsiniz.

  • documentDomain -Kullanıcının Acceleator'ı çalıştırdığı alan adı
  • documentTitle - Accelerator'ın çalıştırıldığı sayfanın Title (başlık) bilgisi.
  • documentUrl -  Accelerator'ın çalıştırıldığı sayfanın tam adresi.
  •  link - Eğer bir linke tıklanarak Acceleratır çalıştırılıyorsa linkin adresi.
  • linkDomain - Eğer bir linke tıklanarak Acceleratır çalıştırılıyorsa linkin alan adı.
  • linkRel - Eğer bir linke tıklanarak Acceleratır çalıştırılıyorsa linkin rel özelliği.
  • linkText - Eğer bir linke tıklanarak Acceleratır çalıştırılıyorsa linkin metni.
  • linkType - Eğer bir linke tıklanarak Acceleratır çalıştırılıyorsa linkin tipi.

Son olarak gelelim Accelerator'ın yanında gözüken önizleme ekranının XML kodlarına.

<?xml version="1.0" encoding="UTF-8"?>

<openServiceDescription

    xmlns="http://www.microsoft.com/schemas/openservicedescription/1.0">

    <homepageUrl>http://www.zargan.com/</homepageUrl>

    <display>   

        <name>Zargan ile cevir</name>

        <icon>http://www.zargan.com/favicon.ico</icon>

    </display>

    <activity category="translate">

        <activityAction context="selection" >

            <preview action="http://www.zargan.com/sozluk.asp">

                <parameter name="Sozcuk" value="{selection}" />

            </preview>

            <execute action="http://www.zargan.com/sozluk.asp">

                <parameter name="Sozcuk" value="{selection}" type="text" />

            </execute>

        </activityAction>

    </activity>

</openServiceDescription>

Ön izleme ekranı yaratmak için preview taglarını kullanmamız gerekiyor. Aynı execute taglarında olduğu gibi burada da action ve gönderilecek olan parametrenin ayarlanması gerekiyor. Normal şartlarda burada yönlendirilen sayfa (action) ile arama sonuçlarının doğrudan gösterileceği sayfanın tasarım olarak farklı olması gerekir. Buradaki sayfanın özellikle ön izleme penceresinin boyutlarına (320*240px) sığacak şekilde tasarlanması çok daha hoş bir kullanım deneyimi sağlayacaktır.

Hepinize kolay gelsin.

Wednesday, September 17, 2008 5:25:19 PM (GTB Standard Time, UTC+02:00)  #    Comments [4]   IE 8.0  | 
 Tuesday, September 16, 2008

Bugün 2008-2009 yılı MSP'lerinin ilk buluştukları MSP Bootcamp'ın ikinci gününde ben de tüm MSP'lerle buluşma ve tanışma şansına sahip oldum. Çoğunu Microsoft Yaz Okulu'ndan tanıdığım gençleri gördükçe önümüzde yıl için ümidim ve hevesim çok daha fazla arttı. Ufak bir oturumda ben INETA tarafıyla ilgili bilgi verdikten sonra sevgili dostum Burak Selim Şenyurt ile beraber "MVP nedir? Nasıl olunur?" konusuna da değindik.

MSP Bootcamp sonu.
MSP Bootcamp sonu.

Bu enerjinizi ve azminizi kaybetmeyin arkadaşlar. Daha çok işimiz var ;)

Tuesday, September 16, 2008 2:03:44 PM (GTB Standard Time, UTC+02:00)  #    Comments [16]    | 
 Monday, September 15, 2008

Bundan birkaç ay önce Microsoft tarafından duyurulan bir program olan DreamSpark programı benim ülkemizdeki öğrenciler adına heyecanla beklediğim bir gelişmeydi. Maalesef ilk duyurulduğunda Türkiye'de herhangi bir geçerliliği yoktu. Oysa şimdi artık Türkiye'de de DreamSpark'tan faydalanabiliyorsunuz.

DreamSpark da nesi?

Bu program sayesinde öğrenciler "öğrenciliklerini kanıtlayabildikleri" sürece Microsoft yazılımlarını ücretsiz olarak kullanabiliyorlar. Tabi ki akademik amaçlarla... Program şu an kısıtlı sayıda üniversite ile işbirliğinde yürüse de eminim ki yakında sayı artacaktır. Projenin detaylarına aşağıdaki adresten ulaşabilirsiniz.

http://dreamsparktr.msakademik.net/

Monday, September 15, 2008 12:56:49 PM (GTB Standard Time, UTC+02:00)  #    Comments [11]    | 
 Sunday, September 14, 2008

Internet Explorer 7.0 ile beraber alıştığımız "Search Providers" yapısına IE 8.0 içerisinde bazı eklemeler yapıldı. Bu eklemelerin içinde en dikkati çeken özellik "Search Suggestions" özelliği. Aslında biz yazılımcıların uzun süredir AJAX ile hazırladığımız ve AutoComplete adını verdiğimiz sistemin ta kendisi.

IE 8.0 içerisinde Search Suggestions örneği.
IE 8.0 içerisinde Search Suggestions örneği.

Artık IE içerisinde arama için siz bir şeyler yazdıkça o an seçtiğiniz "Search Provider" eğer "Search Suggestion" destekliyorsa otomatik olarak sonuçlar anında yukarıdaki gibi karşınıza gelecektir.

Search Provider nasıl hazırlanır?

Search Provider'lar aslında birer XML dosyası şeklinde hazırlanır. Bu XML dosyası içerisinde arama motoru ile ilgili tarayıcının ihtiyaç duyduğu bilgiler yer alır. Düşündüğümüzde bunlar tabi ki arama motorunun adı, adresi ve tarayıcıda gösterilecek olan ikonundan farklı bilgiler değiller.

<?xml version="1.0" encoding="UTF-8"?>

<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">

    <ShortName>AramaMotoruAdı</ShortName>

    <Url type="text/html" template="http://localhost:49438/WebSite2/?aranacak={searchTerms}"/>

    <Image height="16" width="16" type="image/icon">http://localhost:49438/WebSite2/aramaikonu.ico</Image>

</OpenSearchDescription>

Yukarıda görmüş olduğunuz XML formatı OpenSearch standartlarına uygun şekilde hazırlanmalıdır. ShortName tagları arasında arama motorunun adı, URL taglarının template özelliğine arama motorunun adresi yazılır. Adresi yazarken dikkat etmeniz gereken nokta aranacak terimler yerine denk gelen noktaya {searchTerms} yazmanız. Tarayıcı içerisinde kullanıcının arattığı herhangi bir şey doğrudan bu adresteki {searchTerms} yazının yerine konarak verilen adres çalıştırılacaktır. Son olarak isterseniz arama motorunuzun ikon dosyasını da bir Image tagı içerisine adresini yazarak iletebilirsiniz.

Yukarıdaki şekilde Search Provider dosyanızı hazırladıktan sonra artık geriye kalan tek şey kullanıcıların bu dosyayı bir Search Provider olarak bilgisayarlarına eklemelerini sağlayacak JavaScript kodunu yazmak.

<a

  href="#"

  onclick="window.external.AddSearchProvider('http://localhost:49438/WebSite2/arama.xml')">

  Search Provider Ekle

</a>

window.external.AddSearchProvider metoduna doğrudan XML dosyasının konumunu verirseniz yukarıdaki gibi bir linke tıklandığında Search Provider ekleme ekranının gelmesini sağlayabilirsiniz. Artık kullanıcılar sizin Search Provider'ınızı kullanabilirler.

Peki ya Search Suggestions?

Search Suggestions sistemi tabi ki Search Provider'ların üzerine eklenen bir sistem. O nedenle yukarıdaki gibi elinizde hazır bir Search Provider'ın zaten bulunması gerekiyor. Sonrasında eklemeler ile Search Provider'ınızı Search Suggestions destekli hale getirebiliyorsunuz.

<?xml version="1.0" encoding="UTF-8"?>

<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">

  <ShortName>AramaMotoruAdı</ShortName>

  <Url type="text/html"

      template="http://localhost:49438/WebSite2/?aranacak={searchTerms}"/>

  <Url type="application/x-suggestions+json"

      template="http://localhost:49438/WebSite2/json.ashx?aranacak={searchTerms}"/>

  <Url type="application/x-suggestions+xml"

      template="http://localhost:49438/WebSite2/xml.ashx?aranacak={searchTerms}"/>

  <Image height="16"

        width="16"

        type="image/icon">http://localhost:49438/WebSite2/aramaikonu.ico</Image>

</OpenSearchDescription>

Bir önceki örneğimizdeki arama.xml dosyasına iki URL daha ekliyoruz. Bu sefer eklediğimiz URL'lerin type özellikleri text/html değil de application/x-suggestions+json veya application/x-suggestions+xml olabiliyor. Her iki özelliği beraber kullanmanın herhangi bir anlamı yok. Amacımız Search Suggestion esnasından gösterilecek AutoComplete bilgisinin alınacağı adresi belirlemek. Bu adreslerden ya XML ya da JSON formatında veri aktarımı yapılabiliyor. Yine bu adresler içerisinde de aranan kelime doğrudan {searchTerms} kısmına yerleştiriliyor. XML veya JSON döndüreceği için en mantıklısı bu adreslerde ASHX (Generic Handler) kullanmak.

<SearchSuggestion>

  <Query>asp.net</Query>

  <Section>

    <Item>

      <Text>Sonuç 1</Text>

      <Description>Açıklama</Description>

      <Url>http://sonucadresi.com</Url>

    </Item>

  </Section>

</SearchSuggestion>

Yukarıdaki örnekte ASHX dosyamıza aranan parametresi olarak asp.net metnini gönderdiğimizde ortaya çıkan sonucu görebiliriz. Query tagları arasına doğrudan aranan parametresi tekrar yazdırarak tarayıcıya iletmemiz gerekiyor. Böylece tarayıcı gerçekten aranan şeyin sonucunun gelip gelmediğini kontrol edebiliyor. Sonrasında bir Section açarak içerisine tek tek item tagları içerisinde her arama sonucunun Text (metin), Description (Açıklama) ve Url (Adres) bilgisini veriyoruz. Bizim örneğimizde şimdilik sadece tek sonuç var. Tarayıcı en fazla 10 adet sonuç gösterebiliyor.

İlk Search Suggestion denememizin sonucu.
İlk Search Suggestion denememizin sonucu.

Yukarıdaki ekran görüntüsünde de inceleyebileceğiniz üzere XML'den gönderdiğimiz tek sonuç bilgisi otomatik olarak tarayıcı tarafından gösterilmiş durumda. Eğer kullanıcı gelen sonuçlardan herhangi birine tıklarsa o sonuca ait Url tagları ile gelen adrese yönlendirilir. Şimdi sıra geldi bu sonuçlara biraz da görsellik eklemeye.

Son bir defa tekrar yukarıdaki ekran görüntüsüne bir göz atalım. Dikkatinizi çektiyse en üstte "AramaMotoduAdı Suggestions" yazıyor. Bu başlık otomatik olarak arama motorunun adı alınarak sonuna "Suggestions" eklenerek oluşturuluyor. İşin güzel tarafı biz istersek alt başlıklar oluşturabiliyoruz.

<SearchSuggestion>

  <Query>asp</Query>

  <Section>

    <Separator title="Bölüm 1" />

    <Item>

      <Text>Sonuç 1</Text>

      <Description>Açıklamaa</Description>

      <Url>http://sonucadresi.com</Url>

    </Item>

    <Separator title="Bölüm 2" />

    <Item>

      <Text>Sonuç 2</Text>

      <Description>Açıklamaa</Description>

      <Url>http://sonucadresi.com</Url>

    </Item>

  </Section>

</SearchSuggestion>

Yukarıdaki XML içerisinde Separator tagları dikkatinizi çekecektir. Bu taglar title özelliklerindeki yazılarla beraber Search Suggestion içerisinde farklı bölümlemelerin oluşmasını sağlayacaktır.

İki bölümlü Search Suggestion.
İki bölümlü Search Suggestion.

Son olarak gelelim bu sonuçların yanına ufak birer de görsel yerleştirmeye. Böylece çok daha hoş bir görüntü oluşacaktır. Aslında tek yapmamız gereken her bir sonucu tanımlayan item elementinin içerisine bir de image elementi yerleştirerek sonuçla ilgili resmin adresini vermek.

<SearchSuggestion>

  <Query>asp</Query>

  <Section>

    <Separator title="Bölüm 1" />

    <Item>

      <Text>Sonuç 1</Text>

      <Image source="http://localhost:49438/WebSite2/dock.jpg"

            alt="Bir resim"

            width="75"

            height="50" />

      <Description>Açıklamaa</Description>

      <Url>http://sonucadresi.com</Url>

    </Item>

    <Separator title="Bölüm 2" />

    <Item>

      <Text>Sonuç 2</Text>

      <Description>Açıklamaa</Description>

      <Url>http://sonucadresi.com</Url>

    </Item>

  </Section>

</SearchSuggestion>

Daha önceki arama sonucunu tanımlayan XML dosyamızdaki ilk item tagının içerisine bir de Image tagı yerleştiriyoruz. Bu Image tagının aslında HTML'den bildiğimiz Image tagından neredeyse hiçbir farklı yok. Source özelliğine gösterilecek olan fotoğrafın adresini, alt özelliğine ToolTip metnini, width ve height özelliklerine de resmin gösterilecek olan boyutunu belirtmemiz yeterli olacaktır.

Search Suggestion içerisinde fotoğraf gösterimi.
Search Suggestion içerisinde fotoğraf gösterimi.

Bizim örneğimizde resmin boyutları XML içerisinde tanımlı şekilde. Bu boyutları sabit tutabileceğiniz gibi isterseniz dinamik olarak da ayarlayabilirsiniz. Bunun için Search Provider'ın XML tanımındaki URL bilgisinde ufak bir değişiklik yapmak gerekiyor.

  <Url type="application/x-suggestions+xml"

      template="http://localhost:49438/WebSite2/xml.ashx?aranacak={searchTerms}?}&amp;
maxgenislik={maxWidth}&amp;satiryuksekligi={rowHeight}&amp;bolumyuksekligi={sectionHeight}
"/>

ASHX dosyasına ek olarak gönderebileceğiniz {maxWidth}, {rowHeight} ve {sectionHeight} bilgileri tarayıcı tarafından otomatik olarak doldurulacaktır. {maxWidth} Search Suggestion barının genişliğini, {rowHeight} her bir sonucun gösterildiği satırının yüksekliğini, {sectionHeight} ise varsa bir bölümün toplam yüksekliğini verecektir. Bu bilgileri kullanıcının çözünürlüğüne göre değişeceği için sizde ASHX dosyanıza gelen parametrelere uygun şekilde XML yaratırken Image taglarının boyutlarını belirleyebilirsiniz.

Gelin işin bir de sunucu tarafına göz atalım ve son örneğimizdeki XML kodunu oluşturacak ASHX'ın arkasına bakalım.

[VB]

    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest

        context.Response.ContentType = "text/xml"

 

        Dim XMLFeed As New XDocument(New XDeclaration("1.0", "utf-8", "yes"))

        XMLFeed.Add(New XElement("SearchSuggestion", _

                      New XElement("Query", context.Request.QueryString("aranacak")), _

                        New XElement("Section", _

                          New XElement("Separator", _

                            New XAttribute("title", "Bölüm 1")), _

                          New XElement("Item", _

                            New XElement("Text", "Sonuç 1"), _

                            New XElement("Image", _

                              New XAttribute("source", "http://localhost:49438/WebSite2/dock.jpg"), _

                              New XAttribute("alt", "Bir resim"), _

                              New XAttribute("width", "75"), _

                              New XAttribute("height", "50")), _

                            New XElement("Description", "Açıklamaa"), _

                            New XElement("Url", "http://sonucadresi.com")), _

                          New XElement("Separator", _

                            New XAttribute("title", "Bölüm 2")), _

                          New XElement("Item", _

                            New XElement("Text", "Sonuç 2"), _

                            New XElement("Description", "Açıklamaa"), _

                            New XElement("Url", "http://sonucadresi.com")))))

        context.Response.Write(XMLFeed)

    End Sub

[C#]

    public void ProcessRequest (HttpContext context) {

        context.Response.ContentType = "text/xml";

 

        XDocument XMLFeed = new XDocument(new XDeclaration("1.0", "utf-8", "yes"));

        XMLFeed.Add(new XElement("SearchSuggestion",

            new XElement("Query", context.Request.QueryString["aranacak"].ToString()),

            new XElement("Section",

                new XElement("Separator",

                    new XAttribute("title", "Bölüm 1")),

                    new XElement("Item",

                        new XElement("Text", "Sonuç 1"),

                        new XElement("Image",

                            new XAttribute("source", "http://localhost:49438/WebSite2/dock.jpg"),

                            new XAttribute("alt", "Bir resim"),

                            new XAttribute("width", "75"),

                            new XAttribute("height", "50")),

                        new XElement("Description", "Açıklamaa"),

                        new XElement("Url", "http://sonucadresi.com")),

                new XElement("Separator",

                    new XAttribute("title", "Bölüm 2")),

                    new XElement("Item",

                        new XElement("Text", "Sonuç 2"),

                        new XElement("Description", "Açıklamaa"),

                        new XElement("Url", "http://sonucadresi.com")))));

 

        context.Response.Write(XMLFeed.ToString());

    }

Tabi tüm yukarıdaki kodun bir veritabanına bağlanması ve uygun şekilde For döngüleri ve LINQ sorguları ile birden çok item elementlerinin yaratılması gerekiyor.

İşin JSON tarafına baktığımızda maalesef programatik olarak kullanımı çok daha bir sistem söz konusu. Ayrıca JSON tarafında Separator ve Image nesneleri şu an için desteklenmiyor. O nedenle JSON kullanımı pek uygun değil.

Her Search Provider aynı anda bir Accelerator!

Internet Explorer 8.0 ile beraber gelen bir diğer yenilik de eski adıyla "Activities" olan "Accelerator"lar. Accelerator'ların detayına girmeyeceğiz, bunun için ayrı bir makale çok daha uygun olur fakat her Search Provider'ın aslında otomatik olarak da bir Accelerator olduğunu söyleyebiliriz. IE içerisinde herhangi bir web sayfasını açtıktan sonra bir metin seçip fare ile sağ tıkladığınızda Accelerator menüsünden Search Provider'ları görebilirsiniz.

Her Search Provider aynı anda bir Accelerator!
Her Search Provider aynı anda bir Accelerator!

Bu otomatik Accelerator yapısının oluşması için ek bir işlem yapmak gerekmiyor. İsterse kullanıcı rahatlıkla "Manage Accelerators" bölümünden arama motorunu ilk sağ tık ile gelen menüye de alabiliyor.

Search Provider'ı bulunabilir hale getirmek?

JavaScript kodu ile Search Provider ekleme işlemini görmüştük. Bunun haricinden tarayıcıların sayfanıza girildiği gibi uygun Search provider'ı otomatik olarak bulabilmesi için de aşağıdaki kodu sayfanın head bölümüne yerleştirebilirsiniz.

<link title="AramaMotoruAdı"

      rel="search"

      type="application/opensearchdescription+xml"

      href="AramaMotoruAdı">

Burada önemli olan nokta Search Provider'ı tanımlayan XML dosyası içerisinde ShortName ile bu tag içerisindeki title'ın kesinlikle aynı olması gerektiği. Aksi halde birleştirme işlemi yapılamayacaktır. link tagı içerisinde href özelliği doğrudan Search Provider'ın XML dosyasını göstermelidir.

Hepinize kolay gelsin.

Sunday, September 14, 2008 3:55:40 PM (GTB Standard Time, UTC+02:00)  #    Comments [1]   IE 8.0  | 
 Saturday, September 13, 2008

IE8.0 ile gelen ve biz web yazılım geliştiricilerin önümüzdeki dönemde belki de en fazla uygulayacağımız yeniliklerden biri Web Slice yapısı. Özellikle tasarımcılar için Expression Design ve Photoshop gibi araçlardan tanıdık gelecek olan Slice mantığı ile birebir ayı mantıkla bir uygulamadan bahsediyoruz. Kullanıcı hazırlamış olduğunuz web sitesinin belirli bir bölümü keserek kendi tarayıcısının bir parçası haline getiriyor. Tabi bu kesme işleminin nasıl yapılabileceği ve sonucunun ne olacağı konusunda bire bir yazılımcılar olarak biz devreye giriyoruz. Konuyu fazla uzatmadan ilk önce çalışan bir Web Slice nasılmış onu inceleyelim.

Web Slice nedir? ne değildir?

Örnek olarak şu an yayında olan canlı bir siteyi inceleyelim. EBay'in IE 8 Beta 2 uyumlu sitesini buradan inceleyebilirsiniz. Sitenin içerisinde ürünlerde bir aram yaptırdığınızda arama sonucunda gelen listeden herhangi bir ürünün üzerine fare ile gittiğinizde ürünün etrafında ilginç bir yeşil çerçeve ve solunda da özel bir ikon beliriyor.

Canlı bir WebSlice'a ait ikon!
Canlı bir WebSlice'a ait ikon!

Yukarıdaki resimde gördüğünüz yeşil ikona tıkladığımızda karşımıza "Subscripe to a Web Slice" uyarısı çıkıyor. "Add" düğmesine basarak bu Slice'ı IE 8.0'ın arayüzüne eklemiş oluyoruz.

WebSlice'ımız artık IE 8.0 araç çubuğunda duruyor.
WebSlice'ımız artık IE 8.0 araç çubuğunda duruyor.

Biraz önce Web Slice'ını eklediğimiz ürünü artık IE 8.0 araç çubuğundan takip edebiliyorum. Şu an için standart ayarlarda IE 2 saatlik aralıklarla gidip bu Web Slice'ın yenilenip yenilenmediğini kontrol edecek ve eğer yenilenmiş ise tarayıcının üst kısmında bu Web Slice kalın yazılarla gözükecek. İsterseniz kontrol edilme süresini Web Slice'a sağ tuş tıklayarak gelen menünden "Properties" komutunu vererek siz de ayarlayabilirsiniz.

Peki bu iş nasıl yapılıyor?

İlk olarak hazırlamış olduğunuz web sitesinde nerelerin birer Web Slice olacağına karar vermeniz gerekiyor. Web Slice olarak yerlere HTML kodları içerisinde Microformats ile işaretlemeler yapıyoruz. Microformats'ı bir HTML eklentisi gibi düşünebilirsiniz, HTML elementlerine farklı anlamlar kazandırmak için kullanılan bir standart. Buna bir örnek de XFN olabilir. Web Slice'lar da Microformats üzerinden çalışıyorlar.

        <div class="hslice" id="urun1">

            <div class="entry-title item_title">

                ÜRÜN ADI

            </div>

            <div class="entry-content">

                Ürünle ilgili özellikler

            </div>

            <a rel="feedurl" href="/slicebilgi.ashx?ID=1"></a>

        </div>

Yukarıda gördüğünüz HTML kodu bir WebSlice'ı tanımlıyor. Bu kod içerisindeki tagların DIV olmalarının hiçbir önemi yok. Esas önemli olanlar Microformat'lar yani class isimleri!

Bir WebSlice'ın oluşturulabilmesi için kesinlikle tüm WebSlice'ın bir ana HTML elementi içerisinde yer alması gerekiyor. Bu HTML elementinin class ismi olarak hslice'a sahip olması şart. Unutmayın bu isimlerde CSS sınıfları tanımlayarak aynı anda bu classları görsel değişiklikler için de kullanabilirsiniz fakat WebSlice'ın yapısının IE 8.0'ın anlayabilmesi için classların isimlerinin değiştirilmemesi gerekir. hslice olan ana elementin kesinlikle bir ID'ye sahip olması gerekiyor, bu ID'nin standart HTML kuralları çerçevesinde sayfada tek olması da şart.

Yukarıdaki örnek kodumuzu incelersek bir de entry-title CSS sınıfını göreceksiniz. Bu şekilde işaretlenmiş bir elementin içerisinde metin tarayıcı tarafından Web Slice'ın ismi olarak algılanacak ve kullanıcıya da bu şekilde gösterilecektir. Ayrıca Web Slice'ın IE içerisinde araç çubuğunda ilk gözüken kısmı da entry-title'dan alınır.

entry-content şeklinde işaretli kısımlar bu sayfadan kesilerek Web Slice'ın tarayıcının araç çubuğundan ulaşılacak kısımlarını tanımlıyor. Araç çubuğunda herhangi bir WebSlice'a tıklandığında sadece site içerisinde bu WebSlice ile ilişkili olarak entry-content şeklinde işaretli yerler alınarak gösterilecektir. Bunun haricinde isterseniz WebSlice'ın araç çubuğundan gösterilecek kısmını farklı kaynaklardan da alabilirsiniz. Örneğin harici bir RSS kaynağı kullanılabilir.

Örneğimizde içinde yazı olmayan bir link "a" tagı görüyorsunuz. Bu tag kullanıcıya gösterilmeyecek fakat önemli olan bu tagın rel özelliğinde feedurl değerini taşıması. Böylece WebSlice tarayıcıya eklendiğinde tarayıcı WebSlice içerisinde gösterilecek veriyi entry-content olarak ayarlanmış bölümlerden değil de doğrudan harici bir RSS kaynağından alacak.

RSS kaynağı nasıl ayarlanır?

Eğer WebSlice içerisinden harici kaynak kullanılacaksa en mantıklısı bir RSS kullanmak olacaktır. Tabi WebSlice'ın sayfa içindeki rel özelliği feedurl olan adresin bu WebSlice'a özel olması şart. Yani bizim örneğimizde 1 numaralı ürünle ilgili RSS kaynağının gelmesi için slicebilgi.ashx dosyasına parametre olarak ürün ID'sini gönderiyoruz. Söz konusu adresten çıkan RSS içerisinde ilk item nesnesi doğrudan IE tarafından alınarak Web Slice içerisinde gösterilecektir.

<rss version="2.0">

  <channel>

    <title>WebSlice RSS</title>

    <ttl>120</ttl>

    <item>

      <title>Ürün Bilgisi</title>

      <description>HTML &lt;b&gt;kod&lt;/b&gt; gider</description>

    </item>

  </channel>

</rss>

Yukarıdaki gibi basit bir RSS kaynağının Generic Handler(ASHX) üzerinden aktarılıyor olması yeterli. ASHX'in arkasında VB veya C# kodunuzda gelen ID parametresine göre veritabanından veri alabilir ve uygun içeriği üretebilirsiniz. Item tagları içerisinde title IE içerisinde araç çubuğunda WebSlice'da gözükecektir. Description içerisinde kod ise doğrudan Web Slice'ın içeriğini tanımlar.

Yukarıdaki gibi bir RSS'i rahatlıkla XLINQ ile yaratabilirsiniz.

[VB]

Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest

    context.Response.ContentType = "text/xml"

 

    Dim RSS = New XDocument()

    RSS.Add(New XElement("rss", New XAttribute("version", "2.0"), _

               New XElement("channel", _

                  New XElement("title", "WebSlice RSS"), _

                  New XElement("ttl", "120"), _

                  New XElement("item", _

                    New XElement("title", "Ürün Bilgisi" & context.Request.QueryString("id")), _

                    New XElement("description", "HTML <b>kod</b> gider")))))

    context.Response.Write(RSS.ToString())

End Sub

[C#]

    public void ProcessRequest (HttpContext context) {

        context.Response.ContentType = "text/xml";

 

        XDocument RSS = new XDocument();

        RSS.Add(new XElement("rss",

            new XAttribute("version", "2.0"),

            new XElement("channel",

                new XElement("title", "WebSlice RSS"),

                new XElement("ttl", "120"),

                new XElement("item",

                    new XElement("title", "Ürün Bilgisi" + context.Request.QueryString["id"].ToString()),

                    new XElement("description", "HTML <b>kod</b> gider")))));

        context.Response.Write(RSS.ToString());

    }

İçerik kadar sürede bir yenilensin?

Yazımın başında da bahsettiğim gibi kullanıcı WebSlice içeriğinin ne kadar zamanda bir yenilenmesi gerektiğine karar verebiliyor. Fakat bunun haricinde yazılımcı olarak bizim de TTL (Time To Live) değeri vererek içeriğin ne kadar zamana kadar geçerli olduğunu belirtebiliyoruz. Hemen bir önceki örneğimizdeki RSS kaynağındaki TTL değeri de dikkatinizi çekmiştir. TTL değerleri dakika üzerinden verilir. İsterseniz WebSlice'ın ana sayfadaki HTML kodunun içerisinde de Class adı ttl olan bir tag içerisinde bu değeri yazabilirsiniz.

Slice'lar var ama biraz kapalı kalsalar olmaz mı?

HTML kodunuz içerisinde Slice'lar var fakat bir süreliğine veya belirli bir sayfada IE'nin yeşil Slice çerçevelerini ve düğmelerini göstermesini istemiyorsunuz. İşte bu durumda aşağıdaki Meta taglarını kullanabilirsiniz.

<meta name="slice" scheme="IE" content="off" />

Yeşil düğmeler ortadan kaybolsa da Slice'lar çalışmaya devam eder ve kullanıcılar isterlerse IE içerisinde Slice menüsünden tüm Slice'ları görebilir. Ayrıca sayfadaki Slice'ları istemci tarafında dinamik olarak yaratıyorsanız veya değiştiriyorsanız IE'nin Slice Discovery'sini yenilemek ve Slice menüsündeki Slice listesinin güncellenmesini sağlamak için aşağıdaki JavaScript komutunu çağırabilirsiniz.

window.external.contentDiscoveryReset()

Slice ekleme düğmelerinin tasarımını değiştirilir mi?

Slice'ların hepsi kendi özel yeşil düğmeleri ile eklenebilse de bu yeşil düğmeleri yukarıdaki taktik ile kapattığınızda kendi düğmeleriniz ile Slice'ları ekletmek isteyebilirsiniz. Bunun için özel olarak kullanabileceğimiz bir JavaScript komutu yer alıyor.

window.external.addToFavoritesBar('http://sliceburada.com', 'SliceTitleBurada', 'slice')

Yukarıdaki JavaScript metoduna verdiğimiz üç parametreden ilki doğrudan Slice'ın HTML hslice kodlarının bulunduğu adresin ta kendisi. İkinci parametre sayfadaki hangi Slice'ı istediğimizi belirten Slice'ın ID bilgisi. Son olarak eklenecek öğenin tipini de slice olarak belirtiyoruz.

Hepinize kolay gelsin.

Saturday, September 13, 2008 4:52:00 PM (GTB Standard Time, UTC+02:00)  #    Comments [4]   IE 8.0  | 
 Friday, September 12, 2008

AJAX ile programlama yaparken en sık kullandığımız veri taşıma formatlarından biri JSON (JavaScript Object Notation). Detaylarına baktığımızda ASP.NET AJAX içerisinde de tüm PageMethod'lar sunucundan istemciye JSON formatından veri gönderiyor. Bunun tabi ki anlamlı nedenleri var; JSON XML'e kıyasla çok daha düşük boyutta çok daha fazla veri taşıyabiliyor. Ayrıca JSON'un JavaScript tarafında kullanımı XML'e göre daha kolay. JSON'un artık neredeyse tüm AJAX kütüphanelerinde kullanıldığını düşünürsek Microsoft tarafında da IE 8.0'a JSON ile ilgili özelliklerin eklenmesi gerektiği kararı alınarak Beta 2 ile beraber doğrudan JSON'a özel yeni JavaScript özellikleri sunuluyor. Gelin neler varmış beraber inceleyelim.

Eval() mi? İmdat!

AJAX kullanılan sitelerdeki en büyük güvenlik açıklarının arkasına baktığımızda belki de çoğu zaman Eval metodu karşımıza çıkacaktır. Peki Eval metodu ne yapar? Eval kendisine String olarak verilen bir değişkenin içindekileri bir kodmuş gibi çalıştırır. Örneğin aşağıdaki kod çalıştırıldığında ekrana normalde alert JavaScript metodu çalıştırılarak getirilen bir mesaj kutusu gelecektir.

        var Degisken = "alert('DENEME');";

        eval(Degisken);

Gördüğünüz gibi aslında çalıştırılan kod doğrudan bir metin olarak başka bir değişkenin içerisinde saklanıyor. Güvenlik açığı nerede? JSON kullandığınızda sunucudan gelen bir metni doğrudan Eval ile çalıştırarak JSON'un bir JavaScript dizisi olmasını sağlarız. Bu noktada eğer veri harici bir kaynaktan geliyorsa veya bu veriyi daha önce kullanıcı girmişse aslında kullanıcının doğrudan sitenizde çalıştırılacak bir JavaScript kodunu girmesini sağlamış olursunuz. Bunu engellemenin tabi ki yolları var, harici kütüphanalerde yine JavaScript ile eval'e verilen metinleri Parse ederek inceleyen metodlar mevcut, hatta bazıları bunun için Regular Expression bile kullanabiliyor. Fakat bunların hepsi unutmayalım ki yine JavaScript metodları kullanılarak yapılan işlemler. Oysa bizim doğrudan tarayıcı motorunda bu işlemleri yapan bir sistemimiz olsa daha hızlı ve güvenli olmaz mı?

IE 8.0 ve JSON

IE 8.0 Beta 2 ile beraber doğrudan JSON'u parse edebilme özelliği geliyor. Serialization ve Deserialization işlemlerini doğrudan IE içerisinde Native kodlar yaptığı için tabi ki ortaya çok daha yüksek performanslı bir çözüm çıkıyor.

        var KitaplarMetin = "{\"kitaplar\":{\"kitap\":[\"ASP.NET AJAX\",\"ASP.NET 3.5 AJAX\"]}}";

        var Kitaplar = JSON.parse(KitaplarMetin);

        alert(Kitaplar.kitaplar.kitap[0]);

Yukarıdaki kod içerisinde KitaplarMetin değişkenine bir JSON metni aktarıyoruz. Bu metnin bir şekilde JavaScript nesnelerine çevrilmesi gerekiyor. Bunun için klasik eval metodunu kullanmaktansa doğrudan IE 8.0 Beta 2 ile beraber gelen JSON nesnesinin parse özelliğini kullanıyoruz. Son satırda ise artık Kitaplar değişkenimize aktarılan JSON nesnelerinin içerisinden ilk kitabın adını alıyoruz.

Peki ya eldeki JavaScript nesnelerini JSON'dan standart metne çevirmek istersek ne yapacağız? Bu durumda da yardımımıza yine JSON nesnesinin stringify metodu yetişiyor.

        var Kitaplar = {

            kitaplar:{

                kitap:[

                    'ASP.NET AJAX',

                    'ASP.NET 3.5 AJAX'

                ]

            }

        };

        alert(JSON.stringify(Kitaplar));

Yukarıdaki örnekte yarattığımız Kitaplar adından nesneyi stringify metodu ile bir JSON metnine çeviriyoruz. Ayrıca isteyenler haricen .toJSON metodunu da kullanabilirler. IE 8.0 ile beraber standart olarak Boolean, String, Date, Number sınıflarının prototiplerine toJSON metodu eklenmiş durumda.

Zaten JSON sınıfı lokalde harici dosya ile tanımlıydı!

Bugüne kadar harici kütüphanelerle yukarıdaki işlemleri yaptığımız için tabi ki bu kütüphanelerin JSON nesnesi tanımladıklarını unutmadık. Böyle bir durumda aşağıdaki gibi ufak bir kontrol ile tarayıcının JSON nesnesini tanımlayıp tanımlamadığını kontrol edip eğer tanımlı değilse harici scriptler üzerinden ilerlemek gerek.

        if(!this.JSON)

        {

            JSON = .....;

        }

Hepinize kolay gelsin.

Friday, September 12, 2008 3:16:04 PM (GTB Standard Time, UTC+02:00)  #    Comments [1]   IE 8.0  | 
 Thursday, September 11, 2008

Internet Explorer içerisinde en büyük eksikliklerden biri de biz yazılım geliştiriciler için gerekli profilleme de hata bulma araçlarına sahip olmamasıydı. Bunun için bazı durumlarda harici eklentiler kullanırken bazen alternatif tarayıcılara da yönelmek zorunda kalıyorduk. Bu yazımızda yukarıda bahsi geçen sorunları çözme amacıyla Internet Explorer 8.0'a eklenmiş olan "Developer Tools" uygulamasını inceleyeceğiz.

CSS ve HTML DOM gerçek zamanlı düzenleme

Internet Explorer 8.0 içerisinde Tools menüsünden ulaşabileceğiniz "Developer Tools" ayrı bir pencerede ayrı bir programmış gibi açılsa da tabi ki tarayıcı ile entegre çalışıyor. Açılan "Developer Tools" penceresinin sağ üst köşesinde "Pin" düğmesine basarsanız bu pencere kendini IE içerisine yerleştirecektir. Açtığınız herhangi bir sitenin  HTML DOM'unu incelemenin yanı sıra CSS konusunda raporlar da alabiliyorsunuz. Hangi CSS sınıfının nereden geldiği, ve sayfada geçerli olup olmadığını görebiliyorsunuz. Örneğin harici bir CSS ayarı local satır içi bir stil ayarı ile devre dışı bırakılmış olabilir. Tüm bunları rahatlıkla bir liste olarak görmek mümkün.

CSS ve DOM tam kontrol altında!
CSS ve DOM tam kontrol altında!

Yukarıdaki gördüğünüz ekranda sol tarafta sayfanın DOM ağacını inceleyebilirsiniz. DOM içerisinde herhangi bir element özel olarak seçildiğinde o elementi etkileyen tüm CSS sınıfları, özellikleri ve bu özelliklerin nereden geldikleri sağ tarafta görülebiliyor. Daha da güzeli sağ taraftaki herhangi bir özelliğe tıklarsanız istediğiniz bir değeri değiştirerek IE içerisinde gerçek zamanlı olarak sonucu görebiliyorsunuz.

İsterseniz "Developer Tools" içerisinde HTML tabından CSS tabına geçerek doğrudan sayfadaki tüm CSS özelliklerini yakalayabilir ve gerçek zamanlı olarak değişiklikler de yapabilirsiniz. Tüm bu değişiklikleri tamamladıktan sonra araç çubuğundaki "Kaydet" düğmesine basmanız CSS dosyanızın o anki hali ile kaydedilmesi için yeterli.

JavaScript Debuging

Visual Studio içerisinde JavaScript Debuging'e kıyasla çok daha başarılı bulduğum IE 8.0 Developer Tools içerisinde JavaScript araçlarının en büyük avantajı doğrudan IE ile beraber çalıştıkları için tarayıcı içerisindeki tüm aktiviteyi takip edebiliyor olmak. İsterseniz herhangi bir JavaScript değişkenine aynı Visual Studio içerisinde VB veya C# kodlarına yaptığımız gibi Watch'lar ekleyin veya istediğiniz bir adıma BreakPoint yerleştirin. Hatta F10 ve F5 gibi Visual Studio kısayolları bile aynı.

JavaScript tarafında Watch koyarak durumu takip edin.
JavaScript tarafında Watch koyarak durumu takip edin.

Özellikle Silverlight 1.0 tarafında yazılan JavaScript kodlarının veya AJAX tarafında yazılan veri ulaşım kodlarının incelenmesi ve hataların bulunması epey kolaylaşmış durumda. Aşağıdaki görsel içerisinde JavaScript ile tanımlanmış bir Silverlight nesnesinin Source özelliğine verilen değeri doğrudan "Locals" tabı üzerinden giderek sayfada tanımlanmış tüm JavaScript nesnelerini listeleyip bulabiliyoruz. Tüm bunları yaparken istediğiniz anda herhangi bir değişkenin değerini Developer Tools içerisinde değiştirebilirsiniz, sonucu gerçek zamanlı olarak IE içerisinde göreceksiniz.

JavaScript tarafındaki sayfada bulunan tüm nesneler ve değişkenler düzenlenebiliyor.
JavaScript tarafındaki sayfada bulunan tüm nesneler ve değişkenler düzenlenebiliyor.

Profiler ile optimizasyon

Yazdığımız kodun ne kadar optimize olduğunu anlamak çok önemli. Bunun için tam olarak hangi kodun daha çok zaman aldığını bilmeliyiz. Özellikle SQL tarafında alışık olduğumuz Profiler sistemine benzeyen bir yapı ile artık IE üzerinde de Developer Tools içerisinde bir Profiler bulunuyor. "Start Profiler" düğmesine bastıktan sonra IE penceresine geçip site üzerinde istediğiniz işlemleri yapabiliyorsunuz. Sonra Developer Tools'a dönerek "Stop Profiler" dediğinizde geçen süre içerisinde yaptığınız tüm işlemlerin bir listesi karşınıza çıkıyor. Bu listeyi ister bir "Function" listesi olarak alın ister bir ağaç görüntüsünde hangi function'ın hangisini çağırdığına bakarak inceleyin. Önemli olan artık hangi işlemin ne kadar sürdüğünü görebiliyor olmamız.

Kod optimizasyonu için Profiler
Kod optimizasyonu için Profiler

Image Optimizasyonu

Bazı durumlarda bir web sitesine koyduğumuz resmin hem en ve boy boyutu hem de dosya boyutuna bakabilmek için doğrudan dosyanın kendisini bulmamız gerekebilir. Developer Tools içerisinde Image menüsü böyle bir durumda yardımımıza koşuyor ve doğrudan gerçek zamanlı olarak gezdiğiniz tüm sitelerdeki resimlerin boyutlarını resimlerin üzerine yazıyor. Gerçekten hoş bir özellik.

Gerçek zamanlı olarak sitedeki resimlerle ilgili detayları görebilirsiniz.
Gerçek zamanlı olarak sitedeki resimlerle ilgili detayları görebilirsiniz.

Pratik araçlar

Bir sayfadaki tüm DIV'leri görmek mi istiyorsunuz, tek yapmanız gereken "Outline" menüsünden DIV seçeneğini işaretlemek. Böylece gerçek zamanlı olarak sayfa içerisinde tüm DIV'ler ayrıca birer çerçeve içine alınacaktır. Sadece DIV elementleri değil istediğiniz bir elementi kendiniz de belirterek aranmasını sağlayabilirsiniz.

Tools menüsünden "Show Ruler" özelliği ile fare ile ekranda tıkladığınız iki nokta arasında mesafeyi piksel olarak ölçebilir bu mesafeler arasında X ve Y koordinatları farkları görebilirsiniz.

Pratik araçlardan biri : Cetvel!
Pratik araçlardan biri : Cetvel!

Aynı menüdeki "Show Color Picker" ile gezdiğiniz sitedeki herhangi bir rengi seçebilir RGB ve HEX renk kodlarını alabilirsiniz. "Resize" menüsünden ekran çözünürlükleri seçerek tarayıcının otomatik olarak farklı ekran çözünürlüğündeymiş gibi boyutlandırılmasını sağlayabilirsiniz.

Sonuç

IE 8.0 çok ilginç ve güzel yenilikler ile geliyor. IE içerisinde bu kadar geniş özelliklere sahip bir  Developer Tools paketi görmek çok sevindirici. Umarım daha yeni özellikler ile IE'nin sonraki sürümlerinde de gelişmeye devam eder.

Hepinize kolay gelsin.

Thursday, September 11, 2008 4:00:37 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   IE 8.0  | 
 Wednesday, September 10, 2008

En son Microsoft sınavlarına gireli epey uzun zaman olmuş. Bugün yeni sınav serilerinden 70-502 Microsoft .NET Framework 3.5 – Windows Presentation Foundation Application Development sınavına girdim. Tüm MS sınavlarında olduğu gibi 1000 üzerinden 700 skor ile geçilen sınavı 952 ile geçtim. 1000 yapsam güzel olacaktı :) daha önce 1000 yaptığım sınavlar olmuştu, ilginç bir duygu olduğunu itiraf etmeliyim :)

Sonuçta MCTS (M. Certified Technology Specialist) competency'si olarak bir de WPF eklenmiş oldu transcriptime. Maalesef bu sınav MCPD'nin sonraki sürümleri için gerekli sınavlar arasında değil. Yani normal şartlarda .NET Framework 3.5 üzerinden MCPD olmak isteyenlerin bu sınava girmeleri gerekmiyor. Winforms tarafı yeterli oluyor. İlgilenenler için belirtiyim daha Upgrade sınavları çıkmadı :(

Şimdi eminim ki bu postumdan sonra akılda sertifikasyon sınavları ile ilgili sorular belirecek, o nedenle benim aklıma gelenleri bir cevaplıyım :)

Soru: Sınava nerelerde giriliyor?
Cevap: Sınava Prometric Test Merkezleri'nde girebilirsiniz. Ülke ve şehre göre sınav merkezi listesine www.prometric.com üzerinden ulaşabilirsiniz.

Soru: Sınava girmek için eğitim almak şart mı?
Cevap: Girmek için şart değil ama sınavdan başarılı çıkmak için faydalı olabilir :)

Soru: Sınava nasıl kayıt olunuyor?
Cevap: Yine Prometric web sitesinden istediğiniz sınav merkezini ve sınavı seçip kayıt olabilirsiniz. Site üzerinden sınav kayıt işlemini başlattığınızda sınav merkezinin hangi günlerde hangi saatlerde uygun olduğu da karışınıza gelecektir ve sınav saatini siz seçebileceksiniz.

Soru: Ne kadar zaman önceden kayıt olmak gerekir?
Cevap: Bir gün önce yeterli olacaktır.

Soru: Sınava giderken yanımızda neler alalım?
Cevap: ÖSS mantığı ile su ve çikolata alınabilir fakat gereksiz heyecana lüzum yok :) Yanınızda iki farklı kimlik (Ehliyet + Nüfus Cüzdanı) olması şart. Ayrıca sınav kaydınızda siteden aldığınız kayıt no ve öğrenci noyu da yanınızda bulundurmanızda fayda var.

Soru: Sınava geç kalsak? Ertelenebilir mi?
Cevap: Bir gün öncesinden Prometric sitesinden erteleme yapabilirsiniz. Gün için saat değişikliği konusunda doğrudan sınav merkezi ile görüşmeniz gerekecektir.

Soru: Kopya çeksek?
Cevap: Sınav merkezlerinde sınav odaları kamera ile izlenir :)

Soru: Kaç para bir sınav?
Cevap: 35GBP yani ortalama 80 YTL.

Başka sorularınız olursa yorum olarak beklerim ;)

Wednesday, September 10, 2008 2:04:31 PM (GTB Standard Time, UTC+02:00)  #    Comments [6]   WPF  | 
 Tuesday, September 09, 2008

Internet Explorer ile diğer web tarayıcıları arasında kod uyumsuzluk sorunları web programcıları olarak hepimiz biliyoruz. Hazırladığımız siteleri tek tek farklı tarayıcılarda test etmek zorunda olmak ve tarayıcıya özgü farklı kodlar yazmak belki de işimiz en sıkıcı noktalarından biriydi. İşte bu soruna artık bir nokta koymak adına Internet Explorer 8.0 ile beraber artık IE tüm standartlara uygun hareket ediyor. Tabi bu gelişme içerisinde bulunduğum durumunda bizim için "yeni sorunlar" anlamına geliyor. Eskiden IE 7 ve öncesi tarayıcılara özel olarak hazırladığımız kodlar artık IE 8.0 içerisinde aynı şekilde çalıştırılmayacak ve bir anda tüm sitelerin görsellikleri bozulacak.

Compatibility View

Internet Explorer 8.0 Beta 2 ile beraber aslında Beta 1'de de "Emulate IE7" düğmesi aracılığı ile ulaştığımız eski tarayıcı motoru hala geliyor. Bunun nedeni eski sitelerin eski tarayıcı motoru ile gösterilmesinin şart olması. Bir anda tüm sitelerin yeni motora uygun şekilde hazırlanması mümkün değil. Beta 2 ile beraber gelen yenilik bu sistemin "Compatibility View" adı altında farklı bir işlevsellik ile karşımıza çıkması. Artık IE8.0 eski sistem için hazırlanmış siteleri algılayıp kullanıcıyı uyarabiliyor ve farklı tarayıcı motorları arasında geçiş tarayıcının kapatılıp tekrar açılmasını gerektirmiyor.

"Compatibility View" düğmesi.
"Compatibility View" düğmesi.

"Compatibility View" düğmesine basarak eski standartlara göre açtığınız bir web sitesiyle ilgili ayarı IE 8 saklayarak bir dahaki sefere aynı siteyi ziyaret ettiğinizde otomatik olarak "Compatibiltiy View" seçeneği aktif hale getiriyor. Şu an için Beta 2 içerisinde internet üzerinden açılan tüm siteler normal modda çalışırken intranet üzerinden açılan tüm siteler ise otomatik olarak "Compatilibity View" modunda açılıyor. Burada önemli olan bir diğer nokta da User Agent bilgisi. Özellikle istatistik sistemleri için ASP.NET tarafından tarayıcının sürüm bilgisinin alındığı durumlarda unutmamak gerek ki IE 8.0 "Compatibility View" içerisindeyse sunucuya User Agent olarak IE 7 bilgisi gönderecektir.

Hangi sitelerin nasıl gösterileceğine ayrıca Tools menüsünden "Compatibility View Settings" kısmından ulaşabilirsiniz. Buradan ister tüm sitelerin IE 7 gibi gösterilmesini veya sadece adresini ilettiğiniz sitelerin IE 7 olarak açılmasını sağlayabilirsiniz.

Hangi sitelerinde "Compatibility View" modunda açılacağını belirleyebiliyorsunuz.
Hangi sitelerinde "Compatibility View" modunda açılacağını belirleyebiliyorsunuz.

Sitemizi nasıl ayarlarız?

Tavsiye edilen tabi ki tüm sitenizi gözden geçirerek IE 8'e uygun şekilde gerekli düzenlemeleri yapmanız. Fakat bu süreçte hızlı bir adaptasyon sağlamak için isterseniz sitenizin IE 8 içerisinde otomatik IE 7 motoru ile, yani "Compatibility View" içerisinde açılmasını da sağlayabilirsiniz. Bunun için iki seçeneğiniz var;

Eğer tüm site bazında bu işlemi yapmak istiyorsanız HTTP Header olarak aşağıdaki kodu kullanabilirsiniz;

X-UA-Compatible: IE=EmulateIE7

Sitenizdeki sadece bir sayfanın bu modda çalıştırılmasını istiyorsanız, bu sefer de Meta Tag'larından faydalanabilirsiniz;

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />

IIS 7.0 üzerinde bir site için genel HTTP Header tanımlamak için aşağıdaki kodu Web.Config dosyasına koymanız yeterli olacaktır.

<system.webServer>

    <httpProtocol>

        <customHeaders>

            <add name="X-UA-Compatible" value="IE=EmulateIE7" />

        </customHeaders>

    </httpProtocol>

</system.webServer>

Peki sitenizi ilk başta IE7 moduna göre çalışacak şekilde ayarladınız ve "Compatibility View" içerisinde gösterildi. Tüm istemcilerde artık siteniz bu modda gösterilecek şekilde kaydedildiği için IE8.0 ile ilgili uyumluluk sorunlarınızı halletseniz ve HTTP header bilgisi ile meta tagları kaldırsanız da herkes hala IE 7.0 modunda sitenizi ziyaret etmeye devam edecektir. Bunu aşmanın yolu ise tüm istemcileri IE 8.0 modunda çalışmaya zorlamaktan geçiyor.

X-UA-Compatible: IE=EmulateIE8

Yukarıdaki gördüğünüz şekilde ister HTTP Header ayarlayın ister meta taglar kullanır hiç fark etmez. Artık siteniz kesinlikle IE8.0 modunda gösterilecek ve istemcilerde kullanıcılar isteseler de "Compatibility View" modunu aktif hale getiremeyecekler. Eğer siteniz daha öncesinde istemcide "Compatibility View" ile gösterilecek siteler listesinde yer alıyorduysa IE 8.0 tarafından otomatik olarak o listeden de silinecektir.

Hepinize kolay gelsin.

Tuesday, September 09, 2008 2:00:07 PM (GTB Standard Time, UTC+02:00)  #    Comments [2]   IE 8.0  | 
 Monday, September 08, 2008

Son zamanlarda özellikle yurt dışından yola çıkan ve Adobe'ci arkadaşlarımızın :) güzelce saptırdıkları bir haber geziyor etrafta. Buyurun örneğin aşağıdaki yazıyı bir okuyun;

http://www.mmistanbul.com/haber/title/nbc-online-futbol-yayini-icin-silverlight-yerine-adobe-flash-platformunu-secti

Şimdi yazıdaki hatalara gelelim :) NFL (National Football League) hiçbir zaman yayınlarını Silverlight ile yapacağını duyurmadı. Bahsi geçen duyuruyu yapan NBC (National Broadcasting Compan)'dir ve sözü geçen duyuru Olimpiyatların yayını ile ilgiliydi. 2008 Olimpiyatlarının USA içerisindeki yayın hakkına sahip olan NBC Silverlight 2.0 kullanmaya karar verdi ve tüm olimpiyatların yayınları Silverlight 2.0 ile yapıldı. Yani ortada bir üründen vazgeçme gibi bir durum yok :)

Gelelim haberde bahsi geçen Sunday Night Football yayınlarına; bu yayınlar NFL ve NBC Sports tarafından ortaklaşa olarak yapılıyor ve yayınların yapılması için kullanılacak teknolojinin seçiminde yetkili taraf ise NFL. NFL'in kararı ise Flash'tan yana olmuş.

Tüm bu detayları bilmeden, ilgilenmeden "Silverlight yerine Flash'a geçildi" gibi abuk bir sonuç çıkarmaya çalışmak çok yanlış. Olimpiyatların yayını ile Sunday Night Football'un yayınını aynı yayınmış gibi kabul edip :) (eh işlerine öyle geliyor) "İşte değiştirdiler, vazgeçtiler" nidaları gerçekten komik. İlgilenenler Adobe'nin basın açıklamasını okusun bakalım Olimpiyatlardan bahsedilen bir cümle var mı :)

Aslında Flash'ın veya Flash severler ve sosyal toplulukların böyle fake girişimlere ve spot haberlere ihtiyaçları olduğunu düşünmüyordum. Flash'ın güçlü olduğu yanlar var ve sektörde tabi ki yeri var. Ama herhalde Silverlight artık iyice korkutmaya başladı ki haberlerde saptırmalar ortaya çıkıyor.

Bu arada yeni bir haber daha veriyim :) Silverlight'ın sonraki sürümlerinde H.264 MPEG 4 ve AAC desteği geleceği yapılan duyurular arasında. Flash'a kıyasla bu kadar yeni bir teknoloji olarak SL'in aldığı yol özellikle yol/zaman :) adına gerçekten muhteşem, işte bu yüzden Microsoft'u seviyorum.

Sağlıcakla kalın ;)

Monday, September 08, 2008 8:32:53 AM (GTB Standard Time, UTC+02:00)  #    Comments [7]   Silverlight 2.0  | 
 Sunday, September 07, 2008

Geçenlerde bir mail aldım. Maili yazan arkadaş bir yazılım şirketinde programcı olarak görev yaptığını fakat şirket içerisinde yükselemediğini söylüyordu. Yanlış anlaşılmasın, arkadaşımız yönetici olma amacında değil, sadece yazılım geliştirme projelerinde daha yetki sahibi olmak istiyor. Malum Junior/Senior developer kademelerinin arasında sıkışan bir sürü kademe de mevcut. İşte bu kademelerin daha iyi bir yazılımcı olunarak nasıl aşılabileceği soruluyordu mailde. İşte benim tavsiyelerim,

Heyecanlanın!

Yaptığınız işle ilgili heyecanlanın ve bu heyecanı etrafınıza yayın. Görevleri size verildiği için yapıyormuş gibi bir izlenim yaratmanız hiç işinize yaramaz. Tam tersine aldığınız görevi kutsayın! ve onu başarmanın heyecanını koruyun. Heyecan çok önemlidir! Ne kadar teknik bilgisi olursa olsun heyecanı olmayan ve yaptığı işi büyük bir heyecanla yapmayan bir yazılım geliştiricinin önüne geçmek hiç de zor değil. Eğer yaptığınız işten heyecanlanmıyorsanız hiçbir zaman "muhteşem programcı" olamazsınız.

Planlı olun!

Patronunuz "Yarın sabah 10'da şu müşteriye gideceğiz seninle" dediğinde kontrol etmeniz gereken bir takviminiz olsun. "Yarın sabah 09.30-12.00 arasında X projesindeki unit test kodlarını yazacaktım ama erteleyebilirim?" cevabını alan bir patron sizinle ilgili birçok da mesaj almış olacaktır. Ne zaman ne yapacağınız olabildiğince belli olsun. Neredeyse hepimizin bilgisayarında Outlook yüklü, Calendar kısmını kullanmaya başlayın! Toplantılarınızı "Meeting Request"ler atarak onay alıp ilerleyin. Outlook ile senkro olabilen bir cep telefonu alın! İster Outlook içerisinde ister harici programlarda son geçerlilik tarihleri olan "Yapılacaklar listeleri"niz olsun.

Günlük planlarınızı her sabah yazıcıdan çıkartın veya kağıt! ajandanıza elle yazın. Outlook'taki takviminizden ve yapılacaklar listenizden yazılı bir listeyi sabah başka bir ajandaya yazıp tek tek yaptıkça üzerlerini silmek motivasyon katabilir.

Kaliteli iletişim kurun.

İnsanlarla düzgün konuşun. Şaka yapmıyorum, seviyenizi her zaman korumaya çalışın. Özellikle yazılımcı erkeklerin kaynadığı ortamlarda bir süre sonra bel altı esprilerden geçilmez. O esprilere gülün ve kendinizi soyutlamayın ama o esprileri yapan kişi olmayın!

Yazdığınız maillere büyük önem verin ve yazdığınız kişiye göre farklı stillerle yazın. Bazıları maddeler şeklinde mail almayı sever, genelde mail okumaya çok zamanı olmayan kişilerdir bunlar. Bazıları ise uzun uzun hikaye yazar ve uzun mail yazılmasını da kendilerine verilen bir önem olarak görür. Karşınızdakinin kim olduğunu görün ve ona göre davranın. Hiçbir zaman hepsi büyük harflerle mail yazmayın, büyük-küçük harf detaylarına ve yazım/üslup hatalarına dikkat edin. Her mailiniz sonunda imzanız ve teşekkür mesajınız bulunsun.

Toplantılarda gereksiz konuşmayın ve not defteriniz olmadan herhangi bir toplantıya gitmeyin! Çok iyi not almalısınız ve tüm notlarınız üzerinden özlü bir şekilde konuşmalısınız.

Raporlayın!

Raporları birer angarya olarak görmeyin. Patronunuzun okuyacağı yoksa pile okumak isteyeceği raporlar yazmaya çalışın. "Bu hafta X projesinde 95 hata bildirimini giderdim" yazmak yerine detaylara girin. Hangi hataların nasıl çözüldüğünü, bir daha olmaması için şirket içinde neler yapılabileceğini detaylı bir şekilde yazın ama DESTAN yazmayın! Raporunuzu okuyan insanlar zaman kaybettiklerini düşünmemeli.

Patronunuz hiç sizden rapor istemedi mi? Yazın.

Düzgün giyinin.

Yazılımcıdan düzgün giyinmesini beklemek bir hatadır ama siz bu beklentiyi karşılayın. Bayanların zaten genelde bakım sorunu olmaz ama erkekler! Her gün tıraş olun! Kıyafetlerinize dikkat edin. Patronunuz müşteriye giderken yanında teknik birine ihtiyaç duyduğunda ofise bakacaktır, iyi giyim sizi bir adım öne çıkartır, şansınızı arttırır.

Mesai hesabı yapmayın!

İyi bir şirketteyseniz kimse mesai hesabı yapmayacaktır. Öğleden sonra gittiğiniz müşteri toplantısının uzaması veya eşinizin doktor randevusuna kimse itiraz etmeyecektir. Fakat! yumurta deliğe geldiğinde bir projeyi yetiştirmek için sabahlamanız gerektiğinde veya hafta sonu çalışmaya çağrıldığınızda SAKIN "hayır" demeyin. Sadece mesai saatlerine çalışarak yükselmeniz neredeyse mümkün değil. Yıllarca beklersiniz.

Saygı gösterin, öğrenci olun

Her zaman sizden iyi bilenler olacaktır. Sürekli öğrenci olun ve etrafınızdakilerden yeni şeyler öğrenmeye çalışın. Bir üstünüz olan yazılımcı arkadaşınıza düşman olmayın. Ona yaklaşın ve bilgisini emmeye çalışın. Unutmayın onlar birçok proje yaptılar ve ilginç şekillerde anlık muhteşem kararlar alabilirler. Ustalar çıraklarının başarısını ister, çırak olmayı bilmeniz yeterli.

Bilgiyi paylaşın

Özellikle şirketlerde yükselme yolunda "her şeyi sadece ben bilirsem yükselirim" gibi bir hisse kapılmak mümkün fakat durum kesinlikle böyle değil. Etrafınızdakilere öğretin ve bir gün "öğretecek şeyim kalmazsa" gibi bir korkuya kapılmayın. Şu an öğretecek şeyleriniz varsa yarın da olacaktır. Bilgiyi kendinize saklamanız hiçbir işe yaramaz. Bir projede "o detayları sadece O biliyor Onsuz yapamayız" denmesi sizi yüceltmez aksine insanların sizden korkmasına neden olur. Korkan insanlar sizi yükseltmez.

Yenilenin

Yenilikleri takip edin ve şirketinize aktarılması için büyük çaba harcayın. Bu çok zor bir savaştır ama kesinlikle uğraşılması gereken bir konu. Öğrendiğiniz yeni bir şey varsa patronunuza söyleyin bir toplantı ayarlasın ve herkese öğrendiğiniz yeni teknolojiyi anlatın, onlara da öğretin. Ancak onlar da öğrenirse yeni teknolojiyi projelerinizde kullanabilirsiniz, sadece siz bilirseniz kullanamazsınız. Söz konusu yeni teknolojiyi kullanma kararı alındığında ise şirketteki usta siz olacaksınız, bu durumu kendinizi sürekli yenileyerek koruyun.

Bunlar benim tavsiyelerim, unuttuklarım kesin vardır. Sizin de tavsiyeleriniz varsa yorum olarak bekliyorum ;)

Sunday, September 07, 2008 11:22:53 AM (GTB Standard Time, UTC+02:00)  #    Comments [14]    | 
 Saturday, September 06, 2008

Herkes girişsin de bu kodu kim yazacak?

Millet olarak her şeyi abartıyor muyuz anlayamıyorum. Aslında ben de kişisel olarak yaptığım her şeyi abartan ve uç noktalara gitmesini seven bir adamım ama ortada ayrı bir çarpıklık var. "Girişimcilik" üzerine seminerler yapıldı, yapılıyor. Daha geçenlerde INETA Summer Hit'de bile girişimcilik ile ilgili mekanist.net'ten Ali Servet Eyüpoğlu panelde konuğumuz oldu. Ali Servet'in hatırlatmak istediğim bir sözü var; "Ben teknik bir adam değilim" dedi, ki kendisi yanlış hatırlamıyorsam Mühendislik mezunu. Şimdi bu noktada bir hata yok, kaç kişi mezun olduğu dalda uzmanlaşıyor veya çalışabiliyor? ama Ali Servet ne olduğunun farkında!

Tüm bu girişimcilik senaryoları içerisinde bir anda bir "gazlamadır" gidiyor! "Pazarlamacılık" gazlamaları sonrasında sanırım yeni trend de "girişimcilik" gazlamaları olmaya başladı. Yeni "girişimciler" yaratmak için sermayenin nasıl bulunabileceğine kadar ilginç bilgiler internette dolaşıyor ve yavaş yavaş çok daha ilginç bir yazılımcı profili ortaya çıkıyor.

"Abi biz şimdi yazılım yapıyoruz, ama satacak adam yok. O zaman ilginç bir fikir bulup onu kodlayalım. Hem sermayedar da bulunuyor artık alırız 10.000$ ohhhh. Proje tutarsa ne ala, tutmazsa 10.000$'a iş yapmış oluruz işte"

Uzun uzun olayı anlatmaktansa yukarıda sözleri söyleyen suni bir yazılımcı kimliği yaratarak aslında gittiğimiz noktayı göstermeye çalıştım. Bu gidişat iyi midir? Kötü müdür? Çok tartışılır. Yurt dışından gelen bir miktar sermayeye bu çapta yaslanıyor olmak doğru mudur bilemem, konunun uzmanı değilim. Fakat nedense yukarıda bakış açışı benim canımı acıtıyor. Niyet iyi değil.

100.000$ lık siteyiz artık!

Papucumun yarısı :) bir site yapıyorlar sonra bunun %1'ini 1000'a birine satıyorlar :) Aslında adamlar 1000$ destek veriyor "Ya tutarsa" mantığı ile %1'i alıyor. Peki neden %1? Böylece genel anlamı ile site 100.000$ etmiş oluyor :) Peki geri kalanı 99.000$'a satın alan var mı? Yoooo :) Ekonomiden anlamam, yine diyorum uzmanlık alanım değil :) Ama ben bu hesabın algoritmasını çıkartıp kodlayamıyorum, demek ki bir gariplik var. Bu arada ilgilenen deli varsa benim blogun da 1000'e 1'i satılıktır :) milyon dolarlık blog olsun, ne işimize yarayacaksa...

Sinirleniyorum... Geriliyorum...

Geçenlerde bir etkinlikte reklam ile karışık bir oturum yapıldı. Oturumun başında X yazılım firması kendilerini tanıtırken A, B, C ve D adında kurumlara iş yaptıklarından bahsetti. Bu kurumlar kabaca evinizde etrafınıza baktığınızda aklınıza gelebilecek markalar. Yani hepsi de çok büyük firmalar. Oturumu sunan arkadaşın böyle bir kurumda çalışabileceğini öngörmesem de "Eh güzel" diyerek "Demek ki iyi işler yapıyorlar, bu firmalarla çalıştıklarına göre" dedim.

Sonrasında sunumun rezaletinden hiç bahsetmeyeceğim. Hatta sunuma uyuz olan birileri sonradan sunumda tanıtılan siteyi hacklemiş sanırım :) nette dedikoduları geziyordu. Her neyse, biz konumuza dönelim.

Sunumun sonunda birileri "Neden böyle bir proje yaptınız" gibi bir soru sordu. Gelen cevap şuydu;

"Biz bir yazılım şirketiyiz fakat sektörde yazılım şirketlerine kötü gözle bakılıyor. O nedenle kendi projemizi geliştirip kendimiz ilerlemek istedik"

Şimdi ilk önce bir hatırlatiyim, bu sözü söyleyen arkadaş A, B, C ve D büyük markalarına iş yapan bir kurumdandı :) Peki ne oldu? Yukarıdaki cümlenin Türkçesi aşağıdaki gibi:

"Biz A, B, C ve D gibi kurumlarla iş yaptığımızı söylüyoruz ama düzgün iş yapamadık ve adamlar bize kötü gözle bakmaya başladı. Baktık iş yapamıyoruz ama bir şeyler de biliyoruz. Eh dedik o zaman kendi projemizi yapalım da bari böyle para kazanırız."

Yazık! Yanlış anlaşılmasın yazık olan X kurumu değil. Onlar kendilerine bir başarısızlık sonrası farklı bir yol çizmişler. Yolları açık olsun. Ama sen bir etkinlikte onlarca kişinin izlediği bir oturumda çıkıp da "Yazılım firmalarına kötü gözle bakılıyor Türkiye'de" gibi bir genelleme yapma! Bu kiloyla gelir otururum üzerine adamın! :D

Şaka bir yana, uzun zamandır böyle sinirlendiğimi hatırlamıyorum. Allahtan oturumun sonunda Soru-Cevap falan yapmadılar yoksa suyu sabunu almış elemanı yıkamaya hazırdım.

Baba gel beraber yapalım!

"Girişimcilik" aslında ciddi anlamda teknik yazılımcının düşmanı olduğu kadar "Girişimciler" de bazen düşman olabiliyor. Teknik anlamda bir şeyler yapabilen bir yazılımcı ile sermayesi olmayan fake girişimcinin diyalogu her zaman "Baba şöyle bir şey yapsak beraber valla 6 ay sonra para makinası satın almamız gerekir" muhabbeti ile başlar ve genelde bu adamlar çok tatlı ve iyi konuşurlar (dikkat!). Aslında girişimcinin emek harcayacağı pek bir şey yoktur :) o girişecek ve belki sonrasında işin ticari işleyiş yükünü kaldıracak fakat projenin tüm riskini aslında ilk aşamada diğer yazılımcı arkadaş alacaktır. İşte tam da bu noktada yazılımcı kendi kendine sorar: "Yahu ben de girişirim?" işte yazılımcının öldüğü an :)

Şimdi eğer bu yazılımcı girişirse artık bir yazılımcı değil girişimcidir :) eğer girişmez ve ona rağmen yukarıdaki teklifi kabul eder ise bu sefer de enayidir! Peki ne yapmak gerekir? Cevap basit.

Varsayılan Girişimci : "Baba gel ... bıdı bıdı.... yapalım, süper para kırarız!"
Yazılımcı: "Tabi öyle bir proje üç ay sürer ortalama maliyeti 30.000$ olur nasıl sağlarız bu akışı?"
Fos Girişimci: "Hmmmm.... Ya beraber kazanıcaz işte bir başlayalım"

Aman derim! Böyle tiplere dikkat. Eğer bir girişim söz konusu ise ve ortada bir teknik (yazılımcı) adam ve bir tüccar! varsa bu kişiler saat başı çalışma miktarlarını başta ölçüp ona göre masraf geçmek gerekir. Örneğin Armut Portalı yapacaksınız! Süper bir fikir! Fikri girişimci kanki buldu ve size geldi. Girişimci kanki ile beraber girişin fakat onun haftada çalışacağı saat miktarı ile sizinkini ölçün ve ona göre bunu "Girişiminiz"e masraf geçin. Maddi olarak geri almanız şart değil bir yatırım yapıyorsanız bile kimin ne kadar yatırım yaptığı belli olsun. %50 ortak olsanız bile aylarca diğer girişimci kankiden daha çok çalıştığınız saatleri masraf olarak kaydettiğiniz için ileride gelen gelirden alabilirsiniz. Bunlar ince detaylar gibi görünse de özellikle girişim başarısızlığa sürüklendiğinde veya zor günler uzadığında başarısızlığı körükleyen detaylar olurlar.

Tabi "kurunun yanında yaş da yanar" ama biz yakmayalım. Her girişimci yazılımcının düşmanıdır demek de doğru olmaz aslında gerçek anlamıyla bir girişimci yazılımcının besin kaynağı da olabilir. Çünkü birilerinin girişmesi lazım ve bu kesinlikle yazılımcının kendisi olmayacaksa başka birine ihtiyaç duyulduğu açıkça ortada.

Konu biraz saptı fakat bir yazılımcı olarak girişirken dikkat etmeniz gerekenlere az çok değinmek istedim. Yine dertlerimi (taşlarımı) döktüm. Son olarak tekrar etmek istediğim birkaç şey var; eğer işiniz programcılık ise programcılık yapın, yazılımsa uzmanlık alanınız yazılım üretin. Ürettiğiniz yazılımın ticari anlamda işletmeciliğine soyunmayın! O zaman artık bir yazılımcı olmaktan çıkarsınız! Tabi bu da bir seçimdir. Fakat "bol para" kandırmacası altında olayın işletme tarafına kaydığınızda asıl işiniz olan programcılıktan uzaklaşacağını bilin ve son olarak; eğer programcılıkla "bol para" kazanamıyorsanız işinizi yeterince iyi yapmıyorsunuz demektir!

Hepinize kolay gelsin ;)

Saturday, September 06, 2008 12:21:37 PM (GTB Standard Time, UTC+02:00)  #    Comments [11]   Dertli Kerem  | 
 Friday, September 05, 2008

PC Magazine LogoPC Magazine Eylül sayısından başlayarak artık PC Magazine'de Yazılım Editörlüğü görevini de yapıyor olacağım. Silverlight 2.0 yazılarım devam ediyor ve daha birçok projem var.

Eylül sayısında SL 2.0'ın TCP/IP soket programlama kısmına değindim. Ayrıca dergide ileride bloglardan duyuracağımız bir aktivitenin ipuçlarını da verdik :) Sürpriz! :)

Friday, September 05, 2008 1:22:15 PM (GTB Standard Time, UTC+02:00)  #    Comments [3]   Silverlight 2.0  | 
 Thursday, September 04, 2008

Özellikle Doğu ve Güneydoğu Anadolu'dan çok fazla seminerlerle ilgili mail geliyor. Haklı olarak İstanbul'da çok fazla aktivite olduğundan fakat ulaşım ve konaklama sorunları nedeniyle İstanbul'a gelişin zorluğundan yakınanları çok iyi anlıyorum. Her zaman söylediğim gibi bugüne kadar davet edildiğim herhangi bir seminer talebine katılmamazlık etmedim fakat geçenlerde düşünürken aklıma çok daha güzel bir fikir geldi.

Son üç gündür sizlerle farklı konulardaki seminerlerimin kayıtlarını paylaştım. Bundan sonra kişisel olarak da düzgün bir kamera sahibi olmamın sonucunda :) elimden geldiğince tüm seminerlerimi kaydederek internetten yayınlayacağım. Bu çerçevede blogumdaki Seminer TV bölümünü duyuruyorum :)

Nedir Seminer TV?

Blogumdaki Seminer TV bölümünün aslında Soru Merkezi gibi kendine özel bir amacı var. Hedefim her konuda verdiğim seminerleri bu bölüme yerleştirmek. Fakat gereksiz bir yığılmaya da neden olmamak için aynı konuda birden çok seminer yerleştirmeyeceğim. Örneğin şu anda IE 8.0 Beta 1 anlattığım bir seminer Seminer TV'de bulunuyor. IE 8.0 Beta 2 anlattığımda veya ürün yayınlandıktan sonra bir seminer verdiğimde onun kaydını Seminer TV'yi koyduğum anda Beta 2 kaydını kaldıracağım.

Uzun vadeli hedefim olan "İleri Seviye" seminerler düzenleyebilmem için Seminer TV'nin katkısı da büyük olacaktır. En son INETA Summer Hit'de bile salonun yarısından fazlası benim daha önceki Silverlight 1.0 seminerimi internetten izlemişti. Böylece çok daha rahat ve hızlı ilerleyebildik. Tabi bunda aktivite öncesi yolladığım maillerdeki notların sanırım büyük katkısı var.

Sonuçta...

Seminer TV bölümüne sürekli girip çıkıp kontrol etmek zorunda kalmayacaksınız. Yeni bir video eklediğimde veya bir videoyu yenilediğimde blogumda duyuracağım. Amacım blogpostlar arasında bu seminer kayıtlarının kaybolmaması ve sürekli en güncel seminerin rahatlıkla ulaşılabilir olması. Tabi bu durum "Yahu ne gerek var gitmeye ne de olsa bloguna koyacak" psikolojisi yaratmasın :) Kimse gelmezse kayıt da olmaz ona göre :P ;)

Hepiniz kalın sağlıcakla....

Thursday, September 04, 2008 4:06:02 PM (GTB Standard Time, UTC+02:00)  #    Comments [18]    | 
 Wednesday, September 03, 2008

INETA Summer Hit'deki bir diğer seminerim olan IE 8.0 Beta 1 konulu video kaydını da aşağıda sizlerle paylaşıyorum. Bugünlerde epey izleyecek malzeme çıktı sanırım seminerlere gelemeyenler için.

Wednesday, September 03, 2008 3:40:00 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   IE 8.0  | 
 Tuesday, September 02, 2008

INETA Summer Hit'deki Silverlight 2.0 seminerime ait video kaydını aşağıdan izleyebilirsiniz. Daha önceki Silverlight 1.0 seminer kaydının epey izlendiğini bana gelen maillerden biliyorum. Seminer kayıtları ile ilgili sinsi projemin bitmesine az kaldı :)

Tuesday, September 02, 2008 3:38:19 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   Silverlight 2.0  | 
 Monday, September 01, 2008

Yavaş yavaş seminerlerimin kayıtları yayınlama konusunda sinsi hareketlere girişiyorum :) İşte size daha önce bahsetmiş olduğum "Microsoft Gelişim Atölyesi"ndeki WPF eğitimimim kaydı.

Monday, September 01, 2008 3:32:28 PM (GTB Standard Time, UTC+02:00)  #    Comments [0]   WPF  | 

INETA Summer Hit'te gerçekleştirdiğimiz Panel'in videolarını sizlerle paylaşacağımıza söz vermiştim ve sözümü tutuyorum :)

Her defasında izlemeye başladığımda bıkmadan tekrar izleyebiliyorum, bu durum bana özel mi yoksa gerçekten zevkli bir sohbet mi oldu bilemiyorum :)

Not:Kayıtta bazı kısımların eksik olması kesinlikle :) sansür yapıldığı anlamına gelmiyor panelin son yarım saatine kala kameranın hafızası dolmuş ve kayıt durmuş :( oysa en eğlenceli kısmıydı. Bir dahakine artık...

Monday, September 01, 2008 12:06:20 PM (GTB Standard Time, UTC+02:00)  #    Comments [6]    | 
Copyright © 2010 Daron Yöndem. Tüm hakları saklıdır.