30 April 2009

63 Bahasa Scripting Windows PowerShell (Terakhir)

Registry
Registry mempunyai dua elemen, key dan entry. Registry key, yang berfungsi sebagai container (mirip direktori), merupakan item pada drive Windows PowerShell. Mengakses registry key sama dengan mengakses file atau direktori. Terdapat dua root key yang dapat diakses, HKEY_CURRENT_USER dan HKEY_LOCAL_MACHINE. Sedangkan registry entry merupakan property dari registry key. Oleh sebab itu perlu pendekatan berbeda dibanding registry key.

Menampilkan Subkey dari Registry Key
Seperti yang telah dijelaskan, registry key merupakan item. Maka dari itu perlakuan terhadap registry key sama dengan file atau direktori. Kita bisa melihat isi dari registry key dengan cmdlet Get-ChildItem. Contoh berikut akan menampilkan item pada drive HKCU:
Get-ChildItem hkcu:







Perintah-perintah berikut menampilkan hasil yang sama dengan perintah diatas.
Get-ChildItem -Path Registry::HKEY_CURRENT_USER Get-ChildItem -Path Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER Get-ChildItem -Path Registry::HKCU Get-ChildItem -Path Microsoft.PowerShell.Core\Registry::HKCU Get-ChildItem -Path Registry::HKCU
Menyalin Registry Key
Menyalin registry key dilakukan dengan cmdlet Copy-Item. Perintah berikut akan menyalin HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion dan semua property ke HKCU:\ dan membuat key baru dengan nama “CurrentVersion”.
Copy-Item -Path ‘HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion’ -Destination hkcu:
Perintah diatas tidak menyalin subkey pada registry asal. Dengan menambahkan parameter Recurse, semua subkey juga akan disalin.
Copy-Item -Path ‘HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion’ -Destination hkcu: -Recurse

Membuat dan Menghapus Registry Key
Membuat registry key lebih mudah daripada membuat file atau direktori. Karena semua registry key adalah container, kita tidak perlu menyediakan ItemType.
New-Item -Path hkcu:\software\tes
Begitu pula untuk menghapus dengan menggunakan cmdlet Remove-Item.
Remove-Item -Path hkcu:\Software\tes
Berikan parameter Recurse jika tidak ingin ditanya untuk tiap item yang dihapus.
Remove-Item -Path hkcu:\Software\tes -Recurse
Perintah diatas akan menghapus registry key HKCU:\Software\tes beserta isinya. Untuk menghapus isinya saja gunakan perintah berikut.
Remove-Item -Path hkcu:\Software\tes\* -Recurse

Menampilkan Registry Entry
Untuk menampilkan registry entry dari sebuah registry key kita bisa menggunakan cmdlet Get-Item. Registry key mempunyai property dengan nama “Property” yang berisi daftar registry entry.
Get-Item -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion | Select-Object -ExpandProperty Property











Hasil yang ditampilkan perintah diatas adalah kumpulan registry entry. Untuk menampilkan registry entry beserta nilai datanya, gunakan perintah berikut.
Get-ItemProperty -Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion









Membuat dan Menghapus Registry Entry
Cmdlet New-ItemProperty digunakan untuk membuat Registry Entry. Pada contoh ini kita akan menambahkan entry baru dengan nama “PowerShellPath” bersama dengan path ke registry key, PropertyTipe dan nilai dari entry tersebut. Nilai dari registry entry tersebut adalah variabel $PSHome, yang menyimpan direktori instalasi dari Windows PowerShell.
New-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion -Name PowerShellPath -PropertyType String -Value $PSHome
Perintah diatas akan menghasilkan informasi mengenai entry baru yang dihasilkan.




PropertyType merupakan salah satu dari pilihan berikut.
  • Binary. Data biner.
  • DWord. Nilai valid 32 bit integer.
  • ExpandString. String yang dapat berisi variabel environment.
  • MultiString. String multi baris.
  • String. Nilai string.
  • QWord. Data biner 8 byte.
Untuk menghapus registry entry, gunakan cmdlet Remove-ItemProperty.
Remove-ItemProperty -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion -Name PowerShellPath

Baca selengkapnya...

29 April 2009

Bahasa Scripting Windows PowerShell (Bagian 6)

Berhubungan dengan Jaringan
TCP/IP sudah sangat banyak digunakan dalam dunia jaringan dan merupakan protokol jaringan yang paling umum. Akses jaringan pada bahasan berikut akan menggunakan
WMI.

Mendapatkan Alamat IP
Perintah berikut akan mendapatkan daftar dari alamat IP yang digunakan oleh komputer.
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=TRUE -ComputerName . | Select-Object -Property IPAddress





Output dari perintah diatas adalah alamat IP yang diapit tanda kurung kurawal. Ini disebabkan output tersebut mempunyai tipe array. Property IPAddress untuk tiap kartu jaringan sebenarnya merupakan array. Nilai-nilai dari array ini bisa kita dapatkan dengan menggunakan Select-Object ExpandProperty.
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=TRUE -ComputerName . | Select-Object -ExpandProperty IPAddress




Untuk menampilkan data konfigurasi IP untuk tiap kartu jaringan, dapat menggunakan perintah berikut.
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=TRUE -ComputerName .
Tampilan default untuk perintah diatas tidak lengkap untuk kondisi tertentu. Untuk mendapatkan informasi lebih detail, kita dapat menggunakan Select-Object untuk “memaksa” lebih banyak property yang akan ditampilkan.
Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter IPEnabled=TRUE -ComputerName . | Select-Object -Property [a-z]*
Perintah diatas akan menampilkan informasi detail tentang DHCP, DNS, routing dan konfigurasi IP lainnya.

Ping Komputer
Kita dapat melakukan ping terhadap komputer dengan menggunakan Win32_PingStatus. Perintah berikut akan melakukan ping ke komputer lokal dengan output yang panjang.
Get-WmiObject -Class Win32_PingStatus -Filter "Address='127.0.0.1'" -ComputerName .
Kita dapat mendapatkan informasi yang lebih berguna dan mendekati output standar layaknya kita melakukan ping dengan hanya menampilkan property Address, BufferSize, ResponseTime, dan StatusCode.
Get-WmiObject -Class Win32_PingStatus -Filter "Address='127.0.0.1'" -ComputerName . | Select-Object -Property Address,BufferSize,ResponseTime,StatusCode



StatusCode yang berisi 0 berarti ping sukses. Kita dapat melakukan ping lebih dari satu kali dengan menggunakan ForEach-Object.
1..4 | ForEach-Object {Get-WmiObject -Class Win32_PingStatus -Filter "Address='127.0.0.1'" -ComputerName .} | Select-Object -Property Address,BufferSize,ResponseTime,StatusCode
Dengan cara diatas kita akan melakukan ping sebanyak 4 kali.

Bekerja dengan File dan Direktori

Dalam lingkungan Windows tentu kita sering berhubungan dengan file dan direktori. Apalagi dalam Windows PowerShell yang mirip dengan UNIX. Akses terhadap sebagian besar elemen pada Windows layaknya kita mengakses sebuah file. Pada bagian ini kita akan membahas bagaimana manipulasi terhadap file dan direktori dengan menggunakan cmdlet yang telah disediakan.

Menampilkan Isi Direktori
Tentu kita tahu cmdlet Get-ChildItem yang sering menjadi contoh pada beberapa posting sebelumnya. Cmdlet ini mirip dengan perintah dir pada command shell tradisional, yaitu mendapatkan isi dari direktori. Misalnya kita ingin mendapatkan isi dari drive C:\ termasuk file yang di sembunyikan (hidden). Kita bisa lakukan dengan memberikan parameter Force.
Get-ChildItem -Force C:\
Bisa juga kita melihat semua isi dari direktori dari drive C:\ beserta dengan isi dari direktori-direktori yang berada didalam drive C:\. Dengan menambahkan parameter -Recurse, kita bisa melakukan proses ini. Perhatian proses ini dapat memakan waktu yang sangat lama, karena banyaknya file yang ditampilkan. Untuk keluar dari proses ini sebelum berakhir, tekan tombol Ctrl+C.
Get-ChildItem -Force C:\ -Recurse

Menyalin File dan Direktori
Prosedur untuk menyalin file atau direktori dapat diselesaikan dengan cmdlet Copy-Item, yang mirip dengan perintah copy pada command shell tradisional. Perintah copy merupakan alias untuk cmdlet Copy-Item pada Windows PowerShell. Misalnya kita ingin menyalin file dari C:\a.txt ke C:\tes\a2.txt.
Copy-Item -Path C:\a.txt -Destination C:\a2.txt
Jika file tujuan sudah ada, maka proses penyalinan file gagal. Untuk menumpuki file jika sudah ada dapat menggunakan parameter Force.
Copy-Item -Path C:\a.txt -Destination C:\a2.txt -Force
Proses penyalinan direktori dapat dilakukan dengan cara yang sama seperti penyalinan file. Perintah berikut akan menyalin direktori C:\asal berserta isinya ke direktori C:\tujuan.
Copy-Item -Path C:\asal -Recurse -Destination C:\tujuan
Atau bisa juga menyalin sebagian item yang dibatasi oleh kondisi dengan parameter Filter.
Copy-Item -Filter *.txt -Path C:\asal -Recurse -Destination C:\tujuan

Membuat atau Menghapus File dan Direktori
Membuat file dapat dilakukan dengan cmdlet New-Item. Pembuatan file dan direktori dibedakan dengan menyertakan parameter ItemType yang berupa “directory” atau “file”. Untuk membuat direktori baru:
New-Item -Path ‘C:\dir baru’ -ItemType “directory”
Atau membuat file baru:
New-Item -Path ‘C:\dir baru\a.txt’ -ItemType “file”
Menghapus file bisa dilakukan dengan cmdlet Remove-Item. Ini berlaku untuk file maupun direktori.
Remove-Item C:\tes




Berikan parameter Recurse jika tidak ingin ditanya untuk tiap item yang dihapus.
Remove-Item C:\tes -Recurse

Baca selengkapnya...

28 April 2009

Bahasa Scripting Windows PowerShell (Bagian 5)

Filter Obyek dari Pipeline
Windows PowerShell memungkinkan obyek yang dikirim melalui pipe di filter dan hanya obyek dengan kriteria tertentu saja yang ditampilkan. Dengan menggunakan cmdlet Where-Object, tiap obyek yang dikirim melalui pipe akan dites dan hanya yang memenuhi kondisi yang diinginkan saja yang akan ditampilkan. Kondisi yang diinginkan diberikan pada parameter FilterScript.
Isi dari parameter FilterScript merupakan blok skrip yang berisikan satu atau lebih perintah Windows PowerShell yang diawali dan diakiri oleh tanda kurung kurawal {}, yang nantinya akan dievaluasi menjadi kondisi True atau False. Blok skrip tersebut mengandung operator pembanding. Operator-operator pembanding dasar yang ada adalah sebagai berikut.
  • -eq. Sama dengan.
  • -ne. Tidak sama dengan.
  • -lt. Lebih kecil dari.
  • -le. Lebih kecil dari atau sama dengan.
  • -gt. Lebih besar dari.
  • -ge. Lebih besar dari atau sama dengan.
  • -like. Seperti (bisa menggunakan wildcard sebagai pembanding).
  • -notlike. Tidak seperti (bisa menggunakan wildcard sebagai pembanding).
  • -contains. Berisi.
  • -not contains. Tidak berisi.
Variabel spesial “$_” digunakan sebagai referensi terhadap obyek yang dikirim melalui pipeline. Contoh dibawah ini akan memfilter angka dari 1 sampai 4 dengan kondisi lebih kecil dari 3. Hasil yang ditampilkan adalah 1 dan 2.
1, 2, 3, 4 | Where-Object -FilterScript {$_ -lt 3}
Karena $_ merupakan referensi dari obyek, maka kita dapat mengakses property untuk tes kondisi. Misalnya jika kita mengetikkan perintah Get-Command, maka akan tampil banyak elemen dari Windows PowerShell. Namun kita hanya tertarik pada elemen yang memiliki property Name diakhiri kata “Item”. Masalah tersebut dapat diatasi dengan mengetikkan perintah berikut.
Get-Command | Where-Object -FilterScript {$_.Name -like “*item”}
Hasil output dari Where-Object dapat pula diteruskan melalui pipe ke Where-Object lain, yang artinya memfilter dua kali. Tidak terbatas dua, cara filter seperti ini bisa digunakan lebih dari satu. Misalnya hasil dari output filter diatas di filter lagi menjadi hanya yang mempunyai huruf “C” sebagai awal namanya.
Get-Command | Where-Object -FilterScript {$_.Name -like “*item”} | Where-Object -FilterScript {$_.Name -like “c*”}
Dua elemen Where-Object diatas dapat pula dijadikan satu menjadi satu elemen Where-Object dengan menggunakan operator logika.
Get-Command | Where-Object -FilterScript {($_.Name -like “*item”) -and ($_.Name -like “c*”)}
Operator logika standar yang ada adalah sebagai berikut.
  • -and.
  • -or.
  • -not.
  • !. (sama dengan -not).

Menggunakan Variabel
Variabel digunakan untuk menyimpan hasil dari suatu proses. Pada Windows PowerShell, variabel diawali dengan tanda $ dan namanya dapat mengandung karakter alphanumeric dan garis bawah (_). Untuk menciptakan sebuah variabel, kita bisa langsung mengetikkan variabel tersebut, contoh:
$var1
Tidak ada yang dihasilkan dari perintah tersebut karena variabel tersebut tidak memiliki nilai. Kita bisa juga langsung mengisikan nilai pada saat pembuatan variabel.
$var1 = 1000
Jika kita mengetikkan nama variabel yang sudah ada nilainya, maka nilainya akan ditampilkan di layar. Bahkan sebuah obyek dapat disimpan dalam sebuah variabel. Misalkan:
$var1 = Get-ChildItem
Jika kita ketikkan $var1, maka akan tampil isi dari direktori yang bersangkutan. Sebagai bukti lebih lanjut, kita bisa melakukan filter terhadap variabel tersebut.
$var1 | Where-Object -FilterScript {$_ -like “a*”}
Kita dapat melihat apa saja variabel yang ada dengan menggunakan cmdlet Get-Variable. Semua variabel pada Windows PowerShell termasuk variabel yang kita buat akan ditampilkan.
Get-Variable
Hal yang sama kita dapatkan jika kita mengetikkan perintah berikut ini.
Get-ChildItem variable:
Untuk menghapus variabel, kita menggunakan cmdlet Remove-Variable dengan parameter Name diisi dengan nama variabel tanpa menggunakan tanda $.
Remove-Variable -Name var1
Atau bisa menghapus semua variabel dengan cara berikut.
Remove-Variable -Name * -Force -ErrorAction SilentlyContinue

Baca selengkapnya...

27 April 2009

Bahasa Scripting Windows PowerShell (Bagian 4)

Obyek WMI
Windows Management Instrumentation (WMI) merupakan teknologi untuk administrasi sistem Windows dan pernah dibahas pada posting sebelumnya. Untuk keperluan ini disediakan cmdlet Get-WmiObject.
Hal utama yang menjadi masalah bagi user yang mengakses WMI adalah mengetahui apa saja yang bisa diperbuat dengan WMI. Ada ratusan class WMI yang berisi informasi resource yang bisa diakses. Layaknya obyek, dalam class tersebut juga terdapat property. Untuk mendapatkan daftar class dari WMI:
Get-WmiObject -List
Daftar class yang ditampilkan pada tiap komputer dapat bervariasi, tergantung pada sistem operasi yang digunakan dan ektensi WMI yang ditambahkan oleh aplikasi yang diinstal. Kita bahkan dapat mendapatkan informasi ini dari komputer remote dengan menggunakan parameter ComputerName yang menentukan nama komputer atau alamat IP.
Get-WmiObject -List -ComputerName KompParno
Perlu diperhatikan bahwa ketika kita berusaha terhubung dengan komputer remote, komputer remote harus menjalankan service WMI dan pada konfigurasi default akun user yang kita gunakan harus ada pada grup administrators pada remote komputer.
Setelah kita tahu nama class yang kita inginkan, kita dapat memperoleh informasi dari class tersebut dengan parameter -Class.
Get-WmiObject -Class Win32_BIOS




Class Win32_BIOS mempunyai lebih banyak property dari yang ditampilkan di layar. Untuk mendapatkan semua property dari class Win32_BIOS kita bisa mengetikkan perintah berikut.
Get-WmiObject -Class Win32_BIOS | Get-Member –MemberType Property

Menggunakan Class Static dan Method
Class static merupakan referensi pustaka dari method dan property yang “tidak berubah”. Class seperti ini tidak dibuat, tetapi digunakan.

System.Environment
Class System.Environment berisi informasi umum tentang environment yang dipakai untuk process yang bersangkutan, yaitu Windows PowerShell. Kita dapat menggunakan class static dengan menggunakan kurung siku sebelum dan sesudah nama class.
[System.Environment]
Dengan mengetikkan perintah diatas, akan menampilkan informasi umum.



Untuk menampilkan detail class ini:
[System.Environment] | Get-Member
Atau menampilkan member static dengan parameter Static.
[System.Environment] | Get-Member -Static
Supaya dapat berkerja dengan static method atau static property kita menggunakan tanda ::. Misalnya kita ingin mendapatkan nama komputer yang bisa kita dapatkan dengan property MachineName.
[System.Environment]::MachineName

System.Math
Class static System.Math berguna untuk operasi yang berhubungan dengan matematika. Member dari System.Math bisa kita dapatkan dengan menggunakan Get-Member. Berikut adalah sebagian contoh operasi matematika dengan menggunakan class static System.Math.

Baca selengkapnya...

24 April 2009

Bahasa Scripting Windows PowerShell (Bagian 3)

Mengirim Data Menggunakan Cmdlet Out-*
Mengirim data disini maksudnya adalah mengirim data dari output dengan tujuan untuk ditampilkan di layar, atau dicetak melalui printer, atau disimpan kedalam file. Biasanya kita menggunakan cmdlet ini dengan input dari output cmdlet lain (menggunakan pipe). Misalnya jika kita mengetikkan perintah:
Get-ChildItem | Out-Host
Akan menampilkan isi direktori ke layar. Ada 4 tujuan utama pengiriman data.
Console/layar (Out-Host)
File (Out-File)
Printer (Out-Printer)
Tidak ditampilkan/dibuang (Out-Null)

Menampilkan Data pada Console/Layar (Out-Host)
Secara default Windows PowerShell mengirimkan data ke layar, dimana fungsi ini sama persis dengan yang dilakukan cmdlet Out-Host. Pada posting sebelumnya sudah pernah cmdlet ini menjadi contoh. Misalnya dengan perintah berikut akan menampilkan isi dari suatu direktori ke layar yang akan ditampilkan per halaman layar.
Get-ChildItem | Out-Host -Paging
Hal yang sama kita dapatkan jika kita dapatkan jika kita menggunakan fungsi more. Pada Windows PowerShell more adalah sebuah fungsi yang memanggil Out-Host -Paging.
Get-ChildItem | more
Fungsi more juga dapat digunakan untuk menampilkan isi dari file ke layar.
more C:\boot.ini

Menyimpan Data ke File (Out-File)
Jika kita menggunakan cmdlet Out-File, data yang dikirim akan disimpan ke suatu file. Misalnya:
Get-ChildItem | Out-File -FilePath “C:\isidir.txt”
Perintah diatas akan membuat file baru, jika sudah ada maka file tersebut akan di tumpuki. Untuk menambah isi file kita bisa menggunakan parameter Append.
Get-ChildItem | Out-File -FilePath “C:\isidir.txt” -Append
Secara default cmdlet Out-File akan membuat file unicode. Dengan begitu mungkin hasil output file yang dihasilkan mungkin tidak sesuai dengan yang kita harapkan. Kita dapat menghasilkan file bentuk ASCII dengan menggunakan parameter Encoding.
Get-ChildItem | Out-File -FilePath “C:\isidir.txt” -Encoding ASCII
Format file yang disimpan ke file akan tampak seperti output pada console. Pada sebagian kasus, hal ini akan menyebabkan output yang terpotong karena tidak cukup pada layar. Kita bisa memaksa supaya output tidak dipotong dengan menggunakan parameter Width yang merupakan panjang baris. Karena parameter Width tipenya 32 bit integer, maka nilai maksimum adalah 2147483647. Perintah berikut akan mengeset panjang baris ke nilai maksimum.
Get-ChildItem | Out-File -FilePath “C:\isidir.txt” -Width 2147483647

Mencetak Data ke Printer (Out-Printer)
Cmdlet ini digunakan untuk mencetak data ke printer. Jika kita tidak memberikan nama printer sebagai parameter, maka yang digunakan adalah printer default.
Get-ChildItem | Out-Printer -Name “Canon BJC-265SP”

Tidak Menampilkan Data/Dibuang (Out-Null)
Cmdlet ini tidak akan menampilkan hasil/output. Ini berguna jika kita tidak memerlukan data yang dihasilkan. Misalnya untuk melakukan suatu proses tapi kita tidak memerlukan hasil/output dari proses yang dijalankan.
Get-ChildItem | Out-Null

Drive Windows PowerShell
Drive pada Windows PowerShell tidak melulu tentang disk drive. Selain drive pada disk ada fungsi, variabel, registry dan lain-lain, yang bisa diakses seperti layaknya mengakses disk drive. Get-PSDrive merupakan cmdlet untuk menampilkan informasi tentang drive pada Windows PowerShell. Dibawah ini adalah contoh tampilan setelah eksekusi cmdlet Get-PSDrive.






Daftar tersebut bisa berbeda. Kita bisa menambahkan atau menghapus drive yang ada. Pada gambar diatas bisa kita lihat drive C, D, E dan F mempunyai provider FileSystem. FileSystem ini bisa berupa partisi pada hard disk, disk drive atau removable disk drive. Untuk mengetahui apa saja provider yang ada bisa menggunakan cmdlet Get-PSProvider. Kita bisa mengakses drive tersebut dengan cara yang sama seperti kita mengakses drive pada command shell tradisional. Pada command shell tradisional kita mengetikan perintah cd D: untuk berpindah ke drive D. Cara yang sama untuk mengakses drive pada Windows PowerShell. Untuk berpindah drive bisa menggunakan Set-Location (mirip jika kita berpindah drive pada console tradisional dengan mengetikkan cd ).
Set-Location Alias:
Dengan mengetikkan perintah diatas, kita berpindah drive ke drive Alias yang berisi daftar alias yang ada. Fitur ini mirip dengan UNIX/Linux yang menganggap semua hal adalah file.

Menambah Drive Windows PowerShell
Cmdlet yang digunakan untuk menambah drive adalah New-PSDrive. Cmdlet New-PSDrive membutuhkan tiga parameter:
Nama drive. Nama yang unik, tidak boleh kembar.
PSProvider. Provider yang valid untuk Windows PowerShell. (cmdlet Get-PSProvider untuk menampilkan provider yang ada).
Root. Merupakan path ke drive yang dituju.
Misalnya kita ingin membuat drive dengan nama “sys32”. Drive ini merupakan direktori pada disk dengan tujuan C:\Windows\system32.
New-PSDrive -Name sys32 -PSProvider FileSystem -Root C:\Windows\system32
Setelah sukses menambahkan drive, kita bisa melihat isi dari drive tersebut dengan cmdlet Get-ChildItem.

Menghapus Drive Windows PowerShell
Menghapus drive Windows PowerShell dapat menggunakan cmdlet Remove-PSDrive. Parameter yang dibutuhkan adalah nama drive.
Remove-PSDrive -Name sys32
Kita tidak dapat menghapus drive jika kita berada pada drive yang bersangkutan.

Baca selengkapnya...

23 April 2009

Bahasa Scripting Windows PowerShell (Bagian 2)

Object Pipeline
Pemakaian pipe pada console tentu tidak asing lagi bagi administrator UNIX/Linux. Pipe digunakan sebagai input dari perintah dari output dari perintah lain. Begitu pula pada Windows PowerShell yang mempunyai fungsi yang sama, tapi pada Windows PowerShell menggunakan obyek yang dikirim ke perintah lain. Pemakaian pipe bisa dilakukan dimana saja pada Windows PowerShell. Pemakaian pipe ini bisa lebih dari satu, sesuai dengan kebutuhan.
Contoh sederhana dari penggunaan pipe adalah menampilkan isi suatu direktori ke layar dan menampilkannya per halaman. Untuk memenuhi kebutuhan ini, kita memerlukan dua cmdlet yaitu Get-ChildItem dan Out-Host. Get-ChildItem digunakan untuk menampilkan isi direktori dan Out-Host mengirimkan output ke host Windows PowerShell (dalam hal ini layar) untuk ditampilkan. Perintahnya adalah seperti ini.
Get-ChildItem -Path C:\Windows\system32 | Out-Host -Paging
Dengan perintah tersebut, kita akan mendapatkan output berupa isi dari direktori C:\Windows\system32. Output dari Get-ChildItem yang berupa isi dari direktori akan diteruskan sebagai input dari Out-Host yang akan menampilkan ke layar.

Menampilkan Struktur Obyek dengan Get-Member
Ini barangkali bukan merupakan sesuatu yang asing bagi kita yang sering berkutat dengan pemrograman berorientasi obyek. Suatu waktu kita perlu mendapatkan informasi dari sebuah obyek, apakah itu method atau property. Dalam pemrograman .NET, ada suatu istilah yaitu Reflection yang digunakan untuk mendapatkan metadata dari sebuah obyek. Atau pada Delphi ada istilah Runtime Type Information (RTTI), yang mempunyai fungsi mirip seperti diatas. Pada Windows PowerShell ada cmdlet Get-Member untuk kebutuhan ini.
Tanpa kita sadari semua perintah atau cmdlet yang ada adalah merupakan obyek. Dengan kenyataan ini, maka kita bisa mendapatkan informasi method dan property yang dipunyai oleh sebuah cmdlet. Contohnya jika kita ingin mendapatkan struktur obyek dari cmdlet Get-ChildItem dengan mengetikkan perintah:
Get-Member -InputObject Get-ChildItem Maka kita akan mendapatkan output seperti dibawah ini.















Atau kita bisa dapatkan output yang mirip jika kita mengetikkan perintah:
Get-ChildItem | Get-Member Kita bahkan bisa mendapatkan isi dari property Get-ChildItem. Jika menjalankan perintah dibawah ini:
$jumlahfile = (Get-ChildItem).Length echo $jumlahfile Output dari perintah diatas adalah jumlah file yang ada pada suatu direktori.

Baca selengkapnya...

22 April 2009

Bahasa Scripting Windows PowerShell (Bagian 1)

Windows PowerShell menjawab kekurangan sistem operasi Windows terhadap manajemen sistem melalui console. Hal ini membuat Windows PowerShell cocok bagi para administrator Windows. Banyaknya fitur yang ditawarkan membuat Windows PowerShell juga cocok untuk administrator yang mengetahui UNIX, karena UNIX juga mempunyai bahasa scripting yang powerful seperti BASH. Meskipun begitu mungkin butuh waktu bagi kita untuk membiasakannya karena adanya perbedaan pada perintah, sintaks, maupun paradigma.

Menampilkan Daftar Perintah
Dengan perintah Get-Command kita bisa mendapatkan daftar semua cmdlet. Untuk mendapatkan deskripsi atau bantuan tentang cmdlet ini, kita bisa menambahkan parameter -h menjadi:
Get-Command -h
Penulisan huruf besar dan huruf kecil sama saja (case insesitive). Parameter pada tiap cmdlet konsisten dimulai dengan karakter - (minus). Meskipun tidak selalu begitu, tapi merupakan standar. Berikut ini contoh output tampilan di layar dari cmdlet Get-Command.










Hasil yang sama kita dapatkan dengan mengetikkan perintah:
Get-Help Get-Command
Atau bisa juga dengan gaya UNIX:
man Get-Command
Jumlah cmdlet yang ada mungkin ada ratusan, jadi melebihi satu layar. Kita bisa membatasi output yang ditampilkan per satu layar dan menunggu input dari user untuk menekan tombol seperti pada gambar diatas, dengan mengetikkan perintah Get-Command | more. Cara ini juga ada pada command shell tradisional Windows. Output pada kolom pertama adalah CommandType. Ada 7 CommandType:
  • Alias
  • Function
  • Filter
  • Cmdlet
  • ExternalScript
  • Application
  • Script
Jika kita mengetikkan Get-Command saja maka yang ditampilkan hanya yang CommandType-nya cmdlet saja. Untuk menampilkan semuanya ketikkan:
Get-Command *
Atau kita bisa membatasi output yang tampil hanya cmdlet yang namanya dimulai dengan karakter “a”.
Get-Command -CommandType Cmdlet -Name a*

Alias
Salah satu kemampuan Windows PowerShell adalah mereferensikan suatu perintah ke perintah atau cmdlet lain (aliasing). Misalnya jika kita ketik perintah dir atau ls akan menampilkan isi direktori. Memanggil perintah tersebut akan sama hasilnya dengan menjalankan cmdlet Get-ChildItem. Perintah dir atau ls merupakan alias dari cmdlet Get-ChildItem. Jadi jika kita mengetikkan dir atau ls sebenarnya kita menjalankan cmdlet Get-ChildItem. Contoh lain adalah perintah cls atau clear yang merupakan alias dari cmdlet Clear-Host. Hal ini sangat berguna bagi user yang familiar dengan perintah-perintah pada command shell tradisional Windows atau UNIX/Linux.
Untuk mendapatkan nama asli (cmdlet) dari sebuah alias kita bisa menggunakan cmdlet Get-Alias, misalnya:
Get-Alias dir
Bahkan kita bisa membuat alias kita sendiri dengan menggunakan cmdlet SetAlias. Misal kita membuat alias dengan nama liatdir dari cmdlet Get-ChildItem.
Set-Alias -Name liatdir -Value Get-ChildItem
Windows PowerShell juga menggunakan mekanisme alias untuk perintah-perintah umum seperti dir, cd, del, copy, dan lain-lain pada saat start-up, tapi tidak dapat diubah. Jika kita mengubah perintah tersebut dengan Set-Alias maka akan menampilkan error.
Set-Alias -Name dir -Value Get-Location



Jika kita ingin menghapus suatu alias bisa dengan menggunakan cmdlet Remove-Item.
Remove-Item alias:liatdir
Yang perlu diperhatikan adalah jika kita keluar dari Windows PowerShell, maka semua alias yang kita buat otomatis dihapus, artinya alias tersebut hanya berlaku untuk session yang bersangkutan saja. Jika kita membuka session baru, kita harus membuat ulang alias tersebut supaya dapat memakainya lagi.

Baca selengkapnya...

21 April 2009

Pengenalan Windows PowerShell

Melanjutkan bahasan sebelumnya tentang Windows PowerShell, kini kita sedikit masuk pada implementasi nyata dari Windows PowerShell. Saat ini mungkin tidak banyak yang menggunakan command shell terbaru Windows, Windows PowerShell. Mungkin juga belum banyak yang tahu kelebihan Windows PowerShell. Disini yang digunakan adalah Windows PowerShell 1.0 sebagai fokus kita. Sebelum membicarakan kelebihan Windows PowerShell, kita perlu mengetahui bahwa Windows PowerShell memiliki bahasa tersendiri dibanding menggunakan bahasa-bahasa yang sudah ada dengan alasan sebagai berikut.
  • Windows PowerShell memerlukan bahasa untuk me-manage obyek .NET.
  • Bahasa yang digunakan harus menyediakan lingkungan yang konsisten untuk menggunakan cmdlet.
  • Bahasa yang digunakan harus mendukung task yang kompleks tanpa membuat task yang sederhana menjadi rumit.
  • Bahasa yang digunakan harus konsisten dengan bahasa level tinggi yang digunakan pada pemrograman .NET seperti C#.
Langkah awal untuk menjalankan Windows PowerShell, masuk ke command prompt dan ketik powershell. Pada saat install Windows PowerShell, direktori install tersebut secara otomatis sudah ditambahkan ke variabel environment, jadi kita tidak perlu mengganti direktori dimana Windows PowerShell terinstall. Jika berhasil kita akan mendapatkan prompt yang seperti ini, PS C:\>. Dari sini kita bisa mengetikkan perintah-perintah yang valid.
Perintah yang digunakan pada command shell tradisional, masih bisa dipakai pada command shell Windows PowerShell, tapi dengan output tampilan yang berbeda. Misalnya jika ketikkan dir pada command shell akan tampil output sebagai berikut.








Tampilan yang berbeda ini jelas karena beda platform antara lingkungan native dan lingkungan .NET Framework. Oleh sebab itu tanpa kita sadari, pada Windows PowerShell kita bekerja dengan obyek .NET.
Pada saat kita menjalankan perintah dir, sebenarnya kita memanggil perintah lain yaitu Get-ChildItem. Windows PowerShell menggunakan mekanisme yang dinamakan “aliasing”, sehingga user dibolehkan mereferensikan suatu perintah dari perintah lain yang sudah ada. Jika kita mengetikkan perintah Get-ChildItem, kita akan mendapatkan output tampilan yang sama persis. Hal ini akan mempermudah bagi user yang sudah mengenal perintah-perintah console dari command shell tradisional.
Yang unik dari Windows PowerShell bahkan sebagian perintah UNIX juga didukung. Seperti ls, pwd, rm, mount dan lain sebagainya, yang tentunya juga sebagai alias ke suatu perintah asli dari Windows PowerShell. Kita dapat bereksperimen dengan berbagai macam perintah yang ada pada command shell tradisional atau bisa juga dengan perintah asli (cmdlet) Windows PowerShell. Untuk mengetahui apa saja cmdlet yang ada, kita bisa mengetikkan perintah Get-Command. Untuk mengetahui manual dari suatu cmdlet, kita bisa mengetikkan perintah Get-Help <cmdlet-name>. Contoh: Get-Help Get-Command.

Baca selengkapnya...

20 April 2009

Windows PowerShell, Command Shell Baru Windows

Microsoft mengeluarkan program terbaru buat command shell, Windows PowerShell. Sebenarnya tidak benar-benar baru, tapi mungkin banyak di antara kita yang masih tidak familiar dengan program yang satu ini. Mengapa harus pakai Windows PowerShell, pakai command prompt saja sudah cukup tuh. Mungkin sebagian orang berpikir begitu. Meskipun begitu tapi program yang satu ini wajib di install atau jadi persyaratan sebelum install SQL Server 2008. Jika Windows PowerShell tidak di install, instalasi SQL Server 2008 akan mogok nantinya.
Jika dilihat dari manualnya, Windows PowerShell merupakan command shell baru Windows yang di disain terutama untuk system administrator. Tidak seperti kebanyakan shell yang menerima input dan mengeluarkan output berupa teks, Windows PowerShell yang dibangun diatas .NET Common Language Runtime (CLR) dan .NET Framework, menerima input dan mengeluarkan output berupa obyek .NET.
Windows PowerShell memperkenalkan konsep baru yang dinamakan cmdlet (baca: “command-let”), merupakan tool command-line yang sederhana dan mempunyai fungsi tunggal yang dibangun didalam shell. Pada tradisional shell perintah yang di eksekusi merupakan program executable seperti ipconfig.exe, attraib.exe, dan lain-lain. Pada Windows PowerShell, cmdlet dapat kita kenali dari format namanya, yang merupakan gabungan kata kerja dan kata benda dipisahkan oleh tanda minus (-), misalnya Get-Help, Start-Service. Kebanyakan cmdlet mempunyai fungsi sederhana dan di disain untuk digunakan sebagai kombinasi dengan cmdlet lain. Tiap cmdlet mempunyai manual yang bisa diakses dengan mengetikkan:
get-help <cmdlet-name> -detailed

Persyaratan minimum yang dibutuhkan sebelum install Windows PowerShell:
  • Windows XP Service Pack 2, Windows 2003 Service Pack 1 atau Windows yang lebih baru. Pada Windows 7 sudah terinstall secara default.
  • Microsoft .NET Framework 2.0
Untuk install Windows PowerShell, kita harus punya file instalasi terlebih dahulu, kemudian tinggal jalankan dan ikuti petunjuknya. Atau juga bisa silent install dengan cara mengetikkan:
<PowerShell-exe-file-name> /quiet

Baca selengkapnya...

18 April 2009

Pengecekan Penekanan Tombol Dalam Perulangan

Permasalahan klasik tapi cukup banyak ditanyakan orang, terutama yang membuat aplikasi console. Kalau kita membuat aplikasi yang memiliki GUI, memakai form atau kontrol dengan event yang dipunyai tentu tidak jadi masalah. Pengecekan penekanan tombol bisa dilakukan dari event OnKeyPress, OnKeyDown atau OnKeyUp dari sebuah komponen. Tapi bagaimana kita melakukan hal tersebut pada aplikasi console?
Kita bisa melakukannya dengan fungsi GetKeyState() pada unit Windows, digunakan untuk mendapatkan status dari sebuah virtual key. Fungsi ini mempunyai satu parameter dengan tipe integer yang merupakan virtual key yang diinginkan. Hasil kembali dari fungsi ini merupakan status dari virtual key yang di inputkan, dan tipenya integer. Jika bit ke-8 bernilai 1 maka tombol tersebut ditekan dan sebaliknya.
uses Windows;

while True do
begin
  // proses sesuatu…
  Application.ProcessMessages;
  if GetKeyState(VK_ESCAPE) and 128 = 128 then Break;
end;
Bila pengecekan yang diinginkan merupakan kombinasi dari beberapa tombol, misal Ctrl+1, maka pemanggilan fungsi GetKeyState() harus dua kali.
if (GetKeyState(VK_CONTROL) and 128 = 128) and (GetKeyState(Ord('1')) and 128 = 128) then
  Break;

Baca selengkapnya...

17 April 2009

Query Rekursif Common Table Expression (CTE)

Penggunaan CTE seperti pada posting sebelumnya mungkin tidak terlalu memberikan keuntungan yang signifikan pada beberapa kasus. Tapi CTE dapat mereferensikan ke diri sendiri sehingga dapat membuat query rekursif. Hal ini sangat memberikan keuntungan. Sebuah query dapat dikatakan query rekursif jika query tersebut mereferensikan CTE rekursif. Hasil query merupakan data hirarki, contohnya menampilkan organisasi yang mempunyai departemen dan sub departemen.
CTE rekursif mempunyai tiga elemen:
  • Pemanggilan pertama dari CTE rekursif terdiri dari satu atau lebih <CTE_query_definition> yang digabung dengan menggunakan operator UNION ALL, UNION, EXCEPT atau INTERSECT. Query ini disebut sebagai “anchor members” yang harus diletakkan sebelum “recursive members”.
  • Pemanggilan rekursif yang terdiri dari satu atau lebih <CTE_query_definition> yang digabung dengan menggunakan operator UNION ALL dan mereferensikan ke diri sendiri. Query ini disebut sebagai “recursive members”.
  • Pengecekan terminasi query yang dilakukan secara implisit. Proses rekursif akan berhenti jika tidak ada baris data yang dikembalikan dari pemanggilan sebelumnya.
Perlu diperhatikan bahwa CTE rekursif yang tidak benar dapat mengakibatkan perulangan yang tidak berakhir. Untuk membatasi level rekursif dapat menggunakan pilihan MAXRECURSION dengan nilai antara 0 sampai 32767 (0: tidak ada batasan) pada klausa OPTION pada operasi SELECT, INSERT, UPDATE atau DELETE. Contoh dibawah ini mencari semua kemungkinan jalur yang ada antara dua kota. Tabel satu berisi nama-nama kota, dan tabel lainnya berisi jalan yang mungkin dilewati antar kota.
DECLARE @Kota TABLE (Kode int, Nama varchar(MAX));
DECLARE @Jalan TABLE (KodeAsal int, KodeTujuan int);
INSERT INTO @Kota VALUES
  (1, 'Surabaya'), (2, 'Malang'),
  (3, 'Semarang'), (4, 'Yogyakarta'),
  (5, 'Jakarta'), (6, 'Tangerang');
INSERT INTO @Jalan VALUES
  (1, 2), (1, 3), (2, 1), (2, 4), (3, 1),
  (3, 4), (3, 5), (4, 2), (4, 3), (4, 6),
  (5, 3), (5, 6), (6, 5);
WITH JalurCTE (Kode, Jalur, NamaAsal, NamaTujuan, Jarak, KodeTujuan)
AS
(
  SELECT
      CAST(Kode AS varchar(MAX)),
      CAST(Nama AS varchar(MAX)),
      CAST(Nama AS varchar(MAX)),
      CAST(NULL AS varchar(MAX)),
      CAST(0 AS int),
      Kode
    FROM @Kota
  UNION ALL
  SELECT
      c.Kode + '-' + CAST(j.KodeTujuan AS varchar(MAX)),
      c.Jalur + '-' + k.Nama,
      c.NamaAsal,
      k.Nama,
      c.Jarak + 1,
      j.KodeTujuan
    FROM JalurCTE AS c
    INNER JOIN @Jalan AS j ON j.KodeAsal = c.KodeTujuan
    INNER JOIN @Kota AS k ON k.Kode = j.KodeTujuan
    WHERE c.Kode NOT LIKE '%' + CAST(j.KodeTujuan AS VARCHAR(MAX)) + '%'
)
SELECT NamaAsal, NamaTujuan, Jalur, Jarak
FROM JalurCTE WHERE Jarak > 0
ORDER BY NamaAsal, NamaTujuan, Jarak
OPTION (MAXRECURSION 0)

Kita bisa memodifikasi query SELECT untuk menampilkan hasil pada baris paling bawah supaya bisa menampilkan jalur terpendek (shortest path) antara dua kota.
SELECT j1.NamaAsal, j1.NamaTujuan, j1.Jalur, j1.Jarak
FROM JalurCTE AS j1
INNER JOIN (
  SELECT NamaAsal, NamaTujuan, MIN(Jarak) AS Jarak
    FROM JalurCTE WHERE Jarak > 0 GROUP BY NamaAsal, NamaTujuan) AS j2 ON
j2.NamaAsal = j1.NamaAsal AND j2.NamaTujuan = j1.NamaTujuan AND j2.Jarak = j1.Jarak
ORDER BY NamaAsal, NamaTujuan, Jarak

Baca selengkapnya...

16 April 2009

Menggunakan Common Table Expression (CTE)

Common Table Expression (CTE) merupakan fitur baru SQL Server yang dimulai dari SQL Server 2005. Bagi yang pernah menggunakan variabel bertipe TABLE, mungkin ada kemiripan diantara keduanya. Menurut dokumentasi, CTE dapat digambarkan sebagai hasil query sementara yang ada pada lingkup eksekusi operasi SELECT, INSERT, UPDATE, DELETE, atau CREATE VIEW. CTE mirip dengan tabel turunan yang tidak disimpan sebagai obyek. Tapi tidak seperti tabel turunan, CTE dapat di referensikan ke diri sendiri dan dapat di referensikan beberapa kali pada query yang sama.
Menggunakan CTE memiliki beberapa keuntungan yaitu lebih mudah dibaca dan memudahkan pengaturan pada query yang kompleks. Query dapat dipecah menjadi beberapa query yang lebih sederhana. CTE dapat digunakan pada procedure, fungsi, trigger atau view. Cara penggunaanya:
WITH <expression_name> [<column_name [,...n]>]
AS
(<CTE_query_definition>)
Daftar nama kolom bisa tidak diberikan hanya jika pada definisi query terdapat nama kolom yang masing-masing berbeda. Untuk menjalankan CTE sama seperti SELECT dari sebuah tabel.
SELECT <column_list> FROM expression_name
Dibawah ini adalah contoh penggunaan CTE. Terdapat sebuah tabel yang berisi daftar departemen dan pekerjaan. Sebuah departemen/pekerjaan bisa memiliki sub departemen/pekerjaan. Ini hanya sebagai contoh cara penggunaan saja. Pada penggunaan query yang kompleks akan terlihat keuntungan dari penggunaan CTE.
DECLARE @Job TABLE (
  JobID int PRIMARY KEY,
  JobName varchar(20) NOT NULL,
  SubJobID int NULL);
INSERT INTO @Job VALUES
  (1, 'Keuangan', NULL),
  (2, 'HRD', NULL),
  (3, 'Administrasi', NULL),
  (4, 'Accounting', 1),
  (5, 'IT', 1),
  (6, 'Humas', 2),
  (7, 'EDP', 5),
  (8, 'Programmer', 5);
WITH JobCTE
AS
(
  SELECT * FROM @Job
)
SELECT mst.JobID, mst.JobName, sub.JobName AS SubJobName
FROM JobCTE AS mst
LEFT JOIN JobCTE AS sub ON sub.JobID = mst.SubJobID

Baca selengkapnya...

15 April 2009

Kompresi File dengan WinRAR

Kompresi dengan ZLib seperti pada posting sebelumnya cukup baik. Tapi jika dibandingkan dengan kompresi menggunakan WinRAR menjadi format .rar bisa menjadi setengah dari ukuran file dari kompresi dengan ZLib. Berdasarkan percobaan yang aku lakukan, file aplikasi yang dikompres dengan ZLib mempunyai ukuran 6MB lebih, kemudian jika dikompres dengan WinRAR format .rar menjadi sekitar 3.5MB, hampir setengahnya. Atau contoh lain, aplikasi dengan berbagai komponen pendukung jadi satu program executable 11MB. Setelah dipecah dengan komponen pendukung atau dengan teknik packaging menjadi 1.23MB. Setelah dipecah dengan komponen pendukung dan di kompres dengan ZLib menjadi 402KB. Setelah dipecah dengan komponen pendukung dan di kompres dengan rar menjadi 254KB!
WinRAR memang software komersial (shareware), tapi bisa jadi alternatif bagi yang ingin ukuran file sekecil-kecilnya untuk distribusi melalui internet. Dalam WinRAR terdapat tool yang dapat digunakan untuk manajemen file melalui console. File yang bernama “rar.exe” terdapat pada direktori instalasi WinRAR dan ini yang bisa kita gunakan, terutama untuk proses dekompres file. Dengan tool ini, dapat kita manfaatkan sehingga pada saat user download file, tidak perlu dekompres file secara manual
Dari aplikasi Delphi, kita bisa menjalankan perintah console dengan menggunakan fungsi dari unit ShellAPI. Berikut adalah contoh penggunaan tool “rar.exe”. Terdapat juga manual untuk tool ini untuk referensi lebih lanjut di direktori instalasi WinRAR.

Kompres semua file pada direktori aktif dan simpan dengan nama file “tes.rar”.
rar a tes.rar

Dekompres file “tes.rar” ke direktori tes.
rar e tes.rar tes\

Dekompres file “tes.rar” ke direktori tes, tumpuki file jika sudah ada.
rar e -o+ tes.rar tes\

Baca selengkapnya...

14 April 2009

Kompresi File

Distribusi file melalui internet seharusnya sekecil mungkin. Dengan begitu waktu untuk upload dan download akan semakin cepat. Dengan begitu akan menguntungkan kedua belah pihak, dari pengembang aplikasi maupun client. Pada beberapa saat yang lalu pernah dijelaskan tentang Borland Package Library (BPL). Aplikasi yang berisi unit-unit dan logika yang kita buat dipisahkan dengan komponen yang dipakai, yang hasil akhirnya akan mengurangi ukuran file aplikasi secara signifikan.
Tidak berheti disitu saja, masih ada cara lain lagi untuk mengurangi ukuran file yang di upload ke internet. Salah satu cara adalah dengan kompresi file. Delphi menyediakan fungsi untuk kompresi data file pada unit ZLib. ZLib merupakan library untuk keperluan kompresi dan dapat dipakai dan di download secara gratis tanpa membayar royalti. Tersedia juga source code dan dapat di download di situs http://www.zlib.net.
Dua class utama pada unit ZLib adalah TCompressionStream dan TDecompressionStream. TCompressionStream digunakan untuk kompres data. Data yang dikompres ditulis ke stream yang nantinya akan dilewatkan ke constructor TCompressionStream. Kita dapat menentukan level kompresi pada saat membuat obyek stream. Level kompresi yang disediakan adalah clNone, clFastest, clDefault, dan clMax. Untuk dekompres data kita menggunakan class TDecompressionStream.
Skrip dibawah ini untuk kompres dan dekompres file. Tidak hanya satu file saja, tapi bisa lebih dari satu. Variabel yang menyimpan nama-nama file bertipe TStrings. File kompresi ini berisi jumlah file, nama file asal, panjang nama file asal, ukuran file dan isi dari file asal.
uses Classes, SysUtils, ZLib;

procedure CompressFiles(aFiles: TStrings; const aOutFileName: string; aCompressionLevel: TCompressionLevel);
var
  infile, outfile, tmpfile: TFileStream;
  compr: TCompressionStream;
  i, j: Integer;
  s: string;
begin
  outfile := TFileStream.Create(aOutFileName, fmCreate);
  try
    j := aFiles.Count; // jumlah file
    outfile.Write(j, SizeOf(j));
    for i := 0 to aFiles.Count - 1 do
    begin
      infile := TFileStream.Create(aFiles[i], fmOpenRead);
      try
        s := ExtractFilename(aFiles[i]); // nama file asal
        j := Length(s); // panjang nama file asal
        outfile.Write(j, SizeOf(j));
        outfile.Write(s[1], j);
        j := infile.Size; // ukuran file
        outfile.Write(j, SizeOf(j));
        if j = 0 then Continue;
        tmpfile := TFileStream.Create('tmp', fmCreate);
        compr := TCompressionStream.Create(aCompressionLevel, tmpfile);
        try
          compr.CopyFrom(infile, j);
        finally
          compr.Free;
          tmpfile.Free;
        end;
        tmpfile := TFileStream.Create('tmp', fmOpenRead); // tambahkan file terkopmpresi ke file tujuan
        try
          outfile.CopyFrom(tmpFile, 0);
        finally
          tmpfile.Free;
        end;
      finally
        infile.Free;
      end;
    end;
  finally
    outfile.Free;
    DeleteFile('tmp');
  end;
end;

procedure DecompressFiles(const aFileName, aDestDirectory: string);
var
  s: string;
  decompr: TDecompressionStream;
  infile, outfile: TFileStream;
  i, j, count: Integer;
begin
  infile := TFileStream.Create(aFileName, fmOpenRead);
  try
    infile.Read(count, SizeOf(count)); // jumlah file
    for i := 1 to count do
    begin
      infile.Read(j, SizeOf(j)); // panjang nama file asal
      SetLength(s, j);
      infile.Read(s[1], j); // nama file asal
      infile.Read(j, SizeOf(j)); // ukuran file
      s := aDestDirectory + '\' + s;
      outfile := TFileStream.Create(s, fmCreate);
      decompr := TDecompressionStream.Create(infile);
      try
        if j = 0 then Continue; // antisipasi jika ukuran file = 0
        outfile.CopyFrom(decompr, j);
      finally
        outfile.Free;
        decompr.Free;
      end;
    end;
  finally
    infile.Free;
  end;
end;

Baca selengkapnya...

13 April 2009

Restore Database

Backup data yang menghasilkan output file, suatu saat harus dapat digunakan untuk proses restore data suatu saat jika kita membutuhkannya. Ada beberapa cara untuk restore data, tapi yang dibahas disini hanya restore data menggunakan tool “mysql.exe”. Tool ini digunakan untuk menjalankan perintah SQL, seperti operasi SELECT, INSERT, UPDATE, DELETE. Tapi bisa juga menjalankan dari file yang diinputkan. Tool ini tersedia jika kita install MySQL dan tersedia pada direktori <mysql_install_dir>\bin. Ada banyak options sebagai parameter, dan hanya beberapa yang sering aku pakai.
  • --host=<host_name>, -h <host_name>
  • Connect ke server MySQL <host_name>.
  • --user=<user_name>, -u <user_name>
  • Nama user MySQL yang digunakan untuk koneksi.
  • --password=<password>, -p<password>
  • Password MySQL yang digunakan untuk koneksi. Perhatikan jika menggunakan sintax –p<password> tidak ada spasi antara –p dan password.
  • --verbose, -v
  • Cetak informasi tentang apa yang dilakukan program.
  • --execute=<statement>, -e <statement>
  • Menjalankan perintah SQL dan keluar program.
Ada beberapa cara yang bisa dipakai untuk restore data menggunakan mysql.exe:
mysql --user=root < “backup.sql”
mysql --user=root db_name < “backup.sql”
mysql --user=root --execute=”source ‘backup.sql’”

Jika dalam perintah SQL terdapat perintah yang berhubungan dengan penambahan user atau privileges, maka perlu menjalankan perintah FLUSH PRIVILEGES setelah proses restore data selesai dilakukan, supaya user yang ditambahkan atau hak akses yang diberikan bisa berpengaruh. Untuk menjalankan perintah FLUSH PRIVILEGES gunakan perintah: mysql --user=root --execute “FLUSH PRIVILEGES”

Baca selengkapnya...

10 April 2009

mysqldump - Tool untuk Backup Database MySQL

MySQL mempunyai tool untuk backup program yaitu mysqldump. mysqldump adalah program pada sisi client yang dapat digunakan untuk backup beberapa database atau transfer data ke server lain. Tool ini tersedia jika kita install MySQL dan terdapat pada direktori <mysql_install_dir>\bin. Output dari mysqldump adalah file yang berisi perintah-perintah SQL yang dapat dibaca dengan editor teks seperti wordpad. File output ini dapat dijalankan untuk membuat database, tabel, atau melakukan operasi pada database atau tabel. Tool ini bisa digunakan untuk engine MyISAM atau InnoDB dan bisa dijalankan tanpa menghentikan instace MySQL. Menurut manual MySQL, ada tiga cara umum untuk menjalankan mysqldump:
mysqldump [options] db_name [tables]
mysqldump [options] --databases db_name1 [db_name2 db_name3...]
mysqldump [options] --all-databases

Parameter [options] punya banyak variasi pilihan yang bisa digunakan sesuai dengan kebutuhan. Berikut ini sebagian parameter yang sering atau pernah aku pakai untuk backup database.
  • --host=<host_name>, -h <host_name>
  • Backup data dari server MySQL <host_name>. Defaultnya adalah localhost.
  • --user=<user_name>, -u <user_name>
  • Nama user MySQL yang digunakan untuk koneksi.
  • --password=<password>, -p<password>
  • Password MySQL yang digunakan untuk koneksi. Perhatikan jika menggunakan sintax –p<password> tidak ada spasi antara –p dan password.
  • --verbose, -v
  • Cetak informasi tentang apa yang dilakukan program.
  • --complete-insert, -c
  • Perintah INSERT menyertakan nama kolom. Cara aman pada pengembangan database yang belum final atau masih bisa menambahkan field pada tabel.
  • --skip-extended-insert
  • Jika menggunakan parameter ini, perintah INSERT di generate per baris data. Contohnya:
    INSERT INTO tbl1 VALUES (1, ‘a’);
    INSERT INTO tbl1 VALUES (2, ‘b’);
    INSERT INTO tbl1 VALUES (3, ‘c’);
    Jika parameter ini tidak digunakan, yang merupakan pilihan default, perintah INSERT di generate per tabel. Contoh:
    INSERT INTO tbl1 VALUES (1, ‘a’), (2, ‘b’), (3, ‘c’);
    Menggunakan pilihan ini menurutku lebih aman, karena berdasar pengalaman, jika data sudah ada atau terjadi kesalahan, baris perintah INSERT yang berikutnya masih dijalankan. Tapi jika tidak menggunakan pilihan ini dan data sudah ada atau terjadi kesalahan, data berikutnya tidak akan masuk.
  • --single-transaction
  • Hanya berguna untuk tabel transactional seperti InnoDB. Sebelum melakukan backup data, akan diberikan perintah BEGIN. Dengan begini akan mendapatkan konsistensi dari database yang di backup tanpa melakukan blocking pada aplikasi apapun.
  • --routines, -R
  • Backup function dan procedure. Minimum membutuhkan MySQL 5.1.2.
  • --no-data, -d
  • Baris data tidak di backup, hanya struktur saja.
  • --no-create-info, -t
  • Struktur tabel tidak di backup, hanya data saja.
  • --result-file=<nama_file>, -r <nama_file>
  • Menghasilkan output file sesuai <nama_file> yang diinputkan.
  • --ignore-table=<nama_database.nama_tabel>
  • Tidak melakukan backup pada tabel yang diinputkan. Berguna misalnya jika melakukan backup pada database mysql tapi hanya tabel user saja.
  • --xml
  • Menghasilkan output file format xml.
Penggunaan yang umum dari mysqldump mungkin adalah melakukan backup terhadap seluruh database yang ada:
mysqldump --user=root --all-databases --result-file=”backup.sql”

Backup data saja:
mysqldump --user=root db_name --no-create-info --result-file=”backup.sql”

Backup struktur saja:
mysqldump --user=root db_name --no-data --result-file=”backup.sql”

Backup database tertentu beserta database MySQL tabel user saja, dan tidak tabel lain:
mysqldump --user=root --databases db_name mysql --result-file="backup.sql" --ignore-table="mysql.columns_priv" --ignore-table="mysql.db" --ignore-table="mysql.func" --ignore-table="mysql.host" --ignore-table="mysql.plugin" --ignore-table="mysql.proc" --ignore-table="mysql.proc_priv" --ignore-table="mysql.servers" --ignore-table="mysql.tables_priv" --ignore-table="mysql.general_log" --ignore-table="mysql.help_category" --ignore-table="mysql.help_keyword" --ignore-table="mysql.help_relation" --ignore-table="mysql.help_topic" --ignore-table="mysql.ndb_binlog_index" --ignore-table="mysql.procs_priv" --ignore-table="mysql.slow_log" --ignore-table="mysql.time_zone" --ignore-table="mysql.time_zone_leap_second" --ignore-table="mysql.time_zone_name" --ignore-table="mysql.time_zone_transition" --ignore-table="mysql.time_zone_transition_type"

Baca selengkapnya...

09 April 2009

Penggunaan File Resource pada Delphi

Setiap aplikasi yang kita buat biasanya menggunakan resource. Resource merupakan elemen pendukung program seperti bitmap, icon, cursor, dan lain-lain. Ada kalanya kita juga ingin menambahkan file tertentu pada file aplikasi kita. Misalnya file audio yang akan dijalankan pada event tertentu atau file skrip yang berisi kumpulan perintah SQL untuk membuat database dan isinya. Kita tidak ingin memisahkan file-file pendukung tersebut, tapi dijadikan satu dengan file aplikasi kita. Kita akan membuat file resource yang berisi file-file yang diinginkan dengan tool dari Delphi “brcc32.exe” (Borland Resource Compiler). Tool ini digunakan untuk compile file resource. Untuk membuat file resource, ikuti langkah-langkah berikut.

Membuat file skrip resource (.rc).
Buat file dengan ekstensi .rc yang merupakan deskripsi dari file-file yang disertakan. File ini bisa dibuat dari editor teks seperti notepad. Isi dari file ini merupakan daftar file resource yang dibuat per baris dengan format:
ResName ResType ResFileName
ResName merupakan nama yang unik untuk tiap file resource, ResType merupakan tipe resource dan ResFileName adalah nama file. Contohnya:
Clock WAVE “c:\avi\clock.wav”
Cool AVI “c:\avi\cool.avi”
CreateDB RCDATA “c:\skrip\createdb.sql”
Terdapat banyak tipe resource termasuk icon, bitmap, audio, dan lain-lain. Tipe RCDATA tipe data umum yang merupakan tipe data mentah, salah satunya adalah data binary atau file exe.

Membuat file resource (.res)
Supaya dapat digunakan pada aplikasi, file .rc tersebut harus di compile menjadi file .res dengan menggunakan tool “brcc32.exe”. File ini terletak di direktori Delphi\bin. Misalnya file skrip resource tadi disimpan dengan nama “appres.rc”. Buka command prompt dan ketikkan perintah:
brcc32 appres.rc
Jika berhasil akan membuat file “appres.res” di direktori yang sama dengan direktori tempat file “appres.rc” berada.

Gunakan file resource yang telah di compile pada aplikasi.
Setelah file resource terbuat, tinggal menambahkan pada unit kita. Caranya adalah dengan menambahkan compiler directive {$R} dibawah baris {$R *.dfm}.
{$R *.dfm}
{$R appres.res}
Baris pertama {$R *.dfm} sudah ada pada program dan jangan sampai terhapus, tinggal menambahkan baris dua, {$R appres.res}. Setelah itu file resource siap dipakai.
Untuk menampilkan animasi pada file “cool.avi”, kita membutuhkan komponen TAnimate pada tab Win32 (misal nama: Animate1), dan salin kode berikut ini untuk menjalankan animasi.
Animate1.ResName := 'Cool';
Animate1.ResHandle := HInstance;
Animate1.Active := True;
Untuk memainkan file .wav yang ada pada file resource, salin kode berikut ini.
uses MMSystem;

var
  hFind, hRes: THandle;
  Lagu: PChar;
begin
  hFind := FindResource(HInstance, 'Clock', 'WAVE');
  if hFind <> 0 then
  begin
    hRes := LoadResource(HInstance, hFind);
    if hRes <> 0 then
    begin
      Lagu := LockResource(hRes);
      if Assigned(Lagu) then sndPlaySound(Lagu, SND_ASYNC or SND_MEMORY);
      UnlockResource(hRes);
    end;
    FreeResource(hFind);
  end;
end;
Terakhir untuk menjalankan skrip file yang ada pada file resource, kita perlu mengektrak file skrip tersebut ke suatu direktori dan kemudian memproses file tersebut.
var
  filename: string;
  rStream: TResourceStream;
  fStream: TFileStream;
begin
  filename := 'createdb.sql';
  rStream := TResourceStream.Create(HInstance, 'CreateDB', RT_RCDATA);
  try
    fStream := TFileStream.Create(filename, fmCreate);
    try
      fStream.CopyFrom(rStream, 0);
    finally
      fStream.Free;
    end;
  finally
    rStream.Free;
  end;
  …
end;
File apapun dapat disimpan pada file resource dengan tipe RCDATA. File .exe, file database, dan lain-lain. Tidak ada batasan tipe file apa saja bisa masuk.

Baca selengkapnya...

08 April 2009

Menghapus File Temporary Internet Cache

Jika kita download file dari internet, apa yang kita download akan disimpan di suatu direktori atau istilahnya “cache”. Sebelum proses download, akan diperiksa dulu apakah file sudah ada di direktori cache. Jika sudah ada, akan langsung disalin dari direktori cache tersebut, tidak download ulang dari internet. Sebagian orang mungkin tidak menginginkan file disalin dari direktori cache, tapi bagaimanapun juga selalu menyalin dari situs web yang telah ditentukan.
Jika demikian yang kita inginkan, kita harus menghapus file yang sudah kita download dari direktori cache setelah proses download berakhir. Dengan menghapus file pada direktori cache, setiap proses download selalu dari situs web.
uses WinInet;

procedure ClearCache;
var
  lpEntryInfo: PInternetCacheEntryInfo;
  hCacheDir, dwEntrySize: LongWord;
begin
  dwEntrySize := 0;
  FindFirstUrlCacheEntry(nil, TInternetCacheEntryInfo(nil^), dwEntrySize);
  GetMem(lpEntryInfo, dwEntrySize);
  if dwEntrySize > 0 then lpEntryInfo^.dwStructSize := dwEntrySize;
  hCacheDir := FindFirstUrlCacheEntry(nil, lpEntryInfo^, dwEntrySize);
  if hCacheDir <> 0 then
  begin
    repeat
DeleteUrlCacheEntry(lpEntryInfo^.lpszSourceUrlName);
      FreeMem(lpEntryInfo, dwEntrySize);
      dwEntrySize := 0;
      FindNextUrlCacheEntry(hCacheDir, TInternetCacheEntryInfo(nil^), dwEntrySize);
      GetMem(lpEntryInfo, dwEntrySize);
      if dwEntrySize > 0 then lpEntryInfo^.dwStructSize := dwEntrySize;
    until not FindNextUrlCacheEntry(hCacheDir, lpEntryInfo^, dwEntrySize);
  end;
  FreeMem(lpEntryInfo, dwEntrySize);
  FindCloseUrlCache(hCacheDir);
end;

Baca selengkapnya...

07 April 2009

Download dari Internet dengan Progress Bar

Kita membuat aplikasi yang kompleks dari awal, dengan banyak client dan beberapa client jauh dari kita. Pada saat ada update program, kita ingin client bisa download update program dari suatu situs web yang sudah kita tentukan. Banyak juga pengembang software yang memanfaatkan internet atau web sebagai sarana untuk memberikan update bagi client. Dengan begini kita tidak perlu repot harus datang ke banyak tempat hanya untuk melakukan update program.
Berikut ini adalah cara download dari internet dengan menggunakan interface IBindStatusCallback dari unit UrlMon. Interface ini digunakan untuk proses binding secara asynchronous.
uses SysUtils, Windows, UrlMon, ActiveX;

type
  TBindStatusCallback = class(TObject, IBindStatusCallback)
  protected
    FRefCount: Integer;
    function QueryInterface(const IID: TGUID; out Obj): Integer; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
  public
    function OnStartBinding(dwReserved: DWORD; pib: IBinding): HRESULT; stdcall;
    function GetPriority(out nPriority): HRESULT; stdcall;
    function OnLowResource(reserved: DWORD): HRESULT; stdcall;
    function OnProgress(ulProgress, ulProgressMax, ulStatusCode: ULONG;
      szStatusText: LPCWSTR): HRESULT; stdcall;
    function OnStopBinding(hresult: HRESULT; szError: LPCWSTR): HRESULT; stdcall;
    function GetBindInfo(out grfBINDF: DWORD; var bindinfo: TBindInfo): HRESULT; stdcall;
    function OnDataAvailable(grfBSCF: DWORD; dwSize: DWORD; formatetc: PFormatEtc;
      stgmed: PStgMedium): HRESULT; stdcall;
    function OnObjectAvailable(const iid: TGUID; punk: IUnknown): HRESULT; stdcall;
  end;

function TBindStatusCallback.QueryInterface(const IID: TGUID;
  out Obj): Integer;
begin
  if GetInterface(IID, Obj) then Result := S_OK
  else Result := E_NOINTERFACE;
end;

function TBindStatusCallback._AddRef: Integer;
begin
  Inc(FRefCount);
  Result := FRefCount;
end;

function TBindStatusCallback._Release: Integer;
begin
  Dec(FRefCount);
  Result := FRefCount;
end;

function TBindStatusCallback.GetBindInfo(out grfBINDF: DWORD;
  var bindinfo: TBindInfo): HRESULT;
begin
  Result := E_NOTIMPL;
end;

function TBindStatusCallback.GetPriority(out nPriority): HRESULT;
begin
  Result := E_NOTIMPL;
end;

function TBindStatusCallback.OnDataAvailable(grfBSCF, dwSize: DWORD;
  formatetc: PFormatEtc; stgmed: PStgMedium): HRESULT;
begin
  Result := E_NOTIMPL;
end;

function TBindStatusCallback.OnLowResource(reserved: DWORD): HRESULT;
begin
  Result := E_NOTIMPL;
end;

function TBindStatusCallback.OnObjectAvailable(const iid: TGUID;
  punk: IUnknown): HRESULT;
begin
  Result := E_NOTIMPL;
end;

function TBindStatusCallback.OnStartBinding(dwReserved: DWORD;
  pib: IBinding): HRESULT;
begin
  Result := E_NOTIMPL;
end;

function TBindStatusCallback.OnStopBinding(hresult: HRESULT;
  szError: LPCWSTR): HRESULT;
begin
  Result := E_NOTIMPL;
end;

function TBindStatusCallback.OnProgress(ulProgress, ulProgressMax,
  ulStatusCode: ULONG; szStatusText: LPCWSTR): HRESULT;
begin
  Result := OnDownloadProgress(ulProgress, ulProgressMax, ulStatusCode, szStatusText);
end;

function OnDownloadProgress(ulProgress, ulProgressMax,
  ulStatusCode: ULONG; szStatusText: LPCWSTR): HRESULT;
begin
  ProgressBar1.Position := ulProgress;
  ProgressBar1.Max := ulProgressMax;
end;

Contoh pemakaiannya:
var
  bsc: TBindStatusCallback;
begin
  bsc := TBindStatusCallback.Create;
  URLDownloadToFile(nil, PChar(‘http://www.google.com/intl/de/images/home_title.gif’), PChar(‘C:\ home_title.gif’), 0, bsc)
end;

Baca selengkapnya...

06 April 2009

Menampilkan Browse Dialog

Delphi mempunyai beberapa cara untuk menampilkan direktori dari komputer. Dan yang dibahas disini adalah menampilkan dialog untuk browse direktori menggunakan fungsi dari Windows API yaitu SHBrowseForFolder. Disini yang penting adalah parameter dengan tipe TBrowseInfo dari fungsi SHBrowseForFolder. Tiga elemen utama dari TBrowseInfo adalah lpszTitle, ulFlags dan lpfn. lpszTitle yang bertipe Pchar akan ditampilkan diatas treeview yang menampilkan direktori. Untuk menampilkan direktori saja, parameter ulFlags diisi dengan BIF_RETURNONLYFSDIRS. Parameter lpfn adalah pointer ke fungsi callback. Fungsi ini bisa digunakan untuk menampilkan parameter lpszTitle dan menampilkan dialog di tengah layar, karena secara default posisi dialog adalah random.
function OpenBrowseDialogCallBack(aWnd: HWND; aMsg: UINT; aParam, aData: LPARAM): Integer stdcall;
var
  workarea, rect: TRect;
  dlgpoint: TPoint;
begin
  if aMsg = BFFM_INITIALIZED then
  begin
    workarea := Screen.WorkAreaRect;
    GetWindowRect(aWnd, rect);
    dlgpoint.X := ((workarea.Right - workarea.Left) div 2) - ((rect.Right - rect.Left) div 2);
    dlgpoint.Y := ((workarea.Bottom - workarea.Top) div 2) - ((rect.Bottom - rect.Top) div 2);
    MoveWindow(aWnd, dlgpoint.X, dlgpoint.Y, Rect.Right - Rect.Left, Rect.Bottom - Rect.Top, True);
    if aData <> 0 then
      SendMessage(aWnd, BFFM_SETSELECTION, Integer(True), aData);
  end;
  Result := 0;
end;

function OpenBrowseDialog(const aTitle: string; const aFlag: Integer): string;
var
  pitemid: PItemIDList;
  browseinfo: TBrowseInfo;
  displayname, temppath: array [0..MAX_PATH] of Char;
begin
  Result := '';
  FillChar(browseinfo, SizeOf(TBrowseInfo), #0);
  with browseinfo do
  begin
    hwndOwner := Application.Handle;
    pszDisplayName := @displayname;
    lpszTitle := PChar(aTitle);
    ulFlags := aFlag;
    lpfn := OpenBrowseDialogCallBack;
  end;
  pitemid := SHBrowseForFolder(browseinfo);
  if pitemid <> nil then
  begin
    SHGetPathFromIDList(pitemid, temppath);
    Result := temppath;
    GlobalFreePtr(pitemid);
  end;
end;
Contoh penggunaannya:
var
  dir: string;
begin
  dir := OpenBrowseDialog('Pilih direktori', BIF_RETURNONLYFSDIRS);
  // …
end;

Baca selengkapnya...

05 April 2009

Mengembalikan Kontrol Turunan (Inherited) pada Keadaan Semula

Delphi mendukung penuh pemrograman berorientasi obyek (Object Oriented Programming/OOP). Dengan OOP hidup bisa jauh lebih mudah. Salah satu inti dari OOP adalah inheritance, yang memungkinan suatu obyek diturunkan menjadi obyek baru. Obyek yang diturunkan mewarisi semua method dan properti yang dipunyai obyek yang menurunkan. Meski begitu banyak yang belum menyadari ini atau banyak pula yang enggan memakai fitur ini dengan alasan susah, rumit, malas belajar dan lain sebagainya. Padahal dengan mengetahui atau bahkan menguasainya, pengembangan aplikasi, terutama seiring perkembangan aplikasi yang semakin kompleks, penggunaan OOP bisa sangat membantu kita.
Sifat inheritance pada Delphi berlaku pula pada form (Visual Form Inheritance). Jika kita mempunyai form dengan nama Form1 yang mempunyai kontrol Button1, Edit1, Label1 dan mempunyai form lain dengan nama Form2 yang diturunkan dari Form1, maka pada Form2 otomatis juga akan terdapat kontrol Button1, Edit1, Label1, dengan properti yang sama pula (Left, Top, Width, Height, dan lain-lain). Intinya Form2 merupakan hasil “salinan” dari Form1 yang menurunkannya.
Mungkin suatu waktu kita pernah melakukan kesalahan secara tidak sengaja mengubah atau memindah suatu kontrol dari form turunan, dan ingin mengembalikan kontrol tersebut ke kondisi semula seperti kondisi pada form yang menurunkannya. Untungnya pada Delphi ini adalah hal mudah. Inilah langkah-langkahnya.
  1. Pada IDE Delphi, tentukan form turunan yang ingin dikembalikan dan buka form tersebut.
  2. Selanjutnya tentukan kontrol yang ingin dikembalikan kondisinya.
  3. Pada kontrol tersebut klik kanan dan pilih “Revert to Inherited”.



Baca selengkapnya...