Beberapa Hadist Motivasi Amalan Yaumiyah


“Sesungguhnya Allah tidak melihat pada bentuk tubuh kalian, tidak pula pada harta kalian, tapi sesungguhnya Allah melihat pada hati dan amal-amal kalian” (HR. Muslim).


“Sesungguhnya orang-orang yang selalu membaca kitab Allah dan mendirikan sholat dan menafkahkan sebagian dari rezeki yang Kami anugrahkan kepada mereka dengan diam-diam dan terang-terangan, mereka itu mengharapkan perniagaan yang tidak akan merugi”. “Agar Allah menyempurnakan kepada mereka pahala mereka dan menambah kepada mereka dari karunia-Nya. Sesungguhkan Allah Maha Pengampun, Maha Mensyukuri” (QS. Fathir: 29-30).

Sudah lama nemu hadist-hadist yang harusnya bisa memotivasi diri untuk senantiasa menjaga & meningkatkan alaman yaumiyah. Supaya tetap ingat, ditulislah disini.

  • Sholat
    • Rasulullah SAW bersabda: “Amalan yang paling dicintai Allah SWT adalah sholat pada waktunya, berbakti kepada orang tua, kemudian jihad di jalan Allah SWT” (HR. Bukhari – Muslim).
    • Diriwayatkan oleh Abdullah bin ‘Amru bin Ash ra. Bahwasanya Rasulullah SAW pernah bersabda: ”Barang siapa sholat malam dengan membaca sepuluh ayat Al Quran, maka tidaklah ia akan dicatat sebagai orang-orang yang lupa. Barang siapa sholat malam dengan membaca seratus ayat Al Quran, maka dia dicatat sebagai kaum Qaanitiin (patuh) – mereka gemar beribadah. Barang siapa yang sholat malam dengan membaca seribu ayat Al Quran, maka dia dicatat sebagai kaum Muqanthiriinorang kaya yang gemar menyedekahkan hartanya” (HR. Abu Daud).
    • Pernah diceritakan seorang sahabat pada Rasulullah SAW, bahwa ada seorang yang sepanjang malam tertidur pulas dan tidak bangun untuk sholat. “Telinga orang itu telah dikencingi oleh setan”, ucap Rasulullah SAW memberikan tanggapan (HR. Bukhari – Muslim dan Nasa’i).
    • “Pada setiap malam disepertiga terakhir pada bagian malamAllah SWT turun ke langit dunia dan berseru ‘Siapa yang memanggil-Ku, maka Aku pun akan menyambutnya. Siapa yang memohon kepada-Ku, Aku pun mengabulkannya. Dan siapa yang memohon ampun, maka Aku pun mengampuninya‘” ucap Rasullah SAW yang dituturkan kembali oleh Abu Hurairah ra. (HR. Bukhari, Malik, Muslim dan Tirmidzi).
    • “Pada setiap persendian kalian harus dikeluarkan sedekahnya setiap pagi; setiap tasbih [membaca subhanallah] adalah sedekah, setiap tahmid [membaca alhamdulillah] adalah sedekah, setiap tahlil [membaca allahu akbar] adalah sedekah, amar bil ma`ruf adalah sedekah, nahi `anil munkar adalah sedekah. Semua itu dapat terpenuhi dengan sholat dua rakaat yang dilakukan di waktu Dhuha” (HR. Muslim, no.1181).
    • Pada diri manusia terdapat 360 persendian. Harus baginya bersedekah untuk setiap dari persendian itu“. Mereka berkata “Siapa yang mampu melakukan hal itu wahai Rasulullah SAW?”. Beliau bersabda “dahak yang ada di masjid kau tanam, atau sesuatu (berupa gangguan) di jalan engkau singkirkan. Jika kau tak mampu juga maka dua rakaat sholat Dhuha telah mencukupi bagimu” (HR. Ahmad).
  • Membaca Al Quran
    • “Barang siap membaca satu huruf dari Al Quran, maka baginya satu kebaikan dengan bacaan tersebut, dan satu kebaikan dilipatkan menjadi 10 kebaikan semisalnya dan aku tidak mengatakan Alif Laam Miiiiiim satu huruf akan tetapi Alif satu huruf, Lam satu huruf dan Mim satu huruf” (HR. Tirmidzi dan dishahihkan di dalam kitab Shahih Al Jami’).
    • Abu Umammah Al Bahily berkata “Aku telah mendengar Rasulullah SAW bersabda ‘Bacalah Al Quran karena sesungguhnya dia akan datang pada hari kiamat sebagai pemberi syafa`at bagi orang yang membacanya’” (HR. Muslim).
    • Abu Hurairah ra meriwayatkan bahwa Rasulullah SAW bersabda “Maukah salah seorang dari kalian jika dia kembali ke rumahnya mendapati didalamnya tiga onta yang hamil, gemuk serta besar?” Kami (para sahabat) menjawab “Iya”. Rasulullah SAW bersabda “Salah seorang dari kalian membaca tiga ayat di dalam sholat lebih baik baginya dari pada mendapatkan tiga onta yang hamil, gemuk dan besar” (HR. Muslim).
    • Dikatakan kepada orang yang membaca (menghafalkan) Al Quran nanti “Bacalah dan naiklah secara tartilillah sebagaimana engkau di dunia mentartilkan Al Quran. Sesungguhnya kedudukanmu adalah pada bagian akhir ayat yang engkau baca (hafal)” (HR. Abu Dawud dan At-Tirmidzi).
    • Pada hari kiamat Al Quran akan datang kemudian berkata “Wahai Rabb, berilah dia pakaian”, maka dipakaikanlah kepadanya mahkota kemuliaan, kemudian Al Quran berkata lagi “Wahai Rabb, tambahkanlah kepadanya”, maka dipakaikan kepadanya pakaian kemuliaan, kemudian Al Quran berkata lagi “Wahai Rabb, ridhoilah dia”, akhirnya dia pun diridhoi, kemudian dikatakan kepada ahli Al Quran “Bacalah dan naiklah, niscaya akan ditambahkan kepadamu satu pahala kebaikan pada setiap ayat” (HR. Ath Thabrani).
  • Puasa
    • Dibuka pintu-pintu surga pada hari senin dan kamis, lalu diampuni (dosa) setiap orang yang tidak menyekutukan Allah SWT dengan sesuatu apapun, kecuali dua orang yang saling bertikai dikatakan “biarkan mereka berdua sampai keduanya berbaikan” (HR. Tirmidzi (2023), Ibnu Majah(1740) dan dishahihkan Al Albani dalam shahih Tirmidzi dan Ibnu Majah).
    • Puasa yang paling dicintai Allah Ta’ala adalah puasa Dawud, beliau berpuasa sehari dan berbuka sehari. Dan sholat yang paling dicintai Allah SWT adalah sholatnya Dawud, beliau tidur dipertigaan malam lalu bangun (sholat) pada sepertiga malam dan tidur pada seperenamnya. (HR. Bukhari (3238) dan Muslim (1159)).

    Sekian dan semoga bermanfaat.

    Membuat Laporan menggunakan lib mPDF pada CI

    Bagian ini membahas proses pembuatan salah satu laporan untuk aplikasi Simple Kasir yang telah dibahas tahun lalu. Baru sempat merangkumnya sekarang.🙂

    Contoh laporan yang akan dibuat adalah laporan penjualan untuk bulan tertentu. Pembuatan laporan ini menggunakan lib dari mPDF yang bisa diunduh disini. Pada contoh ini digunakan mPDF versi 5.7, jika ingin menggunakan versi yang terbaru silahkan. Pada situs ini juga disediakan dokumentasi yang cukup lengkap yang bisa dijadikan sebagai bahan acuan pembangunan laporan.

    Langkah-langkah awal yang harus dilakukan agar bisa menggunakan mPDF pada CI adalah :

    1. Ekstrak file MPDF57.zip yang sudah diunduh sebelumnya. Hasil ekstraksi berupa folder MPDF57 letakkan di folder application/libraries/MPDF57, kita bisa menghapus beberapa file atau folder yang tidak diperlukan, misalnya : folder example, iccprofiles, graph_cache.

    Lib mPDF memerlukan fungsi mb_string bawaan dari php, jadi pastikan pada file php.ini extension php_mbstring.dll ter-enable.

    2. Agar bisa digunakan dengan mudah dalam CI, kita buat class pdf yang akan membungkus lib mPDF ini. Pada folder application/libraries buat file pdf.php dan isi dengan code berikut :

    <?php if ( ! defined('BASEPATH')) exit('Tidak ada akses langsung script diperbolehkan');
    
    class pdf{
        function pdf(){
            $CI =& get_instance();
            log_message('Debug', 'mPDF class is loaded.');
        }
    
        function load($param=NULL){
            include_once APPPATH.'libraries/MPDF57/mpdf.php';
            if($params == NULL){
                $param = '"en-GB-x","A4","","",10,10,10,10,6,3';
            }
            return new mPDF($param);
        }
    }
    
     /* End of file pdf.php
        Location ./application/libraries/pdf.php */
    

    Pada class pdf terdapat fungsi load yang digunakan untuk memuat lib mPDF. Jika saat memanggil fungsi load tidak ada parameter yang dilewatkan maka secara default fungsi ini akan menginstansiasi object mPDF dengan parameter = “en-GB-x”,”A4″, “”, “”, 10, 10, 10, 10, 6, 3; dimana urutan parameternya adalah : mode, format kertas, font size, font, margin left, margin right, margin top, margin bottom, margin header, margin footer, orientasi kertas (bisa diisi dengan p / portrait atau l / landscape).

    Sampai tahap ini library pdf sudah bisa digunakan. Cara memuat lib ini sama seperti memuat lib lainnya, cukup dengan syntax : $this->load->library(‘pdf’);. Dan untuk mendapatkan object dari class mPDF dengan memanggil fungsi load dengan syntax : $pdf=$this->pdf->load();.

    3. Buat helper pada application/helpers dengan nama file “common_helper.php”. Tambahkan fungsi “getMonthName” untuk mendapatkan nama-nama bulan, fungsi “get5LastYears” untuk mendapatkan daftar tahun lima tahun kebelakang dan fungsi “getNameOfMonth” untuk mendapatkan nama bulan dari nomor urut bulan. Code-nya :

    <?php if ( ! defined('BASEPATH')) exit('Tidak ada akses langsung script diperbolehkan');
    
    if ( ! function_exists('getMonthNames')){
        function getMonthNames(){
            $namaBulan = array(
                1 => 'Januari',
                2 => 'Februari',
                3 => 'Maret',
                4 => 'April',
                5 => 'Mei',
                6 => 'Juni',
                7 => 'Juli',
                8 => 'Agustus',
                9 => 'September',
                10 => 'Oktober',
                11 => 'November',
                12 => 'Desember');
            return $namaBulan;
        }
    }
    if( ! function_exists('getNameOfMonth')){
        function getNameOfMonth($bln){
            $namaBulan = getMonthNames();
            return $namaBulan[(int)$bln];
        }
    }
    if( ! function_exists('getg5LastYears')){    
        function get5LastYears(){
            $listTahun = array();
            $thnNow = intval(date('Y'));
            for($i=$thnNow-4; $i<=$thnNow; $i++){
                $listTahun[(string)$i] = (string)$i;
            }
            return $listTahun;
        }
    }    
    /*     End of file common_helper.php
        Location ./application/helpers/common_helper.php */
    

    4. Buat controller untuk menampilkan halaman cetak laporan dengan nama lapPenjualanPerBulan.php. Pada bagian constructor muat lib template, table dan validation serta model item dan user. Buat fungsi _set_fields yang akan menampung nilai inputan bulan dan tahun.

    Fungsi index akan menampilkan halaman generate laporan dengan memilih bulan dan tahun terlebih dahulu. Untuk mengisi dropdownlist bulan dan tahun, digunakan fungsi dari helper yang sebelumnya sudah kita buat, muat helper dengan syntax : $this->load->helper(‘common_helper’); dan untuk memanggil fungsinya cukup dengan syntax : getMonthNames() dan get5LastYears(). Code-nya :

        function __construct(){
            parent::__construct();
            //load lib:
            $this->load->library('template','table');        
            //load model:
            $this->load->model('item_model', '', TRUE);
            $this->load->model('user_model', '', TRUE);
        }
        
        function index(){
            if($this->session->userdata('logged_in')) {            
                $session_data = $this->session->userdata('logged_in');
                $data['jabId'] = $session_data['jab'];
                $data['judul'] = 'Penjualan';
                
                $this->load->helper('common_helper');
                $data['cbBulan'] = getMonthNames();
                $data['cbTahun'] = get5LastYears();
                $data['lap'] = 'lapPenjualanPerBulan';
                
                $this->validation->namaBulan = date('m');
                $this->validation->tahun = date('Y');
                
                $this->template->display('laporan/lapBlnan', $data);
            }else{ //jika tidak ada session, redirect ke halaman login
                redirect('login', 'refresh');
            }
        }
    

    Tambahkan fungsi loadReport yang akan menghasilkan file pdf yang akan di tampilkan di tab baru, dalam membuat pdf digunakan lib mPDF yang sudah dibungkus dalam class pdf sebelumnya.

        function loadReport(){
            if($this->session->userdata('logged_in')) {            
                $session_data = $this->session->userdata('logged_in');            
                $data['bulan'] = $this->input->post('bln');
                $data['tahun'] = $this->input->post('thn');
                $this->load->helper('common_helper');
                $data['tglCetak'] = date('d') .' '. getNameOfMonth(date('m')) . ' ' . date('Y');
                //As PDF creation takes a bit of memory, we're saving the created file in /downloads/reports/
                $pdfFilePath = FCPATH."/downloads/reports/lapJualBln".date('F').".pdf";
                
                if(file_exists($pdfFilePath)==FALSE){
                    ini_set('memory_limit', '64M');
                    //generate table :
                    $items = $this->item_model->GetLapJualPerBln($data['bulan'] . '-' . $data['tahun']);                
                    $this->load->library('table');
                    $this->table->set_empty("&nbsp;");
                    $this->table->set_heading('No', 'Kode Barang', 'Nama Barang', 'Foto', 'Jumlah Terjual');
                    if($items != false){
                        $i=0;
                        foreach($items as $brg){
                            $this->table->add_row(
                                ++$i,
                                $brg->IdBrg,
                                $brg->NamaBarang,
                                ($brg->GambarBarang!=null) ?
                                '<img width="100" src="data:image/jpeg;base64,'.base64_encode($brg->GambarBarang).'">' : '-',
                                $brg->jumTerjual
                            );
                        }
                    }else{
                        $this->table->add_row("","","Tidak ada barang yang terjual","","");
                    }
                    $data['table'] = $this->table->generate();    
                    
                    $data['bulan'] = getNameOfMonth($data['bulan']);
                    
                    $peg = $this->user_model->GetUserByUserName($session_data['username']);
                    $data['namaPeg'] = $peg->NamaPengguna;
                    
                    $html = $this->load->view('laporan/labjualPerBln', $data, true); //render the view into HTML
                    $this->load->library('pdf');
                    $pdf=$this->pdf->load();
                    $pdf->SetFooter(''.'|{PAGENO}|'.''); //Add a footer for good measure
                    $pdf->WriteHTML($html); //write the HTML into PDF
                    $pdf->Output();
                }
                redirect("downloads/reports/namafile.pdf");
            }else{ //jika tidak ada session, redirect ke halaman login
                redirect('login', 'refresh');
            }
        }
    

    Guna menghasilkan laporan dalan bentuk pdf diperlukan tampilan html yang merupakan isi content dari laporan, dalam contoh ini namanya “labjualPerBln.php” yang akan tersimpan pada application/views/laporan. Code pada file tersebut adalah:

    <head>
        <title>Lap. Penjualan</title>
        <link rel="stylesheet"type="text/css"href="<?php echo base_url().$this->config->item('css'); ?>"/>
    </head>
    <body>
    <div id="content">
        <div class="row">
            <div class="caption" align="center">Laporan Penjualan Barang bulan <?php echo $bulan." ".$tahun;?> </div>
            <div class="end"></div>
        </div>
        <hr>
        <div class="row">
            <div class="value">Tanggal Cetak : <?php echo $tglCetak;?></div>
            <div class="end"></div>
        </div>
        <br/>
        <div class="row">
            <div class="value">Berikut adalah daftar barang yang berhasil terjual bulan ini.</div>
            <div class="end"></div>
        </div>
        <div class="row">        
            <div class="data"><?php echo $table; ?></div>
            <div class="end"></div>
        </div>
        <div class="spacer"></div>
        <div class="row">
            <div class="value" align="right">
                Pembuat Laporan
                <br/><br/><br/>
                <b><?php echo $namaPeg; ?></b>
            </div>
            <div class="end"></div>
        </div>
    </div>                        
    </body>
    

    5. Buat tampilah halaman yang akan membuat file pdf simpan dengan nama lapBlnan.php, code-nya :

    <head>
        <title><?php echo "Laporan ".$judul."/Bulan";?></title>    
        <script type="text/javascript" src="<?php echo base_url() ?>assets/js/jquery-1.3.2.min.js"></script>
    </head>
    <body>
        <div class="row">
            <div class="caption"><?php echo "Laporan ".$judul." Barang/Bulan"; ?></div>
            <div class="end"></div>
        </div>
        <hr />
        <div id="content">
            <?php echo form_open(site_url($lap.'/loadReport'), array('target' => '_blank'));?>
            <div class="row">
                <div class="caption_border">Pilih Periode Laporan</div>
                <div class="end"></div>
            </div>
            <div class="row">
                <table>
                    <tr>
                        <td style="padding-left:5px;">Bulan : </td>
                        <td style="padding-left:5px;"><?php echo form_dropdown('bln',$cbBulan,$this->validation->namaBulan,'id="bln";onChange="updateGraph()"');?></td>
                        <td style="padding-left:15px;">Tahun : </td>
                        <td style="padding-left:5px;"><?php echo form_dropdown('thn',$cbTahun,$this->validation->tahun,'id="thn";onChange="updateGraph()"');?></td>
                        <td style="padding-left:15px;">
                            <?php $f_btn = array('name'=>'submit', 'id'=>'submit', 'value'=>'Generate Report');
                                  echo form_submit($f_btn); ?>
                        </td>
                    </tr>
                </table>
                <div class="end"></div>
            </div>
            <div class="spacer"></div>
        </div>
    </body>
    

    6. Selesai. Slanjutnya tinggal mendaftarkan halaman laporan tersebut pada menu dan contoh hasil tampilannya adalah :

    Dan ketika menekan tombol “Generate Report” akan terbuka tab baru yang menampilkan laporan dalam format pdf. Contoh tampilannya:

    Sekian catatan kali ini. Semoga bermanfaat… (^u^)

    Pagination pada CodeIgniter: Langsung menunjuk hal. tertentu di awal memuat web-page

    Setelah lama g bersua dengan CI, akhirnya kemarin nyoba2 lagi. Ternyata ada kasus gimana caranya bisa menampilkan pagination langsung ke halaman tertentu saat pertama kali web-page dimuat. Dan setelah nyari2 nemulah salah satu caranya. Berikut adalah langkah-langkahnya:

    – Salin file Pagination.php dari folder system/libraries ke dalam folder application/libraries. File inilah yang akan digunakan CI, bukan lagi file aslinya.

    – Buka file salinan tersebut dan lakukan perubahan dan tambahan code berikut :

    > Pada baris 165 sebelum command code// Set current page to 1 if using page numbers instead of offset” tambahkan code berikut :

    //nambahin if supaya bisa ngeset current page di pagination-nya
            if($this->enable_set_cur_page){
                if ($this->use_page_numbers){
                    $this->cur_page = (int) $this->current_page;
                }else{
                    $this->cur_page = (int)($this->per_page * ($this->current_page-1));
                }
            }
    

    > Tambahkan variabel pada baris 62 :

    var $enable_set_cur_page = FALSE; //enable setting current page
    var $current_page = 1; // menentukan halaman saat ini pada pagination
    

    Tahapan mengedit lib Pagination selesai…

    Selanjutnya adalah cara menggunakannya, saat inisialisasi array $config tambahkan code berikut:

    $config['enable_set_cur_page'] = TRUE;
    $config['current_page'] = $hal;
    

    Selesai… Pagination yang muncul akan menunjuk pada hal sesuai dengan $config[‘current_page’] yang ditentukan.

    Berikut adalah hasil tampilan dengan menetapkan nilai current_page = 2.

    tampilan pagination CI

    Sekian, semoga bermanfaat <(^v^)>

    Install dB PostgreSQL dan Menghubungkannya dgn Cpp VS

    Postingan kali ini akan membahas cara installasi sampai penggunaan dB PostgreSQL pada C++ VS. Saat melakukan installasi dengan langsung menjalankan file .exe-nya pada Windows XP selalu terjadi error seperti gambar berikut :

    Setelah googling sana sini akhirnya ditemukan cara mengatasinya, yaitu:

    1. Uninstall Postgres.
    2. Buat folder Postgres yang akan menyimpan hasil instalasi. Berikan hak akses untuk semua user.

      Jika tab Security tidak muncul pada properties folder, lakukan :

      Pada Widows Exploler toolbal pilih “Tools” >> “Folder Option” >> tab “View” >> un-cawang Advanced setting untuk “Use simple file sharing(Recommended)” >> Apply. Cek lagi properties folder, seharusnya tab Security sudah muncul.
    3. Buat akun postgres. Bisa lewat control panel atau
      [Windows]+R >> compmgmt.msc >> Local Users and Groups >> Users >> New User … >> User name: postgres, Password: postgrespass >> Create.
      Click user postgres >> Member of -> Add … -> Administrator -> OK.
    4. Letakkan installer di C:\
    5. Pada cmd :> runas /user:postgres cmd >> cd \ >> postgresql-8.4.9-1-windows.exe >> Proses warning yang sblmnya muncul akan hilang.
    6. Setelah selesai instalasi hapus akun postgres. Bisa lewat control panel atau
      [Windows]+R >> compmgmt.msc -> Local Users and Groups -> Users -> postgres >> Remove.

    Proses instalasi dB PostgreSQL selesai. dB siap digunakan. Untuk mengakses dB bisa menggunakan pgAdmintools yang sudah disedikan.

    Berikut adalah beberapa catatan tentang perbedaan syntax query antara MySQL dengan PostgreSQL:

    MySQL PostgreSQL
    Cara mengeksekusi storeprocedure(@MySQL) atau function(@PostgreSQL) CALL [namaSP] [(params]) Select [namaFungsi] ([params])
    Jika nama parameter pada sebuah SP/function tidak sama dengan syntax yang ada di dalam SP/function Tidak terdeteksi error sehingga berhasil create SP dan secara default akan diisi dengan NULL. Terdeteksi error, sehingga function tidak berhasil ter-create.
    Dari C++ untuk mengetahui jumlah row_affected Bisa memanggil fungsi dari libmysql mysql_affected_rows(conn),
    conn bertipe MYSQL*.
    Tidak disediakan fungsi di libpq. Sehingga pada syntax querynya harus ditambahkan query untuk mengembalikan jumlah row affected, syntaxnya:
    declare cnt integer;
    [syntax query CRUD];
    GET DIAGNOSTICS cnt = ROW_COUNT;
    Select cnt;
    Cara mengisi table yang bertipe string [] [isi data string] [] SET STANDARD_CONFORMING_STRINGS=ON;
    [E] [isi data string] []
    Untuk menghapus data secara massal, sebelumnya harus set sql_safe_updates = 0; Tidak ada
    Saat mengeksekusi sejumlah query bersamaan Dieksekusi satu-satu sampai ketemu ada query yang error baru berhenti dan query selanjutnya tidak dieksekusi. Diperiksa terlebih dahulu semua query-nya, jika ditemuakan ada query yang syntax-nya masih salah maka keseluruhan query tidak akan dieksekusi.

    Untuk menggunakan library PostgreSQl pada C++ VS adalah :

    1. File header yang perlu di-include: libpq-fe.h; postgres_ext.h; pg_config_ext.h;
      Set direktori file header postgresql pada Property Project >> Configuration Properties >> C/C++ >> General >> Additional Include Directories.
    2. File library yang perlu di-include: libpq.lib
      Tambahkan file .lib pada Property Project >> Configuration Properties >> Linker >> Input >> Addition Dependencies.
      Atau dengan melakukan set additional lib. dir. pada Property Project >> Configuration Properties >> Linker >> General >> Additional Library Directories dan melakukan include dengan code: #pragma comment(lib, “libpq.lib”)
    3. File dynamic library yang perlu di-include: libpq.dll; ssley32.dll; libeay32.dll; intl.dll;
      Dari sini ada beberapa cara yang bisa dilakukan. Tapi cara yang paling berhasil adalah dengan menyalin semua file .dll tersebut kedalam folder tempat file exe berada. Cara menyalin file .dll dengan menggunakan code bisa dilihat disini.

    Berikut adalah contoh code untuk melakukan proses CRUD ke dB PostgreSQL dari C++

    #pragma once
    #include <string>
    #include “libpq-fe.h”
    #include <time.h>

    #pragma comment(lib, “libpq.lib”)


    PGconn* ConnectDB(){
    PGconn* conn = NULL;
    //bangun koneksi ke dB
    conn = PQconnectdb(“user=ikti password=via dbname=pt hostaddr=127.0.0.1 port=4419”);
    //Cek apakah backend connection berhasil dibangun
    if(PQstatus(conn) != CONNECTION_OK){
    printf(“Koneksi ke dB GAGAL : %s”, PQerrorMessage(conn));
    CloseConn(conn);
    }
    printf(“Koneksi ke dB BERHASIL\n”);
    return conn;
    }
    void CloseConn(PGconn *conn){
    PQfinish(conn);
    getchar();
    exit(1);
    }
    void CreatePegawaiTable(PGconn* conn){
    //eksekusi dengsn statement SQL
    PGresult* res = PQexec(conn, “CREATE TABLE PEGAWAI (nama varchar(30), tlc char(3))”);
    if(PQresultStatus(res) != PGRES_COMMAND_OK){
    printf(“Create table pegawai GAGAL”);
    PQclear(res);
    CloseConn(conn);
    }
    printf(“Create Table Pegawai BERHASIL\n”);
    //bersihkan result
    PQclear(res);
    }
    void DropTablePegawai(PGconn* conn){
    PGresult* res = PQexec(conn, “DROP TABLE pegawai”);
    if(PQresultStatus(res) != PGRES_COMMAND_OK){
    printf(“Drop pegawai table GAGAL”);
    PQclear(res);
    CloseConn(conn);
    }
    printf(“Drop Table pegawai berhasil\n”);
    PQclear(res);
    }
    void InsertDataPegawai(PGconn* conn, char* name, char* tlc){
    //gabungkan sintax query:
    char sSQL[256];
    sprintf(sSQL, “INSERT INTO pegawai values(‘%s’,’%s’, 11, NULL)”, name, tlc);
    //eksekusi dengan statement sql
    PGresult* res = PQexec(conn, sSQL);
    if(PQresultStatus(res) != PGRES_COMMAND_OK){
    printf(“Insert data pegawai GAGAL”);
    PQclear(res);
    CloseConn(conn);
    }
    printf(“Insert data pegeawai BERHASIL (%s)\n”, PQcmdTuples(res));
    //bersihkan result
    PQclear(res);
    }


    void UpdateDataPegawai(PGconn* conn, char* tlc, char* namaBaru){
    //gabungkan sintax query:
    char sSQL[256];
    sprintf(sSQL, “UPDATE pegawai set nama=\’%s\’ where tlc=\’%s\'”, namaBaru, tlc);
    //eksekusi dengan statement sql
    PGresult* res = PQexec(conn, sSQL);
    if(PQresultStatus(res) != PGRES_COMMAND_OK){
    printf(“Update nama pegawai GAGAL”);
    PQclear(res);
    CloseConn(conn);
    }
    printf(“Update nama pegeawai BERHASIL (%s)\n”, PQcmdTuples(res));
    //bersihkan result
    PQclear(res);
    }


    void DeleteDataPegawai(PGconn* conn, char* tlc){
    //gabungkan sintax query:
    char sSQL[256];
    sprintf(sSQL, “Select hapusPegawai(‘%s’)”, tlc);
    //eksekusi dengan statement sql
    PGresult* res = PQexec(conn, sSQL);
    if(PQresultStatus(res) != PGRES_TUPLES_OK){
    printf(“Hapus pegawai GAGAL : %d”, PQresultStatus(res));
    PQclear(res);
    CloseConn(conn);
    }
    printf(“Hapus pegawai SUKSES (%d)\n”, atoi(PQgetvalue(res,0,0)));
    //bersihkan result
    PQclear(res);
    }


    void DeleteAllPegawaiData(PGconn* conn){
    PGresult* res = PQexec(conn, “DELETE FROM pegawai”);
    if(PQresultStatus(res) != PGRES_COMMAND_OK){
    printf(“DELETE data Pegawai GAGAL”);
    PQclear(res);
    CloseConn(conn);
    }
    printf(“Delete data pegawai BERHASIL\n”);
    PQclear(res);
    }
    void GetPegawaiData(PGconn* conn){
    //yg akan menampung jumlah field pada table pegawai
    int nField;
    PGresult* res = PQexec(conn, “select * from pegawai”);
    if(PQresultStatus(res) != PGRES_TUPLES_OK){
    printf(“ambil data pegawai GAGAL : %s”, PQerrorMessage(conn));
    PQclear(res);
    CloseConn(conn);
    }
    //mendapatkan field name
    nField=PQnfields(res);
    printf(“\nData pegawai:”);
    printf(“\n*****************************************************************\n”);
    for(int i=0; i<nField; i++){
    printf(“%-17s”, PQfname(res, i));
    }
    printf(“\n*****************************************************************\n”);
    for(int i=0; i<PQntuples(res); i++){
    for(int j=0; j<nField; j++){
    printf(“%-17s”, PQgetvalue(res, i, j));
    }
    printf(“\n”);
    }
    PQclear(res);
    }
    int main(void){
    PGconn* conn = NULL;
    conn = ConnectDB();
    CreatePegewaiTable(conn);
    GetPegawaiData(conn);
    InsertDataPegawai(conn, “111”, “xxx”);
    InsertDataPegawai(conn, “2222”, “xxx”);
    GetPegawaiData(conn);
    UpdateDataPegawai(conn, “xxx”, “Ini nama barunya”);
    GetPegawaiData(conn);
    DeleteDataPegawai(conn, “xxx”);
    GetPegawaiData(conn);
    CloseConn(conn);
    getchar();
    return 0;
    }

    Pada PostgreSQl, tabel pegawai dibuat dengan syntax:

    CREATE TABLEpegawai
    (
    nama character varying(30),
    tlc character (3),
    nomor integer ,
    tgl timestamp with time zone — unt coba get & set data timestamp
    )
    WITH (
    OIDS=FALSE
    );

    Proses penghapusan data pegawai berdasarkan tlc dilakukan melalui function hapuspegawai, syntax pembuatan fungsi tersebut:

    CREATE OR REPLACE FUNCTION hapuspegawai (theid character)
    RETURNS integer AS
    $BODY$
    DECLARE jum int;
    BEGIN
    delete from pegawai where tlc=theid;
    GET DIAGNOSTICS jum=ROW_COUNT;
    return jum;
    END;


    $BODY$
    LANGUAGE plpgsql VOLATILE
    COST 100;
    ALTER FUNCTION hapuspegawai(character)
    OWNER TO ikti;

    Sekian catatan kali ini.
    Semoga bermanfaat ~{^v^}~

    Menampilkan Halaman dari JumHalamanIsi di Ms Word

    Kemarin dapat tugas untuk menggabungkan dokumen yang baru dibuat dengan sampul depan dan belakangnya. Binggungnya muncul karena pada bagian header ada [no halaman] dari [jumlah total halaman isi] (Page 1 of 20). Karena belum pernah mbuat yang kayak gitu akhirnya harus googling2. Awalnya cuma nemu yang memberikan sintaks rumus tanpa memberikan langkah2 membuat formulanya. Ternyata langkah2nya cukup mudah.

    Arahkan kursor ke bagian footer ataupun header dimana akan dimunculkan halaman dari jumlahHalaman. Contoh berikut ada di bagian header dan format yang ditampilkan adalah “Halaman XX dari XX”:

    • Tuliskan “Halaman” + [spasi]
    • Tekan [Alt] + F9 untuk menampilkan rumus / formula, karena masih blm ada isinya maka tidak akan muncul apa2
    • Selanjutnya tekan [Ctrl] + F9 untuk memulai formula. Akan muncul lambang kurung kurawal : { }. Ketikkan “PAGE” di dalamnya dan arahkan kursor ke belakang tutup kurung kurawal : }; dan ketikkan [spasi] + “dari” + [spasi].
    • Tekan lagi [Ctrl] + F9 dan isikan didalam kurung kurawal dengan “NUMPAGES”. Tampilannya terlihat seperti gambar berikut:
      tampilanRumus
    • Untuk melihat hasilnya tekan [Alt] + F9. Dan tampilannya seperti gambar berikut:
      tampilanHal

     

    Yang dibutuhkan pada contoh kali ini adalah jumlah total halaman yang harusnya tampil harus dikurangi dua, karena 1 halaman di awal dan akhir dokumen adalah halaman sampul sehingga tidak perlu dihitung. Kita tinggal mengubah rumusnya menjadi : “Halaman {PAGE} dari {= {NUMPAGES} -2}”. Tahapannya hampir sama dengan yang sebelumnya hanya saja saat selesai menulis kata “dari” dan mau memulai menulis formula untuk jumlah halamannya, langkahnya :

    • Tekan [Ctrl] + F9, untuk memulai rumus, didalam kurung kurawal ketik “=” dan sekali lagi tekan [Ctrl] + F9 lalu isi kurung kurawal kedua dengan “NUMPAGES”.
    • Arahkan kursor ke luar kurung kurawal pertama dan ketikkan “-2”. Tampilannya menjadi seperti gambar berikut:
      tampilanRumus2
    • Untuk melihat hasilnya tekan [Alt] + F9. Tampilannya seperti gambar berikut:
      tampilanHal2

    Muncul nol karena jumlah halaman total yang ada di dokumen tersebut cuma 2 sehingga jika dikurangi dua maka hasilnya = nol.

     

    Nb:
    rumus NUMPAGES dan PAGE hanya bisa diaplikasikan pada bagian header atau footer. Menurut percobaan yang dilakukan jika rumus diletakkan di bagian content document, hasil dari rumus yang ditulis tidak akan muncul walau tidak terdapat error.

    Selesai…
    Semoga bermanfaat… 😉

    Sumber:
    http://superuser.com/questions/817691/word-syntax-error-with-numpages-and-formula

    Catatan Yang Tercecer

    Berikut adalah catatan yang didapat dari beberapa ustadz & ustazah(maaf jika ada kesalahan dalam penulisan nama atau bahkan terlupa namanya), terima kasih atas dorongan semangat, ilmu, nasehat dan semua kesabarannya dalam membimbing kami selama ini. Jazakumullah khairan katsiran wa jazakumullah ahsanal jaza (Semoga Allah SWT akan membalas kalian dengan kebaikan yang banyak dan semoga Allah SWT akan membalas kalian dengan balasan yang terbaik).🙂

    Ilmu dari Ustazah Zeni

    • Qs Al Kautsar berisi tentang perintah melaksanakan solat + qurban.
    • Harokat -> pergerakan (mulut yg bergerak)
      – Fatha = membuka, mulut dibuka
      – Kasro = memecah, rahang memecah ke bawah
      – Dummah = mengumpulkan, bibir berkumpul ke depan
    • Saat membaca bacaan qolqolah /memantul, berhati-hatilah. Karena jika tidak memantul pada tempatnya akan menimbulkan TAWALLUD(menimbulkan huruf baru).
    • Qs Al Ma’un bercerita tentang pendusta agama, yaitu orang yang menghardik anak yatim, tidak memberi makan orang miskin dan mengulur-ulur waktu solat / lalai dalam solat.
    • Kotoran hewan cicak adalah Najis.
    • Urutan kerja organ pada malam hari :
      – 21.00 – 23.00 : hati harus dalam keadaan tenang / rileks
      – 23.00 – 01.00 : jantung dalam keadaan lemah, jadi harus tidur
      – 01.00 – 03.00 : limpa sedang berkerja
      – 03.00 – 05.00 : paru-paru bekerja, jadi harus bangun
    • Qs Al Fil (Gajah) turun disaat Mekah diserang pasukan bergajah. Tahun Gajah adalah kelahiran Nabi Muhammad tanggal 12 Rabiul Awal.
    • Mengaji itu menggunakan hati, dinikmati (setidaknya untuk diri sendiri), perhatikan huruf-hurufnya dan jangan takut salah.
    • Inti agama Islam adalah Bersyukur dan Bersabar.
    • Qs Al Buruj bercerita tentang bangsa Najran di Yaman.

    Ilmu dari Ustadz yang aq lupa namanya

    • Qolqolah itu yang keluar adalah suara bukan nafas.

    Ilmu dari Ustadz Syarif

    • Orientasi belajar Al Quran : Dekat dengan Al Quran dan Semakin Cinta dengan Al Quran.
    • Membaca Al Quran tidak mungkin dosa walaupun kita salah saat sedang belajar, asal tidak diniatkan untuk disalahkan. Jadi teruslah berani belajar Al Quran.
    • Sukun artinya berhenti / tenang.

    Ilmu dari Ustadz Zainudin(saat akhir periode 10-06-2014M)

    • Niatkanlah selalu menambah hafalan minimal 1 ayat tiap hari. Karena niat baik saja sudah mendapatkan pahala apa lagi dibarengi dengan usaha sungguh-sungguh untuk mencapainya. Urusan hasilnya sesuai dengan target yang kita buat itu urusan nanti. Buatlah plan jangka panjang(minimal 1 tahun kedepan).
    • Jika bisa menghafal 1 ayat berati kita telah mendapatkan nikmat dari Allah. Jadi bersyukurlah.
    • Cara menghafal yang beliau anjurkan adalah : Jika mau mulai menghafal 1 halaman/surat, baca terlebih dahulu artinya dan coba pahami(ambil poin-poin pentingnya) sambil kenalan dengan bacaan arabnya (baca berulang-ulang sampai lidah ini merasah ringan membacanya)

    Ilmu dari Ustadz yg aq lupa namanya(dr siaran ulang di radio)

    • Iri seorang mukmin itu hanya boleh kepada :
      1. Orang yang menghafal Al Quran dan mengamalkannya(membaca lafadz, dipahami) di waktu siang dan malam(yg lebih banyak). Rasullullah membaca minimal 1 juz dalam solat malamnya, biasanya sampai 5 juz. Jika ingin khatam membaca Al Quran seminggu 2x maka baca sehari 9 juz (4,5 juz di siang dan malam hari). “Mulutku selalu rindu membaca Al Quran“, maksudnya camilan sehari-harinya adalaha Al Quran. Berusahalah memahami Al Quran tiap hari beberapa ayat.
      2. Orang yang kaya yang membelanjakan hartanya di jalan Allah setiap saat tanpa menunda-nunda. Infaq karena Allah (Memberi tepat sasaran), Infaq karena kewajiban zakat dan Infaq tanpa batas.
    • Kenginan yang kita miliki harus disempurnakan alasannya sampai benar karena Allah.
    • Cita-cita yang harus dimiliki seorang muslim adalah “Ingin hafal Al Quran & Menjadi Saudagar Kaya”.

    Ilmu dari Ustadz M. B. Maknun

    • Agar tetap bersemangat berbuat baik -> “Ingat Mati” maka persiapkahlah bekal untuk kematian tersebut dengan sebaik mungkin.
    • Cara membuktikan semangat kebaikan : PAKSA segera melakukannya & PAKSA melawan hawa nafsu jahat.

    Ilmu dari Ustadzah Fariah(22 & 26 Dzulhijjah 1435H)

    • Setiap jalan yang kita pilih pasti ada konsekuensinya yang harus dipertanggungjawabkan. Jika sudah memilih jalan untuk ikut berjuang menghafal Al Quran maka HARUS diPAKSA untuk selalu istoqomah menambah dan menjaganya(murojaah/mengulang-ulang). Minimal targat harian terpenuhi. Semakin sering muter dalam 1 minggu semakin baik. Tidak perlu selalu memaksakan hafalan Golongan B ke Golongan A yang bisa mengakibatkan target harian terbengkalai. Menghafal yang baru itu lebih mudah dari pada menjaga hafalan yang sudah ada. “Tetep semangat menambah hafalan baru & istiqomah murojaah hafalan yg sudah ada“.
    • Al Quran itu suci, jadi jika ingin Al Quran bisa masuk ke hati kita maka awalnya hati ini harus dibersihkan dari semua hal yang kotor.
    • Orang yang hafal Al Quran bukan lagi menggunakan otaknya untuk murojaah melainkan menggunakan hatinya. Contoh pertama, ada seorang hafidzh yang sedang sakit keras, diujung umurnya dia terus melantunkan surat Al Baqarah samapai selesai, padahal jika menurut nalar, otaknya sudah tidak bisa digunakan untuk berpikir lagi, beliau hanya menggunakan hatinya untuk melantunkan surat Al Baqarah tersebut. Contoh kedua, seorang ulama besar yang hafal Al Quran mengalami kecelakaan dan koma semala 3 hari sebelum akhirnya meninggal dan selama 3 hari itu pula beliau telah mengkhatamkan Al Quran sebanyak 3x.

    Masya Allah…. :’| Semoga kita semua termasuk dalam barisan hamba-hamba Allah yang diberi kesempatan untuk melantunkan Al Quran di ujung usia kita Aamiiiin.

    Sekian dan semoga bermanfaat ~{^v^}~

    Wisock UDP Socket vs ENet UDP Socket vs ENet–UDP Realiable

    Pertengahan bulan Muharam 1436H, dapat tugas untuk mencari tau tentang cara kerja ENet. Situs resminya ada disini, semua file-file yang perlu diunduh, contoh penggunaan sampai dokumentasi penjelasannya tersedia. Versi ENet yang digunakan kali ini adalah 1.3.12.

    Tahapan installasi ENet pada Windows XP adalah :

    1. Unduh installer pada : http://enet.bespin.org/Downloads.html dan ekstrak file enet-1.3.12.tar.gz.
    2. Untuk menggunakan lib ini cukup dengan include static lib. “enet.lib” atau “enet64lib” sesuai dengan spec. kompeter, untuk Windows XP digunakan yg “enet.lib”. Lakukan link dengan lib. Winsock dengan menabahkan lib ws2_32.lib dan winmm.lib ke daftar lib project (Project Settings >> Link >> Object / library modules) atau tambahkan #pragma comment(lib, “Ws2_32.lib”) dan #pragma comment(lib, “WinMM.lib”) setelah #include <enet\enet.h> pada bagian header code. Include folder “enet” dari folder include hasil ekstraksi, folder ini berisi file-file header.

    Cara lainnya adalah dengan melakukan build sendiri lib.-nya: Bisa menggunakan project MSVC 6 yang tersedia (enet.dsp), tinggal di upgrade jika menggunakan versi MSVC terbaru. Ato dengan melakukan drag semua file code ke project utama. Pastikan sudah melakukan link ke Winsock lib.

    Proses installasi selesai, selanjutnya ENet siap digunakan untuk melakukan komunikasi antar host.

    Mau menambahkan sedikit tentang ENet berdasarkan beberapa sumber yang sudah lupa dari mana saja🙂. Berikut ringkasan tentang ENet yang berhasil ditemukan :

    • ENet memiliki fitur utama realiable, pengiriman paket yang in-order delivery packet.
    • ENet punya opsi untuk mengirim data dalam banyak channels dan data yang dikirim bisa unrealiable, reliable ataupun berurutan, termasuk peer to peer ping yang terjadi selama connect dengan memilih flag yang sesuai dengan jenis paket yang kita inginkan saat membuat packet.
    • Konsep channel komunikasi Enet adalah pengurutan. Setiap buffer ENet berada dalam urutan numerik. Hasilnya memungkinkan melakukan pengiriman beberapa aliran data dan channel dengan nomor paling kecil punya prioritas tinggi.
    • Pada fungsi enet_packet_create()parameter ketiga adalah flag, yang menentukan jenis paket. FlagENET_PACKET_FLAG_RELIABLE< berarti paket reliable dan berurutan, tidak ada cara lain untuk mendapatkan reliability tanpa pengurutan di ENet. Pengurutan ini hanya berlaku pada channel yang sama. Paket akan terus dikirim ulang selama belum ada ack dari host tujuan, jika selama timeout pengiriman ulang paket tidak juga mendapatkan balasan ack maka akan dianggap terputus dan melakukan reset connection; FlagENET_PACKET_FLAG_UNSEQUENCED berarti paket unreliable dan tidak berurutan; Flag diset NOL berarti paket unreliable tapi berurutan.
    • Paket dikirim ke host tujuan menggunakan fungsi enet_peer_send() yang selanjutnya ENet akan menangani dealokasi secara otomatis, sehingga tidak perlu memanggil fungsi enet_packet_destroy(). Antrian paket akan dikirim pada pemanggilan fungsi enet_host_service() dengan adanya dispatching event atau fungsi enet_host_flush()tanpa dispatching event.
    • Jika memerlukan paket yang reliable tapi tidak berurutan, maka sebaiknya tetap menggunakan paket flag yang reliable namun pada saat pengirimannya menggunakan channel yang berbeda.

    Berikut adalah code untuk komunikasi clientserver. Code dibuat menggunakan Winsock socket UDP, Enet socket UDP dan Enet realiable UDP, agar mengetahui perbedaan code antara lib. ENet dengan Winsock.

    Gambaran umum yang terjadi di client dan server adalah:

    Server Client
    Create Socket Create Socket
    Identify Socket Identify Socket
    Wait incomming message Send message to Server
    Send response back to client Wait response message
    Close Socket Close Socket

    Winsock UDP Socket

    Server

    • Init Winsock

      #include <WinSock2.h>
      #include <Windows.h>
       
      int retval, fromlen;
      SADATA wsaData;
      SOCKET s;
      struct sockaddr_in myaddrs, from;
      char buffer[128];
      char* ipAddrs = “127.0.0.1”;
      unsignedshort port = 1234;
       
      //request Winshock v 2.2
      if((retval = WSAStartup(0x202, &wsaData)) != 0){
       fprintf(stderr, “Server : WSAStartup() failed : %d\n”, retval);
       WSACleanup();
      return -1;
      } else
       printf(“Server: WSAStartup() sukses\n”);
    • Isi Address

      myaddrs.sin_family = AF_INET;
      myaddrs.sin_addr.S_un.S_addr = (!ipAddrs) ? INADDR_ANY : inet_addr(ipAddrs);
      myaddrs.sin_port = htons(port);//port dlm Network Byte Order
    • Buat socket

      //Create socket
      s = socket(AF_INET, SOCK_DGRAM, 0);
      if(s == INVALID_SOCKET){
       printf(“Mbuat soket gagal : %d\n”, WSAGetLastError());
       WSACleanup();
       return -1;
      }else
       printf(“Server: socket() is OK.\n”);
    • Bind Socket

      if(bind(s, (struct sockaddr*)&myaddrs, sizeof(myaddrs)) == SOCKET_ERROR){
       printf(“Server: bind() failed : %d”, WSAGetLastError());
       WSACleanup();
       return -1;
      }else
       printf(“Server : bind OK\n”);
    • Nunggu data dari client & Ngirim balasan

      printf(“Server: Nunggu ada yg connect port=%d, protocol UDP\n”, port);
      while(1){
       fromlen = sizeof(from);
       retval = recvfrom(s, buffer, sizeof(buffer), 0, (struct sockaddr*)&from, &fromlen);
       if(retval == SOCKET_ERROR){
        //fprintf(stderr, “Server: recv() failed %d\n”, WSAGetLastError());
        closesocket(s);
        continue;
       }
       elseif(retval==0){
        printf(“Server: Client closed connection.\n”);
      //Close socket
        closesocket(s);
        continue;
       }
       buffer[retval] = ;
       printf(“Server: dpt data dr %s\n\t received %d bytes, data = %s\nServer: Ketik ulang ke client…\n”,
       inet_ntoa(from.sin_addr), retval, buffer);
      //Send response back to client
       retval = sendto(s, buffer, strlen(buffer), 0, (struct sockaddr*)&from, fromlen);
       if(retval == SOCKET_ERROR)
        printf(“Server: send() failed: error %d\n”, WSAGetLastError());
       else
        printf(“Server: send() OK\n”);

       continue;
      }
    • Tutup soket & Cleaning up winsock

      closesocket(s);
      if(WSACleanup()!=0)
       cerr << “cleanup gagal!\n”;

     
    Client

    • Init Winsock

      #include <WinSock2.h>
      #include <Windows.h>
       
      int retval, serverLen;
      WSADATA wsaData;
      char buffer[256];
      char* myName = “localhost”; char* serverName = “127.0.0.1”;
      unsignedshort serverPort = 1234, myPort=3305;
      struct sockaddr_in myAddr, serverAddr; struct hostent *hp;
      SOCKET s;
      bool connected = false;
       
      if((retval = WSAStartup(0x202, &wsaData)) != 0){
       printf(“Client: WSAStartup() failed= %d\n”, retval);
       WSACleanup();
       return -1;
      }else
       printf(“Client: WSAStartup() OK.\n”);
    • Isi Address

      if(isalpha(myName[0]))
       hp = gethostbyname(myName);
      else{
       //convert nnn.nn address to usable one
       unsignedint addr = inet_addr(myName);
       hp = gethostbyaddr((char*)&addr, 4, AF_INET);
      }
      if(hp==NULL){
       printf(“Client: Cannot resolve address %s, error=%d\n”, myName, WSAGetLastError());
       WSACleanup();
       exit(1);
      }else
       printf(“Client: gethostbyaddr() is OK.\n”);
       
      //copy resolved my info ke struct sockaddr_in
      memset(&myAddr, 0, sizeof(myAddr));
      memcpy(&(myAddr.sin_addr), hp->h_addr, hp->h_length);
      myAddr.sin_family = hp->h_addrtype;
      myAddr.sin_port = htons(myPort);
       
       
      hp = NULL;
      if(isalpha(serverName[0]))
       hp = gethostbyname(serverName); //server address adalah nama
      else{
       //convert nnn.nn address to usable one
       unsignedint addr = inet_addr(serverName);
       hp = gethostbyaddr((char*)&addr, 4, AF_INET);
      }
      if(hp==NULL){
       printf(“Client: Cannot resolve address %s, error=%d\n”, serverName, WSAGetLastError());
       WSACleanup();
       exit(1);
      }else
       printf(“Client: gethostbyaddr() is OK.\n”);
       
      //copy resolved server info ke struct sockaddr_in
      serverLen = sizeof(serverAddr);
      memset(&serverAddr, 0, sizeof(serverAddr));
      memcpy(&(serverAddr.sin_addr), hp->h_addr, hp->h_length);
      serverAddr.sin_family = hp->h_addrtype;
      serverAddr.sin_port = htons(serverPort);
    • Buat socket

      s = socket(AF_INET, SOCK_DGRAM, 0); //open socket
      if(s == INVALID_SOCKET){
       printf(“Client: Error open socket: %d\n”, WSAGetLastError());
       WSACleanup();
      return -1;
      }else
       printf(“Client: socket() OK \n”);
    • Bind Socket

      if(bind(s, (struct sockaddr*)&myAddr, sizeof(myAddr)) == SOCKET_ERROR){
       printf(“CLient: bind() failed : %d”, WSAGetLastError());
       WSACleanup();
       return -1;
      }else
       printf(“CLient: bind OK\n”);
    • Kirim pesan pertama ke server

      strcpy(buffer, “client VIA coba nyambung”);
      if(sendto(s,buffer, strlen(buffer), 0, (struct sockaddr*)&serverAddr, serverLen) == SOCKET_ERROR){
       printf(“Client: send() failed: error %d\n”, WSAGetLastError());
       WSACleanup();
       return -1;
      }else
       connected = true;
    • Kirim pesan dan nunggu balasan dr server

      while(1){
       memset(buffer, 0, strlen(buffer));
       retval = recvfrom(s, buffer, sizeof(buffer), 0, (struct sockaddr*)&serverAddr, &serverLen);
       if(retval == SOCKET_ERROR){
        //fprintf(stderr, “Server: recv() failed %d\n”, WSAGetLastError());
        closesocket(s);
        continue;
       }elseif(retval==0){
        printf(“CLient: Client closed connection.\n”);
      //Close socket
        closesocket(s);
        connected=false;
        break;
       }
       if(retval>0){
        buffer[retval] = ;
        printf(“[Client] %s:%d : sum=%d bytes, \ndata = %s\n”,
        inet_ntoa(serverAddr.sin_addr), serverAddr.sin_port, retval, buffer);
       }
      //Send msg to server
       if(connected){
        printf(“Input: “);
        gets(buffer);
        if(strlen(buffer) == 0)
         continue;
        if(strcmp(“q”, buffer) == 0){
         connected= false;
         closesocket(s);
         if(WSACleanup()!=0)
          printf(“cleanup gagal!\n”);
      <   return 0;
        }
        retval = sendto(s, buffer, strlen(buffer), 0, (struct sockaddr*)&serverAddr, serverLen);
        if(retval == SOCKET_ERROR)
        printf(“Client: send() failed: error %d\n”, WSAGetLastError());
        else
         printf(“Client: send() OK\n”);
        retval = 0;
       }
       continue;
      }
    • Tutup socket & Cleanning up winsock

      if(hSocket != INVALID_SOCKET)
       closesocket(hSocket);
      if(WSACleanup()!=0)
       cerr << “cleanup gagal!\n”;

     

    Enet Socket UDP

    Server

    • Init Winsock

      #include “enet\enet.h”
      #include <stdio.h>
       
      #pragmacomment(lib, “Ws2_32.lib”)
      #pragmacomment(lib, “WinMM.lib”)
       
      ENetAddress addrs, from;
      int retval;
      WSADATA wsaData;
      ENetBuffer recvBuff;
      char buffer[256];
      recvBuff.data = buffer;
      recvBuff.dataLength = sizeof(buffer);
       
      //request Winshock v 2.2
      if((retval = WSAStartup(0x202, &wsaData)) != 0){
       fprintf(stderr, “Server : WSAStartup() failed : %d\n”, retval);
       WSACleanup();
       return -1;
      }else
       printf(“Server: WSAStartup() sukses\n”);
    • Isi Address

      addrs.port = 1234;
      enet_address_set_host(&addrs, “127.0.0.1”);
    • Buat socket

      ENetSocket s = enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM);
      if(s == ENET_SOCKET_NULL){
       printf(“Server: Gagal mbuat socket : %d\n”, WSAGetLastError());
       WSACleanup();
       return -1;
      }else
       printf(“Server: Berhasil create socket\n”);
    • Bind Socket

      if(enet_socket_bind(s, &addrs) < 0){
       printf(“Server bind() failed : %d”, WSAGetLastError());
       WSACleanup();
      return -1;
      }else
       printf(“Server: bind OK\n”);
    • Nunggu data dari client & Ngirim balasan

      while(1){
       recvBuff.dataLength = sizeof(buffer);
       memset(buffer, 0, sizeof(buffer));
       retval = enet_socket_receive(s, &from, &recvBuff, 1);
       if(retval < 0){
        fprintf(stderr, “Server: recv() failed %d\n”, WSAGetLastError());
        enet_socket_destroy(s);
        continue;
       }elseif(retval == 0){
        printf(“Server: Client closed connection.\n”);
        break;
       }
       
       buffer[retval] = ;
       recvBuff.dataLength = strlen(buffer);
       char hostClient[50];
       enet_address_get_host_ip(&from, hostClient, 50);
       printf(“[Server] %s:%d : %d bytes=%s\n”,
       hostClient, from.port, retval, recvBuff.data);
       
      //connect & Send response back to client
       if(enet_socket_connect(s, &from) < 0)
        printf(“Gagal berkoneksi dengan client.\n”);
       retval = enet_socket_send(s, &from, &recvBuff, 1);
       if(retval < 0)
        printf(“Server: send() failed: error %d\n”, WSAGetLastError());
       continue;
      }
    • Tutup soket & Cleaning up winsock

      enet_socket_destroy(s);
      if(WSACleanup()!=0)
       cerr << “cleanup gagal!\n”;

     
    Client

    • Init Winsock

      #include “enet\enet.h”
      #include <stdio.h>
       
      #pragmacomment(lib, “Ws2_32.lib”)
      #pragmacomment(lib, “WinMM.lib”)
       
      int retval, serverLen;WSADATA wsaData;
      ENetBuffer buffer;
      char* myName = “localhost”; char* serverName = “127.0.0.1”;
      unsignedshort serverPort = 1234, myPort = 3305;
      ENetAddress myAddr, serverAddr;
      ENetSocket s;
      bool connected = false;
       
      if((retval = WSAStartup(0x202, &wsaData)) != 0){
       printf(“Client: WSAStartup() failed= %d\n”, retval);
       WSACleanup();
       return -1;
      }else
       printf(“Client: WSAStartup() OK.\n”);
    • Isi Address

      myAddr.port = myPort;
      enet_address_set_host(&myAddr, myName);
      enet_address_set_host(&serverAddr, serverName);
      serverAddr.port = serverPort;
    • Buat socket

      //Create socket
      s = enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM);
      if(s == ENET_SOCKET_NULL){
       fprintf(stderr, “Client: gagal mbuat socket: %d\n”, WSAGetLastError());
       WSACleanup();
       return -1;
      }else
       printf(“Client: socket_create() OK \n”);
    • Bind Socket

      if(enet_socket_bind(s, &myAddr) < 0){
      printf(“CLient: bind() failed : %d”, WSAGetLastError());
       enet_socket_destroy(s);
       WSACleanup();
       return -1;
      }else
       printf(“CLient: bind OK\n”);
    • Coba terhubung dan Kirim pesan pertama ke server

      if(enet_socket_connect(s, &serverAddr) < 0){
       printf(“Gagal connet ke server: %d\n”, WSAGetLastError());
       enet_socket_destroy(s);
       WSACleanup();
       return -1;
      }
       
      char dataBuff[256];
      strcpy(dataBuff, “client VIA coba nyambung”);
      buffer.data = dataBuff;
      buffer.dataLength = strlen(dataBuff);
      if(enet_socket_send(s, &serverAddr, &buffer, 1) < 0){
       printf(“Client: send() failed: error %d\n”, WSAGetLastError());
       enet_socket_destroy(s);
       WSACleanup();
       return -1;
      }else
       connected = true;
    • Kirim pesan dan nunggu balasan dr server

      while(1){
       buffer.dataLength = sizeof(dataBuff);
       memset(dataBuff, 0, sizeof(dataBuff));
       retval = enet_socket_receive(s, &serverAddr, &buffer, 1);
       if(retval < 0){
        fprintf(stderr, “Server: recv() failed %d\n”, WSAGetLastError());
        enet_socket_destroy(s);
        continue;
       }
       elseif(retval==0){
        printf(“CLient: Client closed connection.\n”);
        connected=false;
        break;
       }
       if(retval>0){
        dataBuff[retval] = ;
        char hostServer[50];
        enet_address_get_host_ip(&serverAddr, hostServer, 50);
        printf(“[Client] %s:%d : %d bytes = %s\n”,
         hostServer, serverAddr.port, retval, (char*)buffer.data);
       }
      //Send msg toserver
       if(connected){
        printf(“Input: “);
        gets(dataBuff);
        if(strlen(dataBuff) == 0)
        continue;
        if(strcmp(“q”, dataBuff) == 0){
         connected= false;
         enet_socket_destroy(s);
         if(WSACleanup()!=0)
         printf(“cleanup gagal!\n”);
         return 0;
        }
        buffer.data = dataBuff;
        buffer.dataLength = strlen(dataBuff);
        retval = enet_socket_send(s, &serverAddr, &buffer, 1);
        if(retval < 0)
         printf(“Client: send() failed: error %d\n”, WSAGetLastError());
        else
         printf(“Client: send() OK\n”);
        retval = 0;
       }
       continue;
      }
    • Tutup socket & Cleanning up winsock

      enet_socket_destroy(s);
      WSACleanup();

     

    Enet Reliable UDP

    Server

    • Init ENet

      #include <enet\enet.h>
       
      #pragma comment(lib, “Ws2_32.lib”)
      #pragma comment(lib, “WinMM.lib”)
       
      enet_initialize();
    • Isi Address

      ENetAddress address;
      ENetHost* server;
      /* Bind the server to the default localhost. A specific host address can be specified by enet_address_set_host (& address, “x.x.x.x”); */
      address.host = ENET_HOST_ANY;
      /* Bind the server to port 1234. */
      address.port = 1234;
    • Buat host

      server = enet_host_create (&address /*addres to bind the server host to*/,
      32 /* allow up to 32 clients and/or outgoing connections */,
      2 /* allow up to 2 channels to be used, 0 and 1 */,
      0 /* assume any amount of incoming bandwidth */,
      0 /* assume any amount of outgoing bandwidth */);
      if(server == NULL){
       printf (“An error occurred while trying to create an ENet server host.\n”);
       exit (EXIT_FAILURE);
      }
    • Nunggu pesan dari client & Ngirim balasan

      while(1){
       while(enet_host_service(server, &event, 15000) > 0){
        switch(event.type){
         case ENET_EVENT_TYPE_CONNECT: //ada client yg nyoba connect
          break;
         case ENET_EVENT_TYPE_RECEIVE:
          if(event.peer->data == NULL){
           event.peer->data = malloc(strlen((char*)event.packet->data)+1); //mendaftarkan user
           strcpy((char*)event.peer->data, (char*)event.packet->data);
           sprintf(buffer, “%s has connected\n”, (char*)event.packet->data);
           packet = enet_packet_create(buffer, strlen(buffer)+1, 0);
           enet_host_broadcast(server, 1, packet);
           enet_host_flush(server);
           printf(“%s”, buffer);
          }else{
           //kirim msg yg masuk ke all client keculi pengirimnya :
           for(i=0; i<server->connectedPeers; i++){
            if(&server->peers[i] != event.peer){
             sprintf(buffer, “%s: %s\n”, (char*)event.peer->data, (char*)event.packet->data);
             packet = enet_packet_create(buffer, strlen(buffer)+1, 0);
             enet_peer_send(&server->peers[i], 0, packet);
             enet_host_flush(server);
             printf(“%s”, buffer);
            }
           }
          }
          break;
         case ENET_EVENT_TYPE_DISCONNECT:
          sprintf(buffer, “%s has disconnected.\n”, (char*)event.peer->data);
          packet = enet_packet_create(buffer, strlen(buffer)+1, 0);
          enet_host_broadcast(server, 1, packet);
          free(event.peer->data);
          event.peer->data = NULL;
          printf(“%s”, buffer);
          break;
         default:
          printf(“Tick tock.\n”);
          break;
        }
       }
      }
    • Tutup soket & Cleaning up winsock

      enet_host_destroy(server);
      enet_deinitialize();

     
    Client

    • Init ENet

      #include <enet\enet.h>
       
      #pragma comment(lib, “Ws2_32.lib”)
      #pragma comment(lib, “WinMM.lib”)
       
      enet_initialize();
    • Isi Address Server

      ENetAddress address;
      ENetEvent event;
      ENetPeer *peer;
      /* Connect to some.server.net:1234. */
      enet_address_set_host(& address, “some.server.net”);
      address.port = 1234;
    • Buat host

      ENetHost* client;
      client = enet_host_create (NULL /* create a client host */,
      1 /* only allow 1 outgoing connection */,
      2 /* allow up 2 channels to be used, 0 and 1 */,
      57600 / 8 /* 56K modem with 56 Kbps downstream bandwidth */,
      14400 / 8 /* 56K modem with 14 Kbps upstream bandwidth */);
      if(client == NULL){
       printf(“An error occurred while trying to create an ENet client host.\n”);
       exit (EXIT_FAILURE);
      }
    • Terhubung ke server

      /* Initiate the connection, allocating the two channels 0 and 1. */
      peer = enet_host_connect (client, & address, 2, 0);
      if(peer == NULL){
       printf (“No available peers for initiating an ENet connection.\n”);
       exit (EXIT_FAILURE);
      }
      /* Wait up to 5 seconds for the connection attempt to succeed. */
      if(enet_host_service(client, &event, 5000)>0 &&
      event.type==ENET_EVENT_TYPE_CONNECT){
       puts (“Connection to some.server.net:1234 succeeded.”);
      } else {
       /* Either the 5 seconds are up or a disconnect event was received. Reset the peer in the event the 5 seconds had run out without any significant event. */
       enet_peer_reset(peer);
       puts (“Connection to some.server.net:1234 failed.”);
      }
    • Kirim pesan pertama ke server

      /* Create a reliable packet of size 7 containing “packet” */
      ENetPacket* packet = enet_packet_create (“packet”, strlen(“packet”)+1, ENET_PACKET_FLAG_RELIABLE);
      /*Extend the packet so and append the string “foo”, so it now contains “packetfoo”*/
      enet_packet_resize(packet, strlen (“packetfoo”) + 1);
      strcpy (& packet -> data [strlen (“packet”)], “foo”);
      /* Send the packet to the peer over channel id 0. One could also broadcast the packet by enet_host_broadcast (host, 0, packet); */
      enet_peer_send(peer, 0, packet);
       
      /* One could just use enet_host_service() instead. */
      enet_host_flush (host);
    • Kirim pesan dan nunggu balasan server

      if(enet_host_service(client, &event, 15000) > 0 && event.type == ENET_EVENT_TYPE_CONNECT){
       char namaHost[256];
       int hasil = enet_address_get_host(&(event.peer->address), namaHost, 256);
       printf(“Client: got new connection from %d : %s\n”, hasil, namaHost);
       //kirim notifikasi bahwa udah berhasil connect :
       strcpy(msg, “okta via”);
       paket = enet_packet_create(msg, strlen(msg)+1, ENET_PACKET_FLAG_RELIABLE);
       enet_peer_send(peer, 0, paket);
       printf(“Sekarang ngirim pesan : \n\t%s\n”, msg);
      }
      int eventStatus=1;
      while(1){
       eventStatus = enet_host_service(client, &event, 15000);
       //if had some event
       if(eventStatus>0){
        switch(event.type){
         case ENET_EVENT_TYPE_RECEIVE:
          printf(“Client: msg from server = %s”, event.packet->data);
          enet_peer_send(peer, 0, event.packet);
          break;
         case ENET_EVENT_TYPE_DISCONNECT:
          printf(“Client: %s disconnected.\n”, event.peer->data);
          //reset client info
          event.peer->data = NULL;
          break;
        }
       }
       printf(“say>”); gets(msg);
       if(strlen(msg)>0){
        ENetPacket *packet = enet_packet_create(msg, strlen(msg)+1, ENET_PACKET_FLAG_RELIABLE);
        enet_peer_send(peer, 0, packet);
       }
      }
    • DisconnectingENet peer & Deinit ENet

      enet_peer_disconnect (peer, 0);
      enet_host_destroy(server);
      enet_deinitialize();

     
    Selesai…
    Semoga bermanfaat…😉

    Menghalau Munculnya Jendela Unhandle Exception

    Masih di awal bulan Shafar 1436H / Akhir bulan november 2014M, setelah selesai membuat windows service ada tambahan tugas untuk mencegah munculnya jendela Unhandle Exception jika terjadi error dari service yang sedang berjalan dan langsung melakukan restart terhadap service tersebut, intinya : tidak perlu harus menutup jendela Unhandle Exception terlebih dahulu baru service melakukan restart.

    Ada beberapa cara yang berhasil ditemukan, yaitu dengan :

    1. Menggunakan Callback Unhandle Exception
      LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter(
       _In_ LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter
      );
      Fungsi ini diletakkan sebelum proses inisialisasi, parameternya adalah fungsi callback yang akan dipanggil jika terjadi kesalahan. Pada fungsi callback inilah bisa ditambahkan code untuk menangani error, misalnya menampilkan keterangan error yang terjadi dengan menampilkan dialog box, diakhir fungsi biasanya mengembalikan nilai = EXCEPTION_EXECUTE_HANDLER yang memberitahukan bahwa kesalah yang terjadi sudah ditangani. Penjelasan lebih lengkap bisa dilihat disini dan contoh penggunaannya disini.

    2. Melakukan Setting Mode Error
      UINT WINAPI SetErrorMode(
       _In_ UINT uMode
      );
      Parameter uMode adalah mode error , bisa berisi salah satu atau lebih nilai berikut :

      0 Default system, menampilkan semua dialog box error.
      SEM_FAILCRITICALERRORS
      0x0001
      Tidak menampilkan message box critical-error-handler, tapi tetap mengirimkan error ke proses pemanggilan.
      SEM_NOALIGNMENTFAULTEXCEPT
      0x0004
      System secara otomatis memperbaiki kesalahan memory aligment dan tidak menampakkannya ke aplikasi. Digunakan untuk proses pemanggilan dan tiap proses turunan. Hanya digunakan untuk arsitektur proses tertentu.
      SEM_NOGPFAULTERRORBOX
      0x0002
      Tidak menampilkan dialog box Windows Error Reporting
      SEM_NOOPENFILEERRORBOX
      0x8000
      Tidak menampilkan message box saat gagal mencari file, tapi tetep mengirimkan error ke proses pemanggilan.

      Fungsi ini biasanya diletakkan diawal program sebelum proses inisialisai dilakukan.

    3. Menambahkan code __try __exception
      __try{
       //guarded code
      }
      __except(1){
       //handler
      }
      Penjelasan dan contohnya bisa dilihat disini

     

    Cara yang dipilih dan dirasa paling sesuai dengan kebutuhan kali ini adalah yang no.1 dan no.2, karena ingin mencegah semua dialog box error yang muncul dan melakukan penanganan dengan restart service. Digunakan 2 cara sekaligus, tujuannya agar jika ‘SEH Exception’ atau ‘C++ Exception’ tidak tertangkap oleh fungsi callback UnhandledExceptionFilter bisa ditangani dengan SetErrorMode. Buat dulu fungsi callback-nya dan isi dengan penanganan yang ingin dilakukan dan akhiri fungsi dengan mengembalikan EXCEPTION_EXECUTE_HANDLER yang menyatakan exception sudah tertangani. Kerangka codenya :

    long __stdcall UnhandledExceptionCallback(_EXCEPTION_POINTERS* pExceptPtrs)
    {
     char errMsg[1024];
     sprintf(errMsg, “\n\tAn exception occured which wasnt handled!\n\tCode: 0x%08X\n\tOffset: 0x%08X\n\tAddress: 0x%08X”, pExceptPtrs->ExceptionRecord->ExceptionCode, (char*)((DWORD)pExceptPtrs->ExceptionRecord->ExceptionAddress – (DWORD)GetModuleHandle(NULL)), (DWORD)GetModuleHandle(NULL));
     GenesisAppParams::Global->pLogger->Log(&host, LOG_LEVEL_DEBUG, errMsg);

     //Stop service status
     //…

     //Start service
     //…

     //Kembalikan nilai yang menyatakan exception sudah ditangani.
     return EXCEPTION_EXECUTE_HANDLER;
    }

    Code yang perlu ditambahkan sebelum proses inisialisasi adalah :
    SetUnhandledExceptionFilter(UnhandledExceptionCallback);
    SetErrorMode(
     SEM_NOGPFAULTERRORBOX |
     SEM_FAILCRITICALERRORS |
     SEM_NOOPENFILEERRORBOX
    );

    Code tersebut ditambahkan sebelum proses init service, sehingga kerangka code untuk fungsi ServiceMain (Entry Point of Service) menjadi :

    //setting status service
    //…

    //registering control handler
    //…

    SetUnhandledExceptionFilter(UnhandledExceptionCallback);

    SetErrorMode(
     SEM_NOGPFAULTERRORBOX |
     SEM_FAILCRITICALERRORS |
     SEM_NOOPENFILEERRORBOX
    );
    //init service
    //…

    //lapor status running ke SCM.
    //…

    //panggil proses yang ingin dijalankan service.
    //ex : app.Run();

    while(ServiceStatus.dwCurrentState == SERVICE_RUNNING){

     //apa yang ingin dilakukan selama service berjalan.
     //ex: cetak info
    }

    Clean dan Rebuild project aplikasi service-nya, pindahkan file hasil eksekusi (file .exe) ke direktori tempat service akan running. Jika create service menggunakan aplikasi installer maka bisa dilihat di RegistryEditor(Start > Run > regedt32 > OK) > pada bagian kiri pilih “My Computer” > HKEY_LOCAL_MACHINE > SYSTEM > CurrentControlSet > Services > “CetakAngka”[NamaService] > pada bagian kanan lokasi file .exe terdapat pada “ImagePath”; terakhir restart service. Saat service sedang running dan terjadi error, jendela Unhandle Exception tidak akan muncul dan service secara otomatis langsung akan melakukan restart.

    Selesai…

    Semoga bermanfaat ~{^v^}~

    Create Windows Service in C++

    Di awal bulan Shafar 1436H ini dapat tugas bagaimana menjadikan aplikasi console menjadi Windows service dengan bahasa C++ .NET menggunakan WinAPI SCM(Service Control Manager) yang merupakan proses yang mengatur semua service yang ada dalam sistem. Setelah cari sana sini seharian ketemulah sumber yang penjelasannya cukup lengkap bagi pemula, silahkan di cek sendiri disini[http://www.devx.com/cplus/Article/9857]. Sesuai dengan sumber tersebut, contoh berikut adalah windows service yang akan menuliskan ke file log angka dari 0 yang bertambah satu setiap 15 detik sekali.

    Aplikasi yang dibangun untuk berfungsi sebagai service memerlukan 3 fungsi utama, yaitu :

    • Entry Point of Programs (main app)
    • Entry Point of Service
    • Service Control Handler

    Tahapannya :

    • Buat project dengan tipe “Empty Win32 Console Application“. Tambahkan file .cpp dan beri nama Program.
    • Pada file Program.cpp tersebut tambahkan library yang diperlukan, yaitu:
      #include <Windows.h> //unt mbuat service
      #include <stdio.h> //nulis ke file
      #include <tchar.h> //convert ke TCHAR
    • Deklarasikan variable global dan fungsi utama service:
      SERVICE_STATUS ServiceStatus;//info karakter service dan state sekarang
      SERVICE_STATUS_HANDLE hStatus;//status handle
      void ServiceMain(int argc, char** argv); //Entry Point of Service
      void ControlHandler(DWORD request); //Service Control Handler
    • Buat fungsi untuk menulis data ke file log; pada code berikut file log diberi nama “StatusMemory.log” yang diletakkan pada direktori “C:” :
      int WriteToLog(char* str){
       FILE* log;
       log = fopen(“C:\\StatusMemory.log”, “a+”);
       if(log == NULL)
        return -1;
       fprintf(log, “%s\n”, str);
       fclose(log);
       return 0;
      }
    • Buat fungsi main yang merupakan “Entry point of programs” dengan code :
      void main(void){
       SERVICE_TABLE_ENTRY ServiceTable[] = {
        {_T(“StatusMemory”) , (LPSERVICE_MAIN_FUNCTION)ServiceMain},
        {NULL, NULL}
       };
       
       //start control dispatcher thread for our service
       StartServiceCtrlDispatcher(ServiceTable);
      }
    • Definisikan fungsi ServiceMain yang merupakan “Entry Point of Service” :
      void ServiceMain(int argc, char** argv){
       ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; //tipe service
       ServiceStatus.dwCurrentState = SERVICE_START_PENDING; //state service sekarang. Jika init service blm selesai, set status=SERVICE_START_PENDING
       ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN;  //kontrol service apa yg diperbolehkan untuk diinfokan ke SCM
       ServiceStatus.dwWin32ExitCode = 0;
       ServiceStatus.dwServiceSpecificExitCode = 0;
       ServiceStatus.dwCheckPoint = 0;
       ServiceStatus.dwWaitHint = 0;
       hStatus = RegisterServiceCtrlHandler( _T(“CetakAngka”), (LPHANDLER_FUNCTION)ControlHandler );
       if(hStatus == (SERVICE_STATUS_HANDLE)0){ //registering control handler failed
        return;
       }
       //init service
       if(WriteToLog(“Mulai Mencetak Angka.”)){ //initialized failed
        ServiceStatus.dwCurrentState = SERVICE_STOPPED;
        ServiceStatus.dwWin32ExitCode = -1;
        SetServiceStatus(hStatus, &ServiceStatus);
        return;
       }
       //lapor status running ke SCM.
       ServiceStatus.dwCurrentState = SERVICE_RUNNING;
       SetServiceStatus(hStatus, &ServiceStatus);
       int count = 0, result;
       //loop of service:
       while(ServiceStatus.dwCurrentState == SERVICE_RUNNING){
        time_t now = time(NULL);
        struct tm* timeInfo = localtime(&now);
        char buffer[256], temp[24];
        strftime(temp, 23, “%Y/%m/%d %H:%M:%S : “, timeInfo);
        sprintf(buffer, “%s%d”, temp, count++);
        result = WriteToLog(buffer);
        if(result){
         ServiceStatus.dwCurrentState = SERVICE_STOPPED;
         ServiceStatus.dwWin32ExitCode = -1;
         SetServiceStatus(hStatus, &ServiceStatus);
         return;
        }
        Sleep(15000);
       }
       return;
      }
      RegisterServiceCtrlHandler : Fungsi pertama yang dipanggil untuk mendaftarkan aplikasi sebagai service dengan parameter nama service dan pointer dari fungsi control event handler.
      Setelah register service berhasil, kirimkan status server = running ke SCM dan panggil proses utama yang harus dilakukan service sebelum perulangan while atau didalamnya seperti kerangka berikut ini :
      //lapor status running ke SCM.
      ServiceStatus.dwCurrentState = SERVICE_RUNNING;
      SetServiceStatus(hStatus, &ServiceStatus);
       
      //panggil proses yang ingin dijalankan service.
      //ex : app.Run();
       
      while(ServiceStatus.dwCurrentState == SERVICE_RUNNING){
       //apa yang ingin dilakukan selama service berjalan.
       //ex: cetak info
      }
    • Langkah terakhir definisikan fungsi ControlHandler yang merupakan “Control Handler of Service” :
      void ControlHandler(DWORD request){
       switch(request){
        case SERVICE_CONTROL_STOP:
        case SERVICE_CONTROL_SHUTDOWN:
         WriteToLog(“CetakAngka Berhenti.”);
         ServiceStatus.dwWin32ExitCode = 0;
         ServiceStatus.dwCurrentState = SERVICE_STOPPED;
         SetServiceStatus(hStatus, &ServiceStatus);
         return;
        default:
         break;
       }
       //report current status:
       SetServiceStatus(hStatus, &ServiceStatus);
       
       return;
      }
      Fungsi handler diatas menangani event yang telah diijinkan. Sebelum mengirimkan status service saat ini ke SCM, tambahkan code penanganan yang diinginkan.
       

    Applikasi Windows Service selesai. Untuk mendaftarkan service bisa dengan menggunakan command prompt : Start > Run > ketikkan “cmd“. Saat jendela command prompt terbuka ketikkan perintah :
    sc [spasi] service [spasi] [namaService] [spasi] binpath= [spasi] [path AppService.exe berada]
    jika berhasil akan muncul pesan “[SC] CreateService SUCCESS“, contohnya :
    C:\> sc create CetakAngka binpath= “C:\ServiceCetakAngka.exe”

    Cara menjalankan service : Start > Run > ketikkan “service.msc” > muncul jendela Services > pilih service yang baru dibuat (ex: CetakAngka) > tekan linkStart“. Atau bisa juga dengan perintah di command prompt dengan perintah :
    sc [spasi] start [spasi] [namaService]
    jika berhasil di-start akan muncul info dari status service, contohnya :
    C:\> sc start CetakAngka

    Untuk menghapus service yang sudah didaftarkan bisa menggunakan command prompt dengan perintah :
    sc [spasi] delete [spasi] [namaService]
    jika berhasil akan muncul pesan “[SC] DeleteService SUCCESS“, contohnya :
    C:\> sc delete CetakAngka

    Cara lain untuk mendaftarkan service adalah dengan membuatkan aplikasi installer-nya. Tahapan pembuatannya adalah :

    • Pilih project dengan tipe “Empty Win32 Console Application“.
    • Tambahkan file .cpp dan beri nama Program dan masukkan library :
      #include <Windows.h>
      #include <stdio.h>
      #include <tchar.h>
    • Tambahkan fungsi int main() dan isi dengan code berikut :
      SC_HANDLE scManager, scService;
      SERVICE_STATUS sStatus;
      DWORD dwOldCheckPoint, dwStartTickCount, dwWaitTime;
       
      TCHAR Path[1024];
      GetModuleFileName(NULL,Path, 1024);
      char tempPath[1024];
      int i, index=0;
      for(i=lstrlen(Path); i>0; i–){
       if(Path[i] == ‘\\’){
        Path[i+1] = ;
        break;
       }
      }
       
      lstrcat(Path, _T(“ServiceCetakAngka.exe”)); //nama file service
      LPCTSTR lpszBinaryPathName = Path; //lokasi file .exe
      LPCTSTR lpszDisplayName = _T(“Cetak Angka”); //service display name
      LPCTSTR lpszServiceName = _T(“CetakAngka”); // Registry Subkey
       
      scManager = OpenSCManager(
       NULL, //local machine
       NULL, //service_active_database, database terbuka secara default
       SC_MANAGER_ALL_ACCESS
      );
       
      if(scManager == NULL)
       printf(“OpenSCManager() failed, error: %d.\n”, GetLastError());
      else
       printf(“OpenSCManager() OK.\n”);
      Sleep(1000);
       
      // Create/install service
      scService = CreateService(
       scManager, //SCMan dB
       lpszServiceName, //nama service
       lpszDisplayName, //nama service yg tampil
       SERVICE_ALL_ACCESS, //hak akses

       SERVICE_WIN32_OWN_PROCESS, //tipe service
       SERVICE_DEMAND_START, //tipe start
       SERVICE_ERROR_NORMAL, //tipe error control
       lpszBinaryPathName, //service’s binary
       NULL, // no load ordering group
       NULL, // no tag identifier
       NULL, // no dependencies
       NULL, // LocalSystem account
       NULL // no password
      );
       
      if(scService == NULL){
       printf(“CreateService() failed.\n”);
       Sleep(3000);
       return FALSE;
      }
      else {
       printf(“CreateService() OK.\n”);
       
       SERVICE_FAILURE_ACTIONS sFailAction;
       SC_ACTION failActions[3] =
        {
         {SC_ACTION_RESTART, 3000}, //tunggu 3 detik
         {SC_ACTION_RESTART, 5000}, // tunggu 5 detik
         {SC_ACTION_NONE, 15000} //tunggu 15 detik
        };
       sFailAction.dwResetPeriod = 0; //Reset failures counter, in Seconds.
       sFailAction.lpCommand = NULL; //command to perform due to service failure
       sFailAction.lpRebootMsg = NULL; //msg during rebooting computer due to service failure
       sFailAction.cActions = 3; //jumlah event gagal yang ditangani
       sFailAction.lpsaActions = failActions;
       ChangeServiceConfig2(scService, SERVICE_CONFIG_FAILURE_ACTIONS, &sFailAction);
       
       //auto start service after installation
       if(!StartService(
        scService, //service handler
        0, //jumlah argumen
        NULL)) //tidak ada argumen
       {
        printf(“StartService() failed, error: %d.\n”, GetLastError());
        return 0;
       }
       else
        printf(“StartService(), service start pending.\n”);
       
       //cek status sampai != start pending
       if(!QueryServiceStatus(
        scService, //service handler
        &sStatus)) //alamat dari struktur status info
       {
        printf(“StartService(), service still start pending.\n”);
        return 0;
       }
       else
        printf(“StartService(), service no longer start pending.\n”);
       
       //simpan jumlah tick & init checkpoint
       dwStartTickCount = GetTickCount();
       dwOldCheckPoint = sStatus.dwCheckPoint;
       while(sStatus.dwCurrentState == SERVICE_START_PENDING){
        printf(“Wait Hint: %d\n”, sStatus.dwWaitHint);
       
        //set waktu tunggu antara 1 s/d 10 detik
        dwWaitTime = sStatus.dwWaitHint/10;
        if(dwWaitTime < 1000) dwWaitTime = 1000;
        elseif(dwWaitTime > 10000) dwWaitTime = 10000;

       
        //cek status lagi
        if(!QueryServiceStatus(
         scService, //service handler
         &sStatus)) //address of structure
         break;
        if(sStatus.dwCheckPoint > dwOldCheckPoint){
         //service berprogress…
         printf(“Service starting in progress…\n”);
         dwStartTickCount = GetTickCount();
         dwOldCheckPoint = sStatus.dwCheckPoint;
        }
        else {
         if((GetTickCount()-dwStartTickCount) > sStatus.dwWaitHint){
          //tidak ada progress
          printf(“Well, starting the service looks no progress…\n”);
          break;
         }
        }
       }
       
       if (CloseServiceHandle(scService) == 0)
        printf(“CloseServiceHandle() failed, error: %d.\n”, GetLastError());
       else
        printf(“CloseServiceHandle() is OK.\n);
       
       if(sStatus.dwCurrentState == SERVICE_RUNNING){
        printf(“StartService(), service successfully started.\n”);
        Sleep(3000);
        return 1;
       }
       else {
        printf(“\nService not started.\n Current State: %d\n Exit Code: %d\n Service Specific Exit Code: %d\n Check Point: %d\n Wait Hint: %d\n”, sStatus.dwCurrentState, sStatus.dwWin32ExitCode, sStatus.dwServiceSpecificExitCode, sStatus.dwCheckPoint, sStatus.dwWaitHint);
        Sleep(3000);
        return 0;
       }
      }
       
      Sleep(3000);
      return 0;

    Ringkasan code di atas :

    1. Mendapatkan tempat file installer service .exe berada, sebelumnya salin terlebih dahulu file ServiceCetakAngka.exe ke direktori yang sama dengan installer service .exe berada.
    2. Membuka handle SCM.
    3. Install atau Mbuat service.
    4. Lakukan pengaturan jika terjadi kesalahan. Pada contoh ini lakukan restart service jika ada unhandle exception atau error yang muncul.
    5. Jalankan service.
    6. Cek status service, untuk mengetahui apakah service berhasil dijalankan.
    7. Tutup handler service (kembalian dari tahap no 3).

    Cara menginstall service menggunakan program diatas adalah dengan menjalankan file exe hasil dari project installer tersebut, maka secara otomatis service akan terdaftar dan berjalan.

    Selesai.
     
    Semoga bermanfaat ~{^v^}~

    Petuah Buat Hafidz/Hafidzah – 2

    Bismillah…

    Pada Senin 9 Ramadhan Ustadz Huda berbagi ilmu dan pengalaman menghafalnya. Secara garis besar isinya sebagai berikut :

    • Inti menghafal Al-Quran itu SABAR. Sabar untuk menahan tidak nambah hapalan baru guna memantapkan hafalan sekarang & hafalan lama; Sabar untuk selalu istiqomah me-muroja`ah hafalan dan menambahnya.
    • Menurut beliau kemampuan orang dewasa untuk menghafal itu harusnya lebih mudah dari anak kecil walau mudah juga ilangnya seperti pepatah ‘Belajar diwaktu muda, bagai menulis diatas batu. Belajar sesudah dewasa bagai mengukir diatas air’. Pesan beliau Selalu berani nambah hafalan baru & terus istiqomah menjaganya dengan selalu me-muroja`ah hafalan😉.
    • Cara menjaga hafalan :

      • Kategorikan hafalan kita menjadi 2 kategori.

        Gol A : Hafalan dengan kualitas terbaik, artinya udah hafal diluar kepala / jarang bisa lupa. Misalnya : Qs An-Nas sampai QS al Balad.

        Gol B : Hafalan yg termasuk baru (bukan tambahan baru), artinya yang masih belum mantap dan sering lupa. Misalnya : Qs Al Fajr sampai QS Abasa.

      • Gol A kita muroja`ah dengan nyambi kerjaan lain ato bukan waktu luang / khusus, karena peluang lupa / salahnya kecil juga supaya bisa hemat waktu. Misalnya: sambil berkendara, nyapu-nyapu, cuci-cuci.

        Gol B kita muroja`ah di waktu luang/khusus agar konsen dan bisa memperbaiki jika ada yang lupa ato salah, jika udah mantap segera pindahkan ke Gol A. Kata beliau tenang saja… Gol B tidak mungkin habis karena selalu bertambah jika kita nambah hafalan baru😀.

    • Cara menambah hafalan baru yang beliau anjurkan :

      • Pada malam hari sebelum tidur, baca halaman yg ingin dihafal beberapa kali g mutlak hrs 20x🙂. Yang penting TEMUKAN POINTER-POINTER yang memudahkan kita untuk menghapal.

        Beliau mencontohkan QS Al Fajr : 5 ayat pertama berakhiran ____JR terus…. 7 ayat selanjutnya berakhiran dengan ____D, cari ayat yang hampir mirip dengan yang sudah dihafal sebelumnya sehingga menghafalnya nanti lebih dikit karena tinggal menghafal bagian yang berbeda saja.

      • Dari target yang kita buat, g harus 100% kita hafal. Klw sudah capek tutup mushaf dan tidurlah….
      • Besok pagi sebelum ato setelah solat Subuh buka lagi mushafnya dan mulailah mencoba menghafal 100% sesuai target.

      Menurut pengalaman beliau, menghafal di pagi hari akan terasa lebih cepat ketimbang memaksakan diri tetap menghapal pada malam sebelumnya, karena kita sudah punya pointer untuk menghapal.

      Beliau selama 2 thn bisa hafal 20juz dengan kualitas yg baik. Berati 1thn 10juz ~ 1bln hampir 1juz…. Masya Allah.. Semoga kita juga diijikan oleh Allah untuk bisa menghapalnya…. Aamiin.

    • Bagi yang bekerja di kantor, ada cara yang dianjurkan beliau :

      • Sebisa mungkin kita punya salinan halaman yang sedang kita hafal dan letakkan di atas meja ato bisa juga menggunakan aplikasi yang ada di hp ato komputer, terserah.
      • Terus… buat alarm tiap 1 jam, kalau alarm bunyi kita cicil ngapalin 1 ayat ato 1 baris dengan liat salinan sambil dibaca dan terus diulang-ulang beberapa kali dengan tetap menyelesaikan tugas kerjaan yang ada. Ato bisa juga dengan mendengarkan ayat tersebut berkali-kali menggunakan audio yang ada.
      • Lakukan no.2 tiap jam. Pada sore hari di jam terakhir, tidak perlu menambah hafalan cukup mengulang hafalan yang dikumpulkan dr pagi. Setidaknya kita bisa hafal 5-7 ayat.
      • Nanti diwaktu luang / khusus yang disediakan untuk menghafal, mantapkan hafalan dari kantor tersebut hingga bisa memasukkannya ke Gol B.

      Teorinya ok nih… tapi implementasinya butuh niat yang kuat dan ke-istiqomah-an yang besar:D. Semoga kita semua termasuk orang-orang yang diijinkan Allah untuk memilikinya, Aamiin.

    Semoga Bermanfaat (^u^)

    Follow

    Get every new post delivered to your Inbox.