Makale Özeti

Bu makalemde ise geliştirdiğimiz mobil uygulamaların dağıtım, kurulum ve güncellemeleri için Click Once teknolojisine benzer yapıda bir örnek uygulama yapacağız. Bu örnek uygulamamızın amacı yazmış olduğumuz bir mobil uygulamanın en son versiyonunun mobil cihazda mevcut olup olmadığının kontrolünü yapmak, eğer yeni bir versiyonu bulunuyorsa kurulum dosyasının mobil cihaza indirilmesi ve kurulumu işlemlerinin yapılmasını sağlamak olacak.

Makale

ClickOnce, geliştirilen Windows uygulamalarının dağıtım ve güncellemelerinin daha kolay yapılabilmesine olanak sağlayan Visual Studio 2005 ile gelen teknolojidir. Click Once ile ilgili daha detaylı bilgiye önceden yazmış olduğum makale serisinden ulaşabilirsiniz. Bu makalemde ise geliştirdiğimiz mobil uygulamaların dağıtım, kurulum ve güncellemeleri için Click Once teknolojisine benzer yapıda bir örnek uygulama yapacağız. Bu örnek uygulamamızın amacı yazmış olduğumuz bir mobil uygulamanın en son versiyonunun mobil cihazda mevcut olup olmadığının kontrolünü yapmak, eğer yeni bir versiyonu bulunuyorsa kurulum dosyasının mobil cihaza indirilmesi ve kurulumu işlemlerinin yapılmasını sağlamak olacak. Böylelikle makalenin sonunda, Windows uygulamaları için kullanabildiğimiz Click Once teknolojisine benzer yapıda bir örnekte, bütün özellikleriyle olmasa bile mobil uygulamalar için de nasıl oluşturabileceğimize dair bilgi sahibi olacağız.
İlk olarak uygulamayı geliştirirken izleyeceğimiz adımları özetle geçmek faydalı olacaktır:
* Versiyon bilgisi kontrol edilecek örnek bir mobil uygulama oluşturmak
* Örnek uygulamanın kurulum dosyasını oluşturmak
* Uygulamanın yayınlanmış olan tüm versiyon bilgilerinin tutulduğu bir veritabanı oluşturmak
* Oluşturulmuş olan veritabanından en son versiyon bilgisini çekecek web servisi yazmak
* Web servisten aldığı versiyon bilgisine göre yeni bir versiyon bulunmuşsa uygulamanın yeni versiyonunun kurulum dosyasının indirilip kurulması veya yeni versiyon bulunmaması durumunda uygulamanın mevcut halinin çalıştırılması işlemlerini yapacak uygulamayı yazmak
İlk olarak yeni bir solution oluşturalım ve mobil cihazımıza kuracağımız ve versiyon kontrolünü yapacağımız basit bir örnek uygulama için yeni bir proje ekleyelim:



Uygulamada bir buton olsun ve tıklandığında Hello World
messagebox'da çıksın.



private void btnHello_Click(object sender, EventArgs e)
{
    MessageBox
.Show("Hello World");
}
privatevoid
frmHelloWorld_Closed(object sender, EventArgs e)
{
    Application
.Exit();
}

Şimdi örnek uygulama için kurulum dosyalarını oluşturacak olan bir setup projesini solution'a ekleyelim:



Ardından setup projesine sağ tıklayarak açılan menüden Add -> Project Output'a tıklayarak MySampleApplication uygulamasının setup dosyasının oluşturulması için açılan ekranda PrimaryOutput'u seçelim:



Artık örnek bir uygulamamız ve uygulamamızın mobil cihaza kurulumunu yapabilmemiz için bize gerekli setup dosyasını verecek olan setup projemizi oluşturmuş bulunmaktayız. Çok basit olan bu adımları geçtikten sonra sıra uygulamanın versiyon bilgilerinin tutulacağı veritabanının tasarlanmasına geldi.

Veritabanının adını MobileClickOnceDB, tablonun adını da ApplicationVersions olarak belirleyelim. Veritabanında versiyon bilgilerinin tutulacağı tabloda VersionId, VersionNumber, VersionDate ve VersionPath alanları olsun. VersionNumber uygulamanın versiyon numarasının, VersionDate ise ilgili versiyonun yayınlanma tarihi bilgisinin tutulacağı alanlar olacaktır. VersionPath alanında ise uygulamanın cab dosyasının indirileceği adres bilgisini saklayacağız. Tablonun dizaynı tamamlandığında aşağıdaki gibi olacaktır:



Şimdi veritabanında kullanacağımız tek stored procedure'i yazalım. SP, ApplicationVersions tablosundanVersionDate ve VersionNumber alanlarına göre en güncel olan versiyon bilgilerini getirecek:
CREATE PROC [dbo].[SelectLatestApplicationVersion]
AS
SELECT TOP 1 * FROM ApplicationVersions ORDER BY VersionDate DESC, VersionNumber DESC


Şimdi sırada uygulamanın en son versiyon bilgisini çekecek olan web servisi yazmaya geldi. Solution'a ApplicationVersionUpdateCheckerWebService adında yeni bir web servis uygulaması ekleyelim. Ardından da ApplicationVersionUpdateChecker adında bir web servis ekleyelim. Web servis'e ApplicationVersion adında yeni bir class ekleyelim ve biraz önce yazdığımız SelectLatestApplicationVersion SP'sini çağıralım:
 
public ApplicationVersion SelectLatestApplicationVersion()
{
    DataTable
insDataTable = new DataTable();
    ApplicationVersion
av = new ApplicationVersion();
    SqlConnection
con = new SqlConnection(ConnectionString);
    SqlCommand
com = new SqlCommand("SelectLatestApplicationVersion", con);
    com.CommandType = CommandType.StoredProcedure;
    SqlDataAdapter
da = new SqlDataAdapter(com);
    da.Fill(insDataTable);
   
    av._VersionDate = Convert.ToDateTime(insDataTable.Rows[0]["VersionDate"]);
    av._VersionId = Convert.ToInt32(insDataTable.Rows[0]["VersionId"]);
    av._VersionNumber = insDataTable.Rows[0]["VersionNumber"].ToString();
    av._VersionPath = insDataTable.Rows[0]["VersionPath"].ToString();

     return av;
}


Şimdi sıra web servisten bu fonksiyonu çağırmaya geldi. asmx dosyasına da aşağıdaki kodu yazarak web servisi oluşturma işlemini tamamlayalım:
[WebMethod]
public
ApplicationVersion SelectLatestApplicationVersion()
{
    ApplicationVersion
av = new ApplicationVersion();
    return
av.SelectLatestApplicationVersion();
}

Son adımda uygulamanın versiyon bilgisini kontrol edecek olan uygulamayı yazacağız. Kısaca özetlemek gerekirse bu uygulama, MySampleApplication adındaki asıl uygulamamız yerine kullanıcı tarafından çalıştırılacak, server'a bağlanıp versiyon bilgisini alacak ve yeni versiyon olup/olmaması durumuna göre gerekli işlemleri yürütecek. İlk olarak solution'a yeni bir uygulama ekleyelim ve formu aşağıdaki gibi tasarlayalım:



Formda eğer uygulamanın yeni bir versiyonu mevcutsa kullanıcının tıklayacağı Güncellemeyi Yap ve Güncellemeyi Yapma butonları bulunuyor. En altta da dosya indirilmesi işlemleri sırasında gelinen aşamayı göstermesi açısından bir progressbar var.
İlk olarak biraz önce yazdığımız web servisi referans ekleyelim. Class level bir ApplicationVersion nesnesi tanımlayalım (ac) ve ardından da formun load'ına aşağıdaki kodu yazalım:
private void frmUpdater_Load(object sender, EventArgs e)
{
   
ApplicationVersionUpdateChecker.ApplicationVersionUpdateChecker uc = new MyUpdateChecker.ApplicationVersionUpdateChecker.ApplicationVersionUpdateChecker();
   
ac = new ApplicationVersion();
    string
version = "";
    if
(Registry.LocalMachine.GetValue("MyAppVersionNumber") != null)
    {
        version = Registry.LocalMachine.GetValue("MyAppVersionNumber").ToString();
    }
    ac = uc.SelectLatestApplicationVersion();
    if
(ac.VersionNumber != version)
    {
        MessageBox
.Show("Yeni versiyon bulundu.");
    }
   
else
   
{
        if
(File.Exists(
@"\Program Files\MySampleApplicationSetup\MySampleApplication.exe"))
        {
            Process
.Start(
@"\Program Files\MySampleApplicationSetup\MySampleApplication.exe", "");
            Application
.Exit();
        }
       
else
       
{
            MessageBox
.Show("Uygulama kurulu değil. Uygulamayı kurunuz.");
            return
;
        }
    }
}

Kullanıcı update butonuna bastığında Registry'de MyAppVersionNumber adında uygulamanın kurulu versiyon bilgisini tutacağız. Formun load'ında da bu değer eğer mobil cihazda mevcutsa string tipinde tanımladığımız version değişkenine o değeri atıyoruz. Ardından da uygulamanın en son versiyon bilgisini web servisiyle alıyoruz ve tanımlamış olduğumuz ApplicationVersion (ac) nesnesine atıyoruz. ApplicationVersion nesnesinin VersionNumber property'sinde taşınan değer version değişkeni ile aynı değilse kullanıcı yeni versiyon bulunduğuna dair bilgilendiriliyor. Eğer yeni versiyon yoksa da uygulamayı çalıştırıp, updater uygulamasını sonlandırıyoruz.

Uygulamanın yeni bir versiyonu bulunuyorsa ve kullanıcı Güncelle butonuna basmışsa çalışacak kodu yazalım:
private HttpWebRequest insRequest;
private
HttpWebResponse insResponse = null;

private
void btnUpdate_Click(object sender, EventArgs e)
{
    Cursor
.Current = Cursors.WaitCursor;
    insRequest = (HttpWebRequest)HttpWebRequest.Create(ac.VersionPath);
    insRequest.Timeout = 10000;
    insRequest.AllowWriteStreamBuffering = false;
    insResponse = (HttpWebResponse)insRequest.GetResponse();
    int
totalCount = (int)insResponse.ContentLength;
    Stream
insStream = insResponse.GetResponseStream();
    FileStream
insFileStream = new FileStream(GetCurrentDirectory() + @"\setup.cab", FileMode.Create);
    byte
[] buffer = new byte[256];
    int
count = insStream.Read(buffer, 0, buffer.Length);
    pBar.Maximum = totalCount;
    totalCount = 0;
    while
(count > 0)
    {
        if
(totalCount - count < 0)
        {
            pBar.Value = 0;
        }
       
else
       
{
            pBar.Value = totalCount - count;
        }
        Application
.DoEvents();
        insFileStream.Write(buffer, 0, count);
        count = insStream.Read(buffer, 0, buffer.Length);
        totalCount += count;
    }
    insFileStream.Close();
    insStream.Close();
    insResponse.Close();
    if
(ac.VersionNumber == "" || ac.VersionNumber == null)
    {
        ac.VersionNumber = "1.0.0.0";
    }
    Registry
.LocalMachine.SetValue("MyAppVersionNumber", ac.VersionNumber);
    Cursor
.Current = Cursors.Default;
    string
cabname = GetCurrentDirectory() + @"\setup.cab";
    Process
p = Process.Start(cabname, "");
    int
processId = p.Id;
    while
(!Process.GetProcessById(processId).HasExited)
    {
        Thread
.Sleep(1000);
    }
    Process
.Start(@"\Program Files\MySampleApplicationSetup\MySampleApplication.exe", "");
    Close();
}
private
string GetCurrentDirectory()
{
    return
Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetModules()[0].FullyQualifiedName);
}

Update butonunun click event'inde ilk olarak uygulamanın son versiyonu ApplicationVersion nesnesinin VersionPath property'sinde tutulan adresten HttpWebRequest ve HttpWebResponse kullanılarak cihaza indiriliyor. Bu arada da form üstündeki progressbar da indirilen dosya boyutuna göre ilerliyor. Dosya indirildikten sonra Registry'e uygulamanın son versiyon numarası
MyAppVersionNumber olarak yazılıyor. Ardından indirilmiş olan cab dosyası çalıştırılıyor, cihaza kurulum yapıldıktan sonra da uygulama çalıştırılıp, updater uygulaması kapatılıyor.

Son olarak kullanıcı uygulamayı güncelleme butonuna bastığında çalışacak olan kodu yazalım:

private void btnDoNotUpdate_Click(object sender, EventArgs e)
{
    if
(File.Exists(@"\Program Files\MySampleApplicationSetup\MySampleApplication.exe"))
    {
        Process
.Start(@"\Program Files\MySampleApplicationSetup\MySampleApplication.exe", "");
        Application
.Exit();
    }
   
else
   
{
        MessageBox
.Show("Uygulama kurulu değil. Uygulamayı kurunuz.");
        return
;
    }
}

Kodda da görüldüğü gibi uygulama cihazda mevcutsa direkt olarak çalıştırılıyor ve updater uygulaması kapatılıyor.

Güncelleme iptal butonunun kodunu yazdıktan sonra uygulamanın kodlama kısmı da tamamlanmış oldu. Veritabanındaki ApplicationVersions tablosuna uygulamamızın versiyon bilgisiyle ilgili aşağıdaki gibi bir kayıt ekleyelim:



Updater uygulamasını başlattığımızda bize yeni versiyon bulundu messagebox'ı gösterilecek:



OK'e bastığımızda uygulama ekranı açılacaktır:



Güncellemeyi Yap butonuna bastığımızda uygulama kurulacaktır:



OK'e bastığımızda ise updater uygulaması kapanacak, indirip kurmuş olduğumuz uygulama çalışacaktır:




Bu makalemde mobil uygulamalar için ClickOnce teknolojisinin mantığına benzer yapıda bir uygulamayı nasıl yazabileceğimizi anlattım. Böyle bir uygulamaya yazdığınız mobil uygulamalarda ihtiyaç duyduğunuzda validasyon ve hata yakalama işlemlerinin de koda dahil edilerek kullanabilirsiniz.

Umarım faydalı olmuştur.

Işıl Orhanel

http://www.isilorhanel.net




 

 



 

Örnek kodu buradan indirebilirsiniz.