Showing posts with label WPF. Show all posts
Showing posts with label WPF. Show all posts

Friday, January 16, 2015

Get ATR using pcsc-sharp

This time I'm gonna show you how to get an ATR from a smartcard using pcsc-sharp wrapper step by step. First you have to download the pcsc-shrap project, you can download that from this site. After downloading that project, extract it into your pc hardisk. Then let's start by making a new project in visual studio 2010 :

Then add one button, textbloct and viewbox from toolbox menu to mainwindow.xml then arrange those items according to picture below :


If you are confuse with that, you can directly edit the xml file like this :

Well, you can see that the main window is so simple, so you can make your own window as you like. Next let's add the pcsc-sharp project into this project. Just right click on the solution project, choose "add", then "Existing Project..."  :
After clicking "Existing Project.." then browse the "pcsc-sharp.csproj" :


If everything is right, then you should see a new project in your visual studio.
In order to use all of the available function in pcsc-sharp, we need to reference to it first. So right click in getATRv0 project, choose "add reference.." :

After clicking "Add Reference...", choose project tab, then choose pcsc-sharp, last hit "ok" button :

Until this state, now we can use the available method, class, or namespace from pcsc-sharp project. To prove that, let's go back to our mainwindow.xaml.cs and put these line codes :

As you can see at line 14, we are using PCSC namespace that we reference from pcsc-sharp project and at line 23 to 26, we are using the classes from PCSC namespace, so this is a proof that now we can use the pcsc-sharp project in our current visual studio project. Well, umm... I think it's good if we run our getATR project, just to make sure that everything is ok hehhee.... :D

Ok,.Let's add another variables into our project :

the szReaders will gonna be saving the reader name for our smartcard and atr will be being used to save the byte of smartcard ATR. Ok let's add some methods, the first is :
getAvailableReader will be used to make a context from our reader that already connected to our PC. That method is also used to list all of the available reader then put the readers name to szReader variabel.

The next method is :
As you can see from the method's name, connecReader will be used to connect our application to smartcard reader.

The last method is getATR() as we can see in below :

getATR is the main method that will accomplish our goal in this posting. This method will be used to get the ATR bytes. As a note, this method has to be preceded by getAvailableReader and connectReader methos. Btw, if getATR method failed to be executed or an error occured during getATR method execution, then atrbuff will be filled up with 0x6E and 0x00.

Next, let's add a handle code to our button. Just double click the button in your xml file, then add these line codes into it :
As we can see, when the button is pressed by user, the getAvailableReader's method is called first then connectReader. After that we call our getAtr which put the ATR bytes into atr variable, then we display those atr bytes into our textbox with helped by BitConverter that change atr bytes into a hex string.

The result from this project is shown below :

Thanks,.. I hope this posting is usefull to someone who has been facing the same problem with me when trying to find a way to get the ATR from smartcard using pcsc-sharp :-)

Wednesday, January 7, 2015

Background Worker Part II - C# WPF

Pada kesempatan kali ini akan dipelajari kembali tentang bagaimana menggunakan background worker di C# menggunakan visual studio 2010. Postingan ini adalah postingan yang kedua tentang background worker. Untuk postingan yang pertama bisa dilihat disini. Postingan tidak terlalu berhubungan dengan postingan pertama tadi, soalnya disini kita akan mulai membuat project baru lagi. Namun ada baiknya jika postingan pertama untuk dicoba dulu sebelum melangkah untuk mempelajari background worker yang akan diperlihatkan pada bagian ini.

Secara ringkas, background worker yang akan diperlihatkan pada postingan ini adalah bagaimana menghentikan thread background worker yang sedang berjalan dan memulai kembali thread yang baru dalam satu tombol saja. Jika kita searching di om gugel kn umumnya pake dua tombol untuk start dan satunya lagi untuk stop, jadi untuk tiap event-eventya jadi mudah. Tapi klu cuma pke 1 tombol ceritanya agk beda dikit. Ok... Langsung saja kita buat project baru di visual studio :


Kemudian tambahkan 1 buah button, 1 textbox, 1 listbox, 1 progress bar, 1 label (tempatkan label di atas progress bar). Kemudian atur posisinya :


Kemudian nama dari masing-masing komponen saya ubah seperti terlihat di bawah :

Next, mari kita tambahkan handler buat tombol start. Untuk itu silahkan double klik tombolnya untuk melangkah ke file c#-nya. Emm... Sebelumnya tambahkan dulu variabel backgroudworker baru :
Di line number 23, dibuat variabel baru dengan nama worker. worker inilah yang akan kita gunakan untuk melakukan background process nantinya. Kemudian didalam fungsi startButton_Click(), tambahkan kode berikut {selalu perhatikan line number untuk setiap kode}:
Ketika button start di klik oleh user, maka pada line 34, variabel worker dicek, apakah sedang berjalan (kondisi busy) atau tidak. Nah jika worker tersebut mempunyai thread (sedang running), maka pada line 36, worker tersebut segera dihentikan dengan command "CancelAsync". Dengan dieksekusinya CancelAsync maka pada thread worker yang sedang running dapat mendeteksi jika thread ini harus dihentikan. Caranya diperlihatkan kemudian. Intinya worker.CancelAsync tersebut memberikan sinyal yang menunjukkan adanya perintah untuk menghentikan thread background worker yang sedang running. Kemudian pada line 39, kita membuat variabel baru dengan nama max tipe integer. Variabel max ini berguna untuk menyimpan angka yang dinput oleh user pada textbox (name="number") mainwindow. Angka dari textbox tersebut diambil dengan menggunakan fungsi Convert.ToInt32(). Fungsi convert tersebut ditambahkan eksepsi untuk menghandle user yang memasukkan selain angka pada textboxt. Eksepsinya seperti terlihat di atas yang terdiri dari format exception dan overflowexception. Format exception terjadi apabila user memasukkan huruf-huruf alphabet ke dalam textbox dan overflow exception terjadi apabila user memasukkan angka yang terlalu besar yang ukurannya tidak bisa ditampung pada variabel tipe integer di C#. Kemudian pada line 52, "Debug.Writeline(max)", kode ini hanya memperlihatkan nilai max ke dalam konsole output di visual studio. Terus pada line 54, "field.Items.Clear();", kode ini berguna untuk menghapus angka-angka pada listbox. Jadi setiap tombol startButton diklik, listboxnya akan dibersihkan hehe... :D. Nah kemudian pada line 56, worker kembali di cek, jika worker sedang tidak running, worker tersebut akan dirunning kembali dengan thread backgroundworker yang baru. Kode ini berguna ketika tombol start pertama kali diklik atau diklik setelah thread backgroundworker sudah selesai dijalankan, kondisi seperti itu kan tidak ada thread, jadi kode diline 58 dapat dieksekusi.

Next, ditambahkan 3 buah fungsi pendukung untuk background worker seperti terlihat di bawah :
Penjelasan untuk ketiga fungsi diatas mungkin hampir sama pada postingan sebelumnya tentang background worker dan proggress bar. Tapi tidak mengapa diulang lagi disini :-D. Jadi fungsi threadProcess adalah fungsi yang pertama kali di jalankan ketika thread backgroundworker pertama kali running. Fungsi ini menjalankan aktivitas utama dalam thread dan menjadi sumber event/sinyal untuk menjalankan fungsi yang lainya seperti updateGUI. Method threadProcess ini jugalah yang digunakan untuk mendeteksi adanya perintah untuk menghentikan thread backgroundworker. Pada line 67 pada fungsi threadProcess ini, dibuat variabel bernama args untuk menyimpan angka dari user (yang diambil dari variabel max pada fungsi startButton_Click). Angka tersebut dibawa oleh variabel input e seperti terlihat pada fungsi di atas. Sebagai catatan variabel input e tersebut tidak hanya dapat membawa tipe integer saja, tapi tipe-tipe yang lain juga seperti string, char, double, dsb. Terus untuk line 68, disitu dibuat variabel mBilGanjil yang nantinya digunakan untuk menyimpan jumlah bilangan ganjil dari 0 sampai args.

Line 70 dibuat loop dari 0 sampai args. Loop ini adalah aktivitas utama yang dilakukan thread backgroundworker yang kita buat. Di dalam loop ini pertama kali dihitung presentasi yang akan ditampilkan pada progress bar dan label untuk presentasi progress bar. Yang perlu diperhatikan nilai i/args dikonvert ke double terlebih dahulu sebelum dikalikan 100. Hal ini untuk mencegah pembulatan yang akan menimbulkan progress bar menjadi tidak smooth.

Line 74, nilai i dicek dengan menggunakan modulo 2, jika 1 bagi 2 ternyata sisanya tidak sama dengan 0 berarti i tersebut adalah bilangan ganjil yang mengakibatkan pertambahan 1 angka pada mBilGanjil. Setelah itu di line 77, terdapat fungsi ReportProgress yang merupakan fungsi bawaan dari background worker yang berguna untuk memberikan sinyal kepada fungsi updateGUI untuk segera dijalankan. Jadi ketika fungsi ReportProgress dipanggil maka fungsi updateGUI akan dijalankan. Nah kita lihat di fungsi ReportProgress tersebut terdapat variabel input berupa presentasi dan i. Variabel presentasi nantinya akan digunakan untuk mengupdate tampilan pada progress bar dan presentasi label progress bar, sedangkan i adalah nilai bilangan ganjil yang nantinya akan ditampilkan pada listbox. Sebagai catatan, variabel input i tersebut boleh tidak berupa integer tapi berupa tipe data yang lain seperti string, char, double, float, byte, dsb.

Line 79 adalah handle untuk nilai i yang bukan bilangan ganjil. Urainnya hampir sama dengan kode blok di line 74, cuman di dalam kode else ini fungsi report progress hanya mengambil presentasi saja, karena jika i adalah bilangan maka kita tidak perlu menampilkan bilangan tersebut pada listboxt.

Line 84, thread dibuat sleep selama 13ms. Angka 13ms cuma coba-coba saja :D, silahkan gunakan angka yang lain sesuai dengan kebutuhan project yang dibuat. Yang perlu diperhatikan jika waktu sleep terlalu pendek maka updateGUI dapat mengalami masalah ketika mengupdate progress bar. Secara sederhana fungsi updateGUI butuh waktu beberapa milli sekon (mkn 12 - 17 ms tergantung tampilan GUI) untuk mengupdate GUI mainWindow, nah jika fungsi updateGUI tersebut belum selesai kemudian dia panggil lagi dari proses looping, berarti tar fungsi updateGUInya terlalu sibuk yang boleh jadi mengakibatkan aplikasi menjadi freeze. Makanya disini loopingnya di sleepkan dulu, biar fungsi updateGUI bisa selesai dengan tugasnya kemudian baru looping selanjutnya diproses :-). Nah itu kalo waktu sleepnya terlalu pendek, jika waktu sleep terlalu panjang otomatis update value diprogress bar terlihat agak lama dan membosankan, jadi pilih angka sleep yang pas untuk masing-masing aplikasi.

Line 87 - 91, ini adalah kode untuk mendeteksi sinyal cancel untuk menghentikan thread. Jika kembali melihat fungsi startButton_Click di line 36, disitu terdapat fungsi cancelAsync() yang telah dijelaskan sebelumnya bahwa fungsi cancelAsync tersebut berguna untuk memberikan sinyal untuk menghentikan thread background worker yang sedang berjalan. Nah sinyal dari cancelAsync ini diterima oleh fungsi cancellationPending yang menyebabkan e.cancel menjadi true (line 89), nilai true tersebut nantinya akan digunakan pada fungsi selesai() yang akan dijelaskan kemudian. Kemudian line 90, reportProgress diubah kembali menjadi nol, karena jelas thread ini harus dihentikan jadi progress barnya harus kembali di set ke nilai 0. Terus line 91, 'return', berarti fungsi threadProcess ini selesai yang mengakibatkan fungsi selesai() akan dijalankan dengan e.cancel bernilai true.

Line 97, terdapat fungsi ReportProgress kembali namun dengan nilai 100. Tentunya fungsi ini dapat dicapai jika proses looping telah selesai dan tidak ada sinyal untuk menghetikan thread, makanya nilainya 100. Kemudian line 98, e.Result = mBilGanjil, nah e.Result tersebut berarti menyimpan jumlah total bilangan ganjil yang dari selang 0 - args. e.Result ini akan digunakan oleh fungsi selesai() yang nantinya akan ditampilkan ke user. Kita lihat line 98 adalah kode terakhir dari fungsi threadProcess ini, berarti setelah itu fungsi selesai() akan dijalankan, namun dengan e.cancel = false.

Beralih ke fungsi updateGUI. Fungsi ini berguna untuk melakukan update terhadap item-item yang terdapat pada mainWindow aplikasi yang kita buat. Fungsi ini akan dijalankan ketika fungsi ReportProgress dieksekusi pada fungsi threadProcess. Seperti terlihat diatas, pada fungsi ReportProgress terdapat variabel input berupa presentasi dan nilai bilangan ganjil. Nah variabel-variabel tersebut akan digunakan lebih lanjut oleh updateGUI untuk menyesuaikan tampilan mainWindow yang lebih aktual.

Line 105, nilai progress bar diset sesuai dengan presentasi yang dimasukkan ke fungsi ReportProgress. Line 106 pun juga sama, cuman presentasinya ditampilkan pada label. Jadi selain progress bar yang terupdate kita juga dapat melihat presentasi progressnya.

Line 107, dilakukan pengecekan terhadap e.UserState. UserState sebenarnya menyimpan bilangan ganjil yang dimasukkan dari fungsi ReportProgress. Nah makanya disini dicek, kalo ada bilangan ganjil (e.UserState tidak bernilai 0), maka bilangan ganjil tersebut akan ditampilkan pada listboxt seperti yang dilakukan pada line 109.

Terakhir adalah fungsi selesai(). Seperti yang telah disebutkan sebelumnya, fungsi selesai() adalah fungsi yang baru akan dijalankan ketika fungsi threadProcess selesai atau eksekusi program keluar dari fungsi threadProcess. Sebagaimana diketahui, threadProcess diakhiri ketika ada perintah untuk menghentikan thread atau karena proses yang dikerjakan threadProcess (dalam hal ini mengecek dan menghitung bilangan ganjil) memang sudah selesai. Jadi dua kondisi tersebut akan dievaluasi di dalam fungsi selesai() ini.

Line 117, jika e.Cancelled bernilai true berarti menandakan bahwa fungsi threadProcess sebelumnya diakhiri karena adanya sinyal untuk menghentikan thread. Hal tersebut dapat dilihat pada line 89 di dalam fungsi threadProcess. Kemudian di line 119 - 134, kode programnya sama dengan line 34 - 59 yang mengambil bilangan inputan dari user kemudian dimasukkan ke variabel max yang kemudian dimasukkan kembali ke fungsi RunWorkerAsync(max){line 135} untuk memulai thread backgroundworker yang baru. Jadi secara sederhana, jika thread pertama di cancel maka thread kedua akan segera dijalankan sesaat setelah thread pertama berhenti tanpa menunggu user untuk mengklik tombol start. Nah makanya disini kita dapat menggunakan 1 tombol saja untuk menjalankan atau menghentikan thread yang sedang running.

Line 138, Di sini dideteksi jika fungsi threadProcess berhenti karena adanya error yang terjadi dalam sistem {error pada visual studio, error pada program, atw hardware pc, dsb...}. Jika ternyata error seperti ini terjadi maka akan dikeluarkan message seperti yang terlihat pada line 140.

Line 142 sampai terakhir adalah kode program yang akan dieksekusi jika fungsi threadProcess berhenti secara normal. Makanya di line 144 diperlihatkan jumlah bilangan ganjil yang telah dihitung. Jumlah bilangan ganjil tersebut diambil dari e.Result. Sebelumnya seperti terlihat pada line 98 di fungsi threadProcess, e.Result ini diassign mBilGanjil, sehingga pada fungsi selesai() nilai e.Result tersebut dapat digunakan kembali untuk ditampilkan ke user dengan menggunakan messageBox seperti pada line 144.

Nah sampai disini, kita telah membuat fungsi-fungsi yang nantinya digunakan untuk menjalankan backgroundworker sesuai dengan kebutuhan project yang sedang kita buat. Berikutnya adalah menghubungkan ketiga fungsi-fungsi diatas ke variabel worker. Untuk itu kembali ke fungsi public MainWindow() yang terletak dibaris-baris awal, kemudian tambahkan kode berikut :


public MainWindow() sebagaimana diketahui bersama adalah fungsi konstruktor, jadi didalam fungsi ini kita akan melakukan inialisasi variabel-variabel termasuk variabel worker yang telah dibuat. Line 28 adalah fungsi yang secara otomatis akan selalu ada karena digenerate secara otomatis oleh visual studio. Fungsi tersebut melakukan inisialisasi internal terhadap program kita seperti inisialisasi komponen-komponen pada file xml untuk GUI aplikasi. Kemudian line 30, variabel worker yang telah kita buat ditambahkan fitur reportprogress, Maksudnya worker ini dapat menggunakan fungsi ReportProgress yang telah dijelaskan sebelumya. Line 31, worker ditambahkan fitur yang dapat melakukan request untuk menghentikan thread. Jadi sekalipun didalam fungsi threadProcess terdapat kode untuk menghetikan thread, namun jika WorkerSupportCancellation tidak diset ke true, maka kode yang terdapat dalam fungsi threadProcess tersebut tidak akan berguna. Line 32, variabel worker diintegrasikan dengan fungsi threadProcess yang melakukan kegiatan utama dithread. Line 33, jika terdapat fungsi ReportProgress dari doWork, maka worker akan memanggil fungsi updateGUI, dan yang terakhir adalah jika workernya selesai maka fungsi selesa() akan dipanggil. So sampai disini kita bisa melihat semua fungsi-fungsi yang telah dibuat telah diintegrasikan. So... Jika programnya kita jalankan, hasilnya :
Kemudian pada textbox dimasukkan angka 678 terus tombol start ditekan hasilnya :
Nah ketika presentasi progress bar sekitar 58, angka pada textbox diganti, kemudian tombol start ditekan kembali sebelum presentasinya mencapai 100, maka progress bar akan start dari awal lagi. Jika kita kita tidak menggunakan kode untuk menghentikan thread backgroundworker yang sedang berjalan sekarang maka aplikasi ini akan membuat thread yang baru. So jika tombol start ditekan berulang-ulang, aplikasinya bisa freeze atau malah crash/not responding. Jadi terlihat, pentingnya untuk mengetahui teknik dalam menghentikan thread backgroundworker yang sedang running. :-)

Sekian...... semoga bermanfaat... :-)

Wednesday, December 31, 2014

Making a Simple Pie Chart Style from Scratch in C# WPF - Basic

Pada postingan ini akan dibuat satu buah chart di C# dengan bentuk Pie tanpa menggunakan dll dari orang lain. Jadi postingan ini beranjak dari awal dengan menggunakan canvas,brush, path, dan sebagainya. Pertama-tama mari kita buat project baru di visual studio 2010 :


Setelah tekan tombol "OK", kemudian klik kanan project tersebut dan pilih "Add -  New Item" :


Setelah itu piliha "User Control (WPF)", dan beri nama terserah saja. Di sini namanya " graphControl" :


Silahkan tekan tombol "Add", Nah sampai disini kita mempunya 2 buah file xml, satu untuk window dan satu biji untuk user control dengan nama "graphControl". Terus, Drag 1 biji canvas ke GraphControl tersebut :


Konfigurasi layout canvas tersebut diubah seperti konfigurasi berikut :


Beralih ke file "GraphControl.xml.cs", di dalam kelas GraphControl tambahkan private kelas dengan nama piePieceData. Kelas tersebut berguna menampung data yang dibutuhkan untuk membuat satu element warna pada PieGraph yang kita buat. Secara spesifik sebenarnya kelas tersebut berguna untuk menyimpan properti yang dibutuhkan oleh ArcSegment untuk PathFigure. Kode programnya sebagai berikut :


Terus tambahkan variabel-variabel yang dibutuhkan :


Terus..... Tambahkan method-method berikut dalam kelas GraphControl:





Sekarang beralih ke bagian MainWindow, untuk itu pada MainWindow.xml tambahkan nama pada gridnya :


Nah berikutnya kita akan menghubungkan GraphControl yand telah dibuat ke mainWindow.So..Tambahkan kode berikut pada MainWindow.xaml.cs :


Sampai disini Pie Graph yang telah kita buat hasilnya seperti di bawah :


Alhamdulillah.... Yeeee.... selesai..... Semoga bermanfaat..... :-)

Wednesday, December 24, 2014

Menemukan Directory File.exe Menggunakan C# WPF

Jika kita mencari kode program dalam C# di google untuk menemukan directory file.exe dari program yang kita buat di visual studio, maka akan ditemukan banyak cara untuk menemukan directory file.exe tersebut. Nah disini cuma diperlihatkan 4 cara untuk mencapai tujuan ini. Untuk itu, silahkan buat project baru di visual studio 2010, dengan tampilan main window seperti terlihat di bawah :


Jadi terlihat, main windownya terdiri dari 4 button dan 4 textbox. Kemudian masing-masing textbox-nya diberi nama yang spesifik biar tar mudah dipanggil didalam kode program untuk tiap button. Penamaan textboxnya terserah saja sesuai keinginan, untuk project ini digunakan masing-masing nama seperti terlihat di bawah :


Ok, berikutnya akan ditambahkan kode di dalam tiap button. Untuk button pertama :
Kemudian untuk button kedua :
Untuk button ketiga :
Untuk button keempat :

Ok. Jika aplikasinya dijalankan, dan masing-masing tombolnya di tekan, hasilnya :


Jika file.exe-nya dipindahkan ke directory yang lain :

Jika file.exe-nya dirunning dari komputer lain dalam jaringan :

Terlihat... masing-masing kode dapat digunakan untuk menemukan directory aktual file.exe yang sedang running. Nggg.... Jika keempat cara tersebut dibandingkan, Saya pribadi lebih memilih cara yang "kedua" hehehe... :D

Sekian... Moga bermanfaat... :-)