Lagi bikin tools kecil untuk start dan stop Delphi, setelah googling nemu di sini. Tapi karena procedural, jadi gatel untuk mengubah ke class wised. Hal lain kalau mau menjalankan atau menghentikan service mesti menyebutkan WorkstationNamenya. Berarti kalau mau mendapatkan nama computer di mana program ini berjalan, mesti cari lagi. Hasil google mengarah ke sini. Ternyata kalau ada di domain, nama workstation saja masih tidak dikenali. Harus lengkap beserta domainnya. Lihat help di Delphi (F1), dapatlah GetComputerNameEx. Nah aku tambahkan juga method yang bisa mengenali workstation di mana programnya dijalankan. Aku sengaja tidak mengubah rutin yang di dapat dari Sadikhov forum di atas, hanya ditambahkan wrapper saja.
unit unitServiceControl;
interface
uses WinSvc, SysUtils, Windows;
{
Main Routine for Services : TARZAN from http://www.sadikhov.com/forum/index.php?showtopic=9039
Main Routine for ComputerName : Zarko Gajic from http://delphi.about.com/cs/adptips2002/a/bltip0102_3.htm
OOP Wrapper and minor enhancement and variable type correction : Wisnu Widiarta (7 April 2011)
}
type
TServiceControl = class
public
class function StartService(workstationName, serviceName: String) : boolean;
class function StopService(workstationName, serviceName: String) : boolean;
class function StartServiceInCurrentWorkstation(serviceName: String): Boolean;
class function StopServiceInCurrentWorkstation(serviceName: String): Boolean;
class function GetComputerNetName: String;
end;
implementation
{ TServiceControl }
//
// start service
//
// return TRUE if successful
//
// sMachine:
// machine name, ie: \SERVER
// empty = local machine
//
// sService
// service name, ie: Alerter
//
class function TServiceControl.StartService(workstationName,
serviceName: string): boolean;
var
//
// service control
// manager handle
schm,
//
// service handle
schs : SC_Handle;
//
// service status
ss : TServiceStatus;
//
// temp char pointer
psTemp : PChar;
//
// check point
dwChkP : Word;
begin
ss.dwCurrentState := 0;
// connect to the service
// control manager
schm := OpenSCManager(
PChar(workstationName),
Nil,
SC_MANAGER_CONNECT);
// if successful...
if(schm > 0)then
begin
// open a handle to
// the specified service
schs := OpenService(
schm,
PChar(serviceName),
// we want to
// start the service and
SERVICE_START or
// query service status
SERVICE_QUERY_STATUS);
// if successful...
if(schs > 0)then
begin
psTemp := Nil;
if(WinSvc.StartService(
schs,
0,
psTemp))then
begin
// check status
if(QueryServiceStatus(
schs,
ss))then
begin
while(SERVICE_RUNNING
<> ss.dwCurrentState)do
begin
//
// dwCheckPoint contains a
// value that the service
// increments periodically
// to report its progress
// during a lengthy
// operation.
//
// save current value
//
dwChkP := ss.dwCheckPoint;
//
// wait a bit before
// checking status again
//
// dwWaitHint is the
// estimated amount of time
// the calling program
// should wait before calling
// QueryServiceStatus() again
//
// idle events should be
// handled here...
//
Sleep(ss.dwWaitHint);
if(not QueryServiceStatus(
schs,
ss))then
begin
// couldn't check status
// break from the loop
break;
end;
if(ss.dwCheckPoint <
dwChkP)then
begin
// QueryServiceStatus
// didn't increment
// dwCheckPoint as it
// should have.
// avoid an infinite
// loop by breaking
break;
end;
end;
end;
end;
// close service handle
CloseServiceHandle(schs);
end;
// close service control
// manager handle
CloseServiceHandle(schm);
end;
// return TRUE if
// the service status is running
Result :=
SERVICE_RUNNING =
ss.dwCurrentState;
end;
//
// stop service
//
// return TRUE if successful
//
// sMachine:
// machine name, ie: \SERVER
// empty = local machine
//
// sService
// service name, ie: Alerter
//
class function TServiceControl.StartServiceInCurrentWorkstation(
serviceName: String): Boolean;
begin
Result := StartService(GetComputerNetName, serviceName);
end;
class function TServiceControl.StopService(workstationName,
serviceName: string): boolean;
var
//
// service control
// manager handle
schm,
//
// service handle
schs : SC_Handle;
//
// service status
ss : TServiceStatus;
//
// check point
dwChkP : Word;
begin
// connect to the service
// control manager
schm := OpenSCManager(
PChar(workstationName),
Nil,
SC_MANAGER_CONNECT);
// if successful...
if(schm > 0)then
begin
// open a handle to
// the specified service
schs := OpenService(
schm,
PChar(serviceName),
// we want to
// stop the service and
SERVICE_STOP or
// query service status
SERVICE_QUERY_STATUS);
// if successful...
if(schs > 0)then
begin
if(ControlService(
schs,
SERVICE_CONTROL_STOP,
ss))then
begin
// check status
if(QueryServiceStatus(
schs,
ss))then
begin
while(SERVICE_STOPPED
<> ss.dwCurrentState)do
begin
//
// dwCheckPoint contains a
// value that the service
// increments periodically
// to report its progress
// during a lengthy
// operation.
//
// save current value
//
dwChkP := ss.dwCheckPoint;
//
// wait a bit before
// checking status again
//
// dwWaitHint is the
// estimated amount of time
// the calling program
// should wait before calling
// QueryServiceStatus() again
//
// idle events should be
// handled here...
//
Sleep(ss.dwWaitHint);
if(not QueryServiceStatus(
schs,
ss))then
begin
// couldn't check status
// break from the loop
break;
end;
if(ss.dwCheckPoint <
dwChkP)then
begin
// QueryServiceStatus
// didn't increment
// dwCheckPoint as it
// should have.
// avoid an infinite
// loop by breaking
break;
end;
end;
end;
end;
// close service handle
CloseServiceHandle(schs);
end;
// close service control
// manager handle
CloseServiceHandle(schm);
end;
// return TRUE if
// the service status is stopped
Result :=
SERVICE_STOPPED =
ss.dwCurrentState;
end;
class function TServiceControl.StopServiceInCurrentWorkstation(
serviceName: String): Boolean;
begin
Result := StopService(GetComputerNetName, serviceName);
end;
class function TServiceControl.GetComputerNetName: String;
var
buffer: PWideChar;
size: Cardinal;
begin
size := 256;
GetMem(buffer, size);
if GetComputerNameEx(ComputerNameDnsFullyQualified, buffer, size) then
Result := buffer
else
Result := '';
FreeMem(buffer, size);
end;
end.
Penggunaannya simple saja:
const
SERVICE_NAME = 'BlackfishSQL';
{$R *.dfm}
procedure TformMain.btnStartClick(Sender: TObject);
begin
Log('Trying to stop SERVICE ' + SERVICE_NAME + ' in ' + TServiceControl.GetComputerNetName + '...');
if TServiceControl.StopServiceInCurrentWorkstation(SERVICE_NAME) then
Log('Service ' + SERVICE_NAME + ' has been stopped...')
else
Log('Service ' + SERVICE_NAME + ' cannot be stopped. Try to stopped it manually.');
//Untuk dikomputer xxx
if TServiceControl.StopService('xxx', SERVICE_NAME) then
Log('Service ' + SERVICE_NAME + ' has been stopped...')
else
Log('Service ' + SERVICE_NAME + ' cannot be stopped. Try to stopped it manually.');
end;
procedure TformMain.Log(event: String);
begin
mmLog.Lines.Add(FormatDateTime('DD/MM/YY hh:mm:ss', Now) + ' >> ' + event);
end;
PS: Kode ini kalau dijalankan di beberapa PC looping infinite. Kalau itu terjadi mungkin bisa mencoba cara lain dengan jalan memanggil aplikasi net.exe dari dos dengan perintah dari Delphi memanggil function ShellExecute yang bisa diperoleh dari unit ShellApi. Perintah untuk start adalah net.exe start <nama service>. Untuk menghentikan service, net.exe stop <nama service>.




Kayaknya dulu, jaman masih jadi coder di windows, aku juga pernah bikin tool beginian deh. Buat start/stop development tools dari tray bar, mulai delphi-nya, db server, web server, package builder, dsb. Tapi ntah ada dimana tuh program dan source code-nya ya? 😀
Kalau di MacBook konsepnya kayak di linux ya? Macam kill -9 bla bla bla gitu, apa ada cara lain?
Mac OSX itu Unix plus. Jadi, pake cara Unix bisa, pake cara Mac (kyk Windows API gitu) bisa, pake messaging (tool-nya Automator, sejenis VBA gitu) juga bisa. Tergantung kebutuhan dan preferensi aja.
Awesome dong ya?
Biasa aja kali bro. Sama aja sama OS yg lain. 🙂
Maklum.. belum pernah mainan mac OS hehehe..
Btw… WordPress.com udah bisa balik ke classic/normal view. Protesmu didengerin, bro. 🙂
Bwakakaka… aku dah coba barusan. Jauuuuuuuuuuuuuh…. standard lots faster brooo!
Iya nih, coding JS-nya masih gak optimized. Aku nyoba Sencha Touch yg lebih kompleks performanya masih lebih baik.
Sencha touch itu apaan? Theme?
Wogghh bahasa yang tak dimengerti awam …
Rumit juga ya dibalik tombol-tombol komputer ini ..
Sebenarnya semuanya diterjemahkan ke dalam biner.. 1 dan 0. Lalu diterjemahkan sebagai ada arus dan tidak ada arus… Sunatullah Bang. 🙂
saua masih bergelut dengan PHP dan MySQL 🙂
Oh itu juga mengasyikkan kok….
kok saya tidak bisa getComputerNameEx dan ComputerNameDnsFullyQualified?
tidak dikenali keduanya.
mohon bantuannya yah
thx
apa win 7 tidak support ya?
thx
Aku cobanya pake XP. Di sini gak ada Vista atau Win 7. Bisa jadi udah beda APInya 😀