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...
08 April 2009
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...
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...
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.

Baca selengkapnya...
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.
- Pada IDE Delphi, tentukan form turunan yang ingin dikembalikan dan buka form tersebut.
- Selanjutnya tentukan kontrol yang ingin dikembalikan kondisinya.
- Pada kontrol tersebut klik kanan dan pilih “Revert to Inherited”.
Baca selengkapnya...
04 April 2009
Masalah Kegemukan pada Program Delphi
Ketik sana ketik sini, compile program, ok, dan jadilah satu program aplikasi (exe) pada Delphi. Mudah, simpel, karena semua komponen, unit, form yang kita buat dilebur jadi satu menjadi sebuah file executable. File jadi berukuran besar untuk program yang kompleks dan butuh berbagai macam komponen. Memang bagi sebagian orang tidak masalah, tapi tidak dengan aku. Ukuran file yang besarnya hingga belasan MB sulit didistribusikan ke client apalagi tempatnya berjauhan, di luar kota bahkan ada yang di luar pulau. Dikirim melalui paket baru bisa sampai besoknya belum lagi biaya yang bisa melebihi penghasilan jika kirim berulang-ulang. Istilahnya lebih besar pasak dari pada tiang, bisa-bisa bukannya mendapatkan keuntungan malah ngutang melulu.
Untuk mengatasi masalah ini, biasanya aku mengirimkan file menggunakan akses internet. Inipun juga bermasalah, soal ukuran yang relatif besar jika di upload. Apalagi dengan akses internet yang “angin-anginan” dan “pas-pasan”, bisa-bisa nggak nyampai ke tujuan sampe hari kiamat. Waduh repot juga yah, sudah jadi masalah cukup lama bagi aku.

Untungnya hal tersebut kini bisa teratasi. Program Delphi ternyata bisa dipecah. Untuk komponen pendukung tidak jadi satu dengan file executable. Jika kita pernah mendengar istilah “package” atau Borland Package Library (BPL), bisa jadi ini adalah solusi bagi anda yang mengalami masalah sama dengan aku dulunya. Semua komponen yang kita pakai di Delphi merupakan package. Jika kita memakai komponen TForm, TEdit, dan lain sebagainya, tanpa disadari kita memakai package. Jadi package ini sama seperti DLL, tapi hanya bisa diakses dari lingkungan Delphi.
Perbedaan ukuran file sebelum dan sesudah memakai cara ini sangat signifikan. Dari ukuran yang dulunya sampai belasan MB kini tidak sampai 2 MB. Package itu sendiri merupakan file terpisah yang mempunyai ekstensi .bpl dan sudah tersedia jika kita mengistall Delphi atau jika kita menginstall komponen lain. Package dari Delphi biasanya terdapat pada direktori “$(DELPHI)\Bin”.
Prakteknya kita akan mencoba membuat aplikasi baru di Delphi. Disini kita akan coba membuat aplikasi kosong dan membandingkan ukurannya jika komponen/package dijadikan satu atau terpisah dengan file executable yang kita buat. Jika kita compile aplikasi kosong tersebut dan melihat ukuran file exe yang dihasilkan, kira-kira akan berukuran sekitar 359 KB (Delphi 7). Kemudian dari menu Project->Options dari tab Packages centang pilihan “Build with runtime packages”, tekan OK dan compile ulang. Jika kita lihat ukuran file exe yang dihasilkan akan menjadi sekitar 16,5 KB!
Proses compile pertama yang menghasilkan file exe yang besar itu dinamakan static linking, dimana semua kode-kode program yang dibutuhkan aplikasi dijadikan satu oleh proses linking menjadi satu file dan ini yang menjadi pilihan default waktu kita membuat aplikasi baru. Proses kedua yang menghasilkan file exe yang lebih kecil dinamakan dynamic linking yang mirip dengan DLL standar. Pada dynamic linking, package yang diperlukan akan diload pada saat diperlukan. Dan perlu kita ketahui proses dynamic linking tersebut dijalankan secara otomatis tanpa diperlukan tambahan kode program. Proses distribusi aplikasi dengan dynamic linking perlu menyertakan file package (*.bpl) yang diperlukan secara terpisah dan diletakkan pada suatu direktori yang terdaftar pada environment variables.
Baca selengkapnya...
Untuk mengatasi masalah ini, biasanya aku mengirimkan file menggunakan akses internet. Inipun juga bermasalah, soal ukuran yang relatif besar jika di upload. Apalagi dengan akses internet yang “angin-anginan” dan “pas-pasan”, bisa-bisa nggak nyampai ke tujuan sampe hari kiamat. Waduh repot juga yah, sudah jadi masalah cukup lama bagi aku.
Untungnya hal tersebut kini bisa teratasi. Program Delphi ternyata bisa dipecah. Untuk komponen pendukung tidak jadi satu dengan file executable. Jika kita pernah mendengar istilah “package” atau Borland Package Library (BPL), bisa jadi ini adalah solusi bagi anda yang mengalami masalah sama dengan aku dulunya. Semua komponen yang kita pakai di Delphi merupakan package. Jika kita memakai komponen TForm, TEdit, dan lain sebagainya, tanpa disadari kita memakai package. Jadi package ini sama seperti DLL, tapi hanya bisa diakses dari lingkungan Delphi.
Perbedaan ukuran file sebelum dan sesudah memakai cara ini sangat signifikan. Dari ukuran yang dulunya sampai belasan MB kini tidak sampai 2 MB. Package itu sendiri merupakan file terpisah yang mempunyai ekstensi .bpl dan sudah tersedia jika kita mengistall Delphi atau jika kita menginstall komponen lain. Package dari Delphi biasanya terdapat pada direktori “$(DELPHI)\Bin”.
Prakteknya kita akan mencoba membuat aplikasi baru di Delphi. Disini kita akan coba membuat aplikasi kosong dan membandingkan ukurannya jika komponen/package dijadikan satu atau terpisah dengan file executable yang kita buat. Jika kita compile aplikasi kosong tersebut dan melihat ukuran file exe yang dihasilkan, kira-kira akan berukuran sekitar 359 KB (Delphi 7). Kemudian dari menu Project->Options dari tab Packages centang pilihan “Build with runtime packages”, tekan OK dan compile ulang. Jika kita lihat ukuran file exe yang dihasilkan akan menjadi sekitar 16,5 KB!
Proses compile pertama yang menghasilkan file exe yang besar itu dinamakan static linking, dimana semua kode-kode program yang dibutuhkan aplikasi dijadikan satu oleh proses linking menjadi satu file dan ini yang menjadi pilihan default waktu kita membuat aplikasi baru. Proses kedua yang menghasilkan file exe yang lebih kecil dinamakan dynamic linking yang mirip dengan DLL standar. Pada dynamic linking, package yang diperlukan akan diload pada saat diperlukan. Dan perlu kita ketahui proses dynamic linking tersebut dijalankan secara otomatis tanpa diperlukan tambahan kode program. Proses distribusi aplikasi dengan dynamic linking perlu menyertakan file package (*.bpl) yang diperlukan secara terpisah dan diletakkan pada suatu direktori yang terdaftar pada environment variables.
Baca selengkapnya...
03 April 2009
Mengganti Authentication Mode pada SQL Server dari Skrip SQL
Buat komputer lokal bisa set Authentication Mode dengan akses registry dari Delphi, terus gimana kalo akses dari komputer lain? Salah satu cara adalah dengan menggunakan extended stored procedure. Extended stored procedure yang diperlukan adalah xp_regread dan xp_regwrite yang tidak didokumentasikan tapi ada pada database master. Langkahnya sama dengan posting sebelumnya. Berikut ini adalah stored procedure untuk membaca dan mengganti nilai dari registry. Stored procedure dengan nama uspSetSQLServerAuthMode mempunyai satu parameter tipe integer. Jika parameter tersebut diisi 1 maka modenya adalah SQL Server and Windows Authentication mode, selain nilai 1 modenya adalah Windows Authentication mode.
CREATE PROCEDURE uspSetSQLServerAuthMode(@MixedMode INT)
AS
BEGIN
  DECLARE @InstanceName VARCHAR(100)
  DECLARE @Key VARCHAR(150)
  DECLARE @LoginMode INT
  EXEC master..xp_regread 'HKEY_LOCAL_MACHINE',
    'Software\Microsoft\Microsoft SQL Server\Instance Names\SQL\',
    'MSSQLSERVER', @InstanceName OUTPUT
  SET @Key = 'Software\Microsoft\Microsoft SQL Server\' + @InstanceName + '\MSSQLServer\'
  IF @MixedMode = 1
    SET @LoginMode = 2
  ELSE
    SET @LoginMode = 1
  EXEC master..xp_regwrite 'HKEY_LOCAL_MACHINE', @Key,
    'LoginMode', 'REG_DWORD', @LoginMode
END
Baca selengkapnya...
CREATE PROCEDURE uspSetSQLServerAuthMode(@MixedMode INT)
AS
BEGIN
  DECLARE @InstanceName VARCHAR(100)
  DECLARE @Key VARCHAR(150)
  DECLARE @LoginMode INT
  EXEC master..xp_regread 'HKEY_LOCAL_MACHINE',
    'Software\Microsoft\Microsoft SQL Server\Instance Names\SQL\',
    'MSSQLSERVER', @InstanceName OUTPUT
  SET @Key = 'Software\Microsoft\Microsoft SQL Server\' + @InstanceName + '\MSSQLServer\'
  IF @MixedMode = 1
    SET @LoginMode = 2
  ELSE
    SET @LoginMode = 1
  EXEC master..xp_regwrite 'HKEY_LOCAL_MACHINE', @Key,
    'LoginMode', 'REG_DWORD', @LoginMode
END
Baca selengkapnya...
02 April 2009
Mengganti Authentication Mode pada SQL Server dari Program
Trik berikut bisa dilakukan pada SQL Server 2008 dan mungkin juga SQL Server 2005, tapi tidak pada SQL Server 2000. Kita tahu pada SQL Server terdapat dua mode untuk otentikasi, yaitu Windows Authentication dan SQL Server Authentication. Jika kita klik kanan pada SQL Server Management Studio kemudian pilih Properties dan pada bagian Security kita bisa melihat ada pilihan Server Authentication. Ada dua pilihan, Windows Authentication mode atau SQL Server and Windows Authentication mode. Dari sini jelas bahwa jika kita pilih Windows Authentication mode, maka kita hanya bisa login dengan mode Windows Authentication saja. Jika kita pilih SQL Server and Windows Authentication mode, kita bisa memilih salah satu dari mode login tersebut.
Mungkin masih banyak dari kita yang memilih menggunakan SQL Server Authentication untuk koneksi ke SQL Server. Masalah timbul jika kita mengembangkan aplikasi dengan SQL Server dan memakai SQL Server Authentication, sedangkan instalasi SQL Server secara default pilihannya hanya Windows Authentication mode. Kita juga tidak mau merepotkan user dengan meminta user untuk mengubah mode tersebut secara manual. Bisa-bisa nanti user ngomel atau malah tidak mau menggunakan program kita. Apalagi jika pada komputer target/server hanya menggunakan Windows Authentication mode dan tidak ada SQL Server management studio.
Permasalahan ini bisa diatasi dengan menggantinya melalui program. Hal pertama yang perlu kita ketahui adalah apa yang perlu kita ubah, dan jawabannya adalah registry. Jika kita membuka registry (menu Start->Run, ketikkan “regedit”) pada HKEY_LOCAL_MACHINE terdapat key SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL. Didalam sini terdapat daftar nama instance yang ada pada komputer dengan key value-nya, dan isi dari key value ini yang kita butuhkan. Misal nama instance yang mau diganti modenya adalah “MSSQLSERVER”, dan key value-nya berisi “MSSQL10.MSSQLSERVER”. Pada key SOFTWARE\Microsoft\Microsoft SQL Server terdapat harusnya terdapat subkey dengan nama “MSSQL10.MSSQLSERVER” dan pada subkey tersebut terdapat lagi subkey “MSSQLServer”, jadi lengkapnya adalah SOFTWARE\Microsoft\Microsoft SQL\MSSQL10.MSSQLSERVER\MSSQLServer. Didalam key ini terdapat key dengan nama “LoginMode” dan inilah yang perlu kita ganti isinya. Set 1 untuk Windows Authentication mode atau 2 untuk SQL Server and Windows Authentication mode.
uses Windows, Registry;
procedure SetSQLServerAuthMode(aMixedMode: Boolean);
var
  reg: TRegistry;
  s: string;
begin
  reg := TRegistry.Create;
  try
    reg.RootKey := HKEY_LOCAL_MACHINE;
    reg.OpenKey('SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL', False);
    s := reg.ReadString('MSSQLServer');
    reg.CloseKey;
    reg.OpenKey('SOFTWARE\Microsoft\Microsoft SQL Server\' + s + '\MSSQLServer', False);
    if aMixedMode then reg.WriteInteger('LoginMode', 2)
    else reg.WriteInteger('LoginMode', 1);
    reg.CloseKey;
  finally
    reg.Free;
  end;
end;
Baca selengkapnya...
Mungkin masih banyak dari kita yang memilih menggunakan SQL Server Authentication untuk koneksi ke SQL Server. Masalah timbul jika kita mengembangkan aplikasi dengan SQL Server dan memakai SQL Server Authentication, sedangkan instalasi SQL Server secara default pilihannya hanya Windows Authentication mode. Kita juga tidak mau merepotkan user dengan meminta user untuk mengubah mode tersebut secara manual. Bisa-bisa nanti user ngomel atau malah tidak mau menggunakan program kita. Apalagi jika pada komputer target/server hanya menggunakan Windows Authentication mode dan tidak ada SQL Server management studio.
Permasalahan ini bisa diatasi dengan menggantinya melalui program. Hal pertama yang perlu kita ketahui adalah apa yang perlu kita ubah, dan jawabannya adalah registry. Jika kita membuka registry (menu Start->Run, ketikkan “regedit”) pada HKEY_LOCAL_MACHINE terdapat key SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL. Didalam sini terdapat daftar nama instance yang ada pada komputer dengan key value-nya, dan isi dari key value ini yang kita butuhkan. Misal nama instance yang mau diganti modenya adalah “MSSQLSERVER”, dan key value-nya berisi “MSSQL10.MSSQLSERVER”. Pada key SOFTWARE\Microsoft\Microsoft SQL Server terdapat harusnya terdapat subkey dengan nama “MSSQL10.MSSQLSERVER” dan pada subkey tersebut terdapat lagi subkey “MSSQLServer”, jadi lengkapnya adalah SOFTWARE\Microsoft\Microsoft SQL\MSSQL10.MSSQLSERVER\MSSQLServer. Didalam key ini terdapat key dengan nama “LoginMode” dan inilah yang perlu kita ganti isinya. Set 1 untuk Windows Authentication mode atau 2 untuk SQL Server and Windows Authentication mode.
uses Windows, Registry;
procedure SetSQLServerAuthMode(aMixedMode: Boolean);
var
  reg: TRegistry;
  s: string;
begin
  reg := TRegistry.Create;
  try
    reg.RootKey := HKEY_LOCAL_MACHINE;
    reg.OpenKey('SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL', False);
    s := reg.ReadString('MSSQLServer');
    reg.CloseKey;
    reg.OpenKey('SOFTWARE\Microsoft\Microsoft SQL Server\' + s + '\MSSQLServer', False);
    if aMixedMode then reg.WriteInteger('LoginMode', 2)
    else reg.WriteInteger('LoginMode', 1);
    reg.CloseKey;
  finally
    reg.Free;
  end;
end;
Baca selengkapnya...
01 April 2009
Beberapa Hal Baru pada SQL Server 2008
Beberapa hal baru dalam SQL Server 2008 yang belum lama ini aku ketahui, merupakan perbaikan pada Transact-SQL (T-SQL). Perbaikan ini bagi aku cukup berpengaruh pada produktivitas kerja yang meningkat dan akhirnya juga mengurangi waktu pengembangan aplikasi.
Pertama adalah inisialisasi variabel dimungkinkan pada saat deklarasi variabel tersebut, jadi cukup satu baris saja untuk deklarasi dan inisialisasi variabel. Fitur ini seperti yang terdapat pada kebanyakan bahasa pemrograman seperti Delphi, C++, C#. Dengan fitur ini tidak perlu menggunakan statement DECLARE dan SET secara terpisah.
DECLARE @Harga INT = 10000;
DECLARE @Jumlah INT = 5;
DECLARE @Total INT = @Harga * @Jumlah;
Kemudian bagi yang pernah menggunakan bahasa C++/C# kemungkinan pernah memakai/mengetahui sintak seperti berikut: x += 5; yang sama seperti statement x = x + 5;. Penggunaan sintak seperti yang pertama menggunakan compound operator lebih singkat yang nantinya juga berpengaruh ke efektivitas produksi. Hal yang sama juga bisa dilakukan pada SQL Server 2008. Daftar compound operator yang didukung SQL Server 2008:
-= Minus *= Kali /= Bagi %= Modulo (hasil bagi) &= Bitwise AND |= Bitwise OR ^= Bitwise XOR Bagi yang pernah menggunakan MySQL, mestinya tahu bahwa operasi INSERT bisa dilakukan dengan mengisikan nilai lebih dari satu dengan hanya satu statement INSERT, misal: INSERT INTO tabelku (a, b,) VALUES (1, ‘satu’), (2, ‘dua’), (3, ‘tiga’). Sekarang hal yang sama juga bisa dilakukan pada SQL Server 2008. Jadi lebih singkat, lebih sedikit statement yang ditulis dan akhirnya berpengaruh ke produktivitas juga. Seperti ada seorang tokoh yang sering bilang “LEBIH CEPAT, LEBIH BAIK!”.
Baca selengkapnya...
Pertama adalah inisialisasi variabel dimungkinkan pada saat deklarasi variabel tersebut, jadi cukup satu baris saja untuk deklarasi dan inisialisasi variabel. Fitur ini seperti yang terdapat pada kebanyakan bahasa pemrograman seperti Delphi, C++, C#. Dengan fitur ini tidak perlu menggunakan statement DECLARE dan SET secara terpisah.
DECLARE @Harga INT = 10000;
DECLARE @Jumlah INT = 5;
DECLARE @Total INT = @Harga * @Jumlah;
Kemudian bagi yang pernah menggunakan bahasa C++/C# kemungkinan pernah memakai/mengetahui sintak seperti berikut: x += 5; yang sama seperti statement x = x + 5;. Penggunaan sintak seperti yang pertama menggunakan compound operator lebih singkat yang nantinya juga berpengaruh ke efektivitas produksi. Hal yang sama juga bisa dilakukan pada SQL Server 2008. Daftar compound operator yang didukung SQL Server 2008:
- += Plus
Baca selengkapnya...
Langganan:
Postingan (Atom)

