[Delphi:90131] サービスアプリケーションの停止や開始の制御方法

884 views
Skip to first unread message

Yamamoto Satoshi

unread,
Dec 5, 2007, 11:01:45 AM12/5/07
to Del...@ml.users.gr.jp
こんにちは。山本です。

質問します。

プログラムから
Windowsサービスアプリケーションの停止やスタート、再起動を
指示するのはどのようにすればよいのでしょうか。

例えば手動で
[管理ツール][サービス][IIS Admin][再起動]とすると
依存しているサービスも再起動してくれたりしますが
これをDelphi製のプログラムで行いたいです。

コマンドラインで
net start や net stop のコマンドを使う方法は
しっていますが
メッセージが出てしまうので
できればコマンドラインではない方法で
サービスの挙動を制御したいと思っています。

メッセージを隠す方法がわかればいいのかもしれません。

やり方を教えていただけますと幸いです。

よろしくお願いします。


-----
Yamamoto Satoshi
sat...@big.or.jp


ht_...@nifty.com

unread,
Dec 5, 2007, 11:12:35 AM12/5/07
to Del...@ml.users.gr.jp
こんにちは、山本さん。

> プログラムから
> Windowsサービスアプリケーションの停止やスタート、再起動を
> 指示するのはどのようにすればよいのでしょうか。

・OpenService
・QueryServiceStatus
・StartService
・ControlService
・CloseServiceHandle

これらを使う事により実現できます。
# 足りないものがあったらゴメンナサイ。

--
by DEKO
-------------------------------------
http://homepage1.nifty.com/ht_deko/
ht_...@nifty.com
-------------------------------------

khe00221

unread,
Dec 5, 2007, 7:23:12 PM12/5/07
to Del...@ml.users.gr.jp
KHE00221です

ネットで調べればそれなりに出てくるとは思いますが・・・

uses に WinSVC を入れて下さい

サービスの起動(スタートアップが無効な物も)・停止・状態取得、一覧取得が出来ます

TServiceResult と TServiceStatusResult は適当に作ってください

-----------------------------
http://khe00221.image.coocan.jp/
----------------------------

function TForm1.GetStartup(hService:SC_HANDLE):Cardinal;
var
QSC : PQueryServiceConfig;
nBytesNeeded : DWord;
begin
nBytesNeeded := 0;
QSC := nil;
try
//サービスのステータスを取得
QueryServiceConfig(hService,QSC,SizeOf(QSC),nBytesNeeded);
GetMem(QSC, nBytesNeeded);
QueryServiceConfig(hService,QSC,nBytesNeeded,nBytesNeeded);
Result := QSC.dwStartType;
except;
Result := $FFFFFFFF;
end;
FreeMem(QSC);
end;

function TForm1.ChangeStartup(hService:
SC_HANDLE;dwStartType:DWord):Boolean;
begin
Result :=
ChangeServiceConfig(hService,SERVICE_NO_CHANGE,dwStartType,SERVICE_NO_CHANGE,nil,nil,nil,nil,nil,nil,nil);
end;

function TForm1.ServiceStart(ServiceName:String):TServiceResult;
var
hscm, hsc: THandle;
SERVICE_STATUS : TServiceStatus;
DW : DWord;
CD : Cardinal;
P : PChar;
Startup : Boolean;
begin
Startup := False;
CD := $FFFFFFFF;
Result := srServiceNoExecute; //サービスは実行されなかった
hscm := OpenSCManager(nil, nil,STANDARD_RIGHTS_EXECUTE or
SC_MANAGER_CONNECT);
try
if hscm <> 0 then
begin
//スタートアップの状態を取得
hsc := OpenService(hscm,PChar(ServiceName), GENERIC_READ or
SERVICE_CHANGE_CONFIG);
try
if hsc <> 0 then
begin
//スタートアップが無効の場合手動にする
CD := GetStartup(hsc);
if CD = SERVICE_DISABLED then
begin
Startup := True;
ChangeStartup(hsc,SERVICE_DEMAND_START);
end;
CD := GetStartup(hsc);
end;
finally
CloseServiceHandle(hsc);
end;
hsc := OpenService(hscm,PChar(ServiceName), GENERIC_READ or
GENERIC_EXECUTE);
try
if hsc <> 0 then
begin
QueryServiceStatus (hsc,SERVICE_STATUS);
DW := SERVICE_Status.dwCurrentState;
case DW of
SERVICE_RUNNING:
begin
Result := srServiceNoStop; //サービスは既に実行している
end;
SERVICE_PAUSED,SERVICE_STOPPED:
begin
P := nil;
if StartService(hsc,0,P) then
begin
Result := srServiceRun; //サービスを実行させた
if Startup = True then Result := srServiceForceRun;
end
else
begin
Result := srServiceRunError; //サービスの実行に失敗した
if (Startup = True) and (CD = SERVICE_DISABLED) then
Result := srServiceForceRunError;
end;
end;
end;
end;
finally
CloseServiceHandle(hsc);
end;
//スタートアップを変更した場合元(無効)に戻す
if Startup = True then
begin
//スタートアップの状態を取得
hsc := OpenService(hscm,PChar(ServiceName), GENERIC_READ or
SERVICE_CHANGE_CONFIG);
try
if hsc <> 0 then
begin
ChangeStartup(hsc,SERVICE_DISABLED);
end;
finally
CloseServiceHandle(hsc);
end;
end;
end;
finally
CloseServiceHandle(hscm);
end;
end;

function TForm1.ServiceStop(ServiceName:String):TServiceResult;
var
hscm, hsc: THandle;
stat: _SERVICE_STATUS;
DW : DWord;
SERVICE_STATUS : TServiceStatus;
begin
Result := srServiceNoExecute; //サービスは実行されていない(無効か存在していない)
hscm := OpenSCManager(nil, nil,STANDARD_RIGHTS_EXECUTE or
SC_MANAGER_CONNECT);
if hscm <> 0 then
begin
try
hsc := OpenService(hscm,PChar(ServiceName), GENERIC_READ or
GENERIC_EXECUTE);
if hsc <> 0 then
begin
try
QueryServiceStatus (hsc,SERVICE_STATUS);
DW := SERVICE_Status.dwCurrentState;
if DW=SERVICE_STOPPED then Result := srServiceNoRun; //サービスは既に停止している
if (DW = SERVICE_RUNNING) or (DW = SERVICE_PAUSED) then
begin
if ControlService(hsc, SERVICE_CONTROL_STOP, stat) then
begin
Result := srServiceSTOP; //サービスを停止させた
end
else
begin
Result := srServiceStopError; //サービスの停止に失敗した
end;
end;
finally
CloseServiceHandle(hsc);
end;
end;
finally
CloseServiceHandle(hscm);
end;
end;
end;

function TForm1.CheckService(ServiceName:String):TServiceStatusResult;
var
hscm, hsc: THandle; // サービスマネージャ、サービスハンドル
SERVICE_STATUS : TServiceStatus;
Startup : Boolean;
begin
Result := ssServiceNoExecute; //サービスは存在しないもしくは無効
hscm := 0;
hsc := 0;
StartUp := False;
// サービスマネージャのハンドルオープン
try
hscm := OpenSCManager(nil, nil,STANDARD_RIGHTS_EXECUTE or
SC_MANAGER_CONNECT);
if hscm <> 0 then
begin
// サービスハンドルオープン
hsc := OpenService(hscm, PChar(ServiceName), GENERIC_READ or
GENERIC_EXECUTE);
if hsc <> 0 then
begin
QueryServiceStatus (hsc,SERVICE_STATUS);
if SERVICE_Status.dwCurrentState = SERVICE_RUNNING then Result :=
ssServiceRUN ; // サービスは実行している
if SERVICE_Status.dwCurrentState = SERVICE_PAUSED then Result :=
ssServicePAUSE; // サービスは一時停止している
if SERVICE_Status.dwCurrentState = SERVICE_STOPPED then Result :=
ssServiceSTOP ; // サービスは停止している
  end;
end;
finally
if hsc <> 0 then CloseServiceHandle(hsc);
if hscm <> 0 then CloseServiceHandle(hscm);
end;
GetLastError;
end;

function TForm1.GetServiceList(DisplayNameList,ServiceNameList:
TStrings;lpServices: DWord):boolean;
type
TSvcA = array[0..0] of TEnumServiceStatus;
PSvcA = ^TSvcA;
var
j: integer;
schm: SC_Handle;
nBytesNeeded, nServices, nResumeHandle: Cardinal;
ssa: PSvcA;
begin
Result := False;
try
schm := OpenSCManager(nil, nil,SC_MANAGER_ENUMERATE_SERVICE);
if schm <> 0 then
begin
nResumeHandle := 0;
nServices := 0;
nBytesNeeded := 0;
ssa := nil;
EnumServicesStatus(schm,SERVICE_WIN32,lpServices,ssa[0],SizeOf(ssa)
,nBytesNeeded,nServices,nResumeHandle);
GetMem(ssa, nBytesNeeded);
EnumServicesStatus(schm,SERVICE_WIN32,lpServices,ssa[0],nBytesNeeded,nBytesNeeded,nServices,nResumeHandle);
for j := 0 to nServices - 1 do
begin
DisplayNameList.Add(StrPas(ssa[j].lpDisplayName));
ServiceNameList.Add(StrPas(ssa[j].lpServiceName));
end;
Result := True;
FreeMem(ssa);
CloseServiceHandle(schm);
end;
except
end;
end;


Yamamoto Satoshi

unread,
Dec 10, 2007, 10:25:44 AM12/10/07
to Del...@ml.users.gr.jp
返事が遅くなってしまいました。

DEKOさん、KHE00221さん、
教えていただいてありがとうございました。

勉強させていただきます。


> 送信者 "khe00221" <khe0...@vesta.dti.ne.jp>
> 宛先 <Del...@ml.users.gr.jp>
> 日時 2007/12/06 9:23:12
> 件名 [Delphi:90133] Re: サービスアプリケーションの停止や開始の制御方法
> ----


> KHE00221です
>
> ネットで調べればそれなりに出てくるとは思いますが・・・
>
> uses に WinSVC を入れて下さい
>
> サービスの起動(スタートアップが無効な物も)・停止・状態取得、一覧取得が出来ます
>
> TServiceResult と TServiceStatusResult は適当に作ってください
>
> -----------------------------
> http://khe00221.image.coocan.jp/
> ----------------------------

-----
Yamamoto Satoshi
sat...@big.or.jp


Reply all
Reply to author
Forward
0 new messages