http://borland.mblogger.cn/aiirii/posts/2893.aspx相關 Api:ChangeServiceConfigThe ChangeServiceConfig function changes the configuration parameters of a service.To change the optional configuration parameters, use the ChangeServiceConfig2 function. BOOL ChangeServiceConfig( SC_HANDLE hService, DWORD dwServiceType, DWORD dwStartType, DWORD dwErrorControl, LPCTSTR lpBinaryPathName, LPCTSTR lpLoadOrderGroup, LPDWORD lpdwTagId, LPCTSTR lpDependencies, LPCTSTR lpServiceStartName, LPCTSTR lpPassword, LPCTSTR lpDisplayName );reference: http://www.bugtraq.ru/cgi-bin/forum.mcgi?type=sb&b=2&m=104683sample:procedure ConfigService(ServiceName: string; fDisable: boolean; lpDesc: string); type PQueryServiceLockStatus = ^TQueryServiceLockStatus; const SERVICE_CONFIG_DESCRIPTION: DWord = 1; var DynChangeServiceConfig2: function( hService: SC_HANDLE; // handle to service dwInfoLevel: DWORD; // information level lpInfo: Pointer): Bool; StdCall; // new data
sclLock: SC_LOCK; lpqslsBuf: PQueryServiceLockStatus; //LPQUERY_SERVICE_LOCK_STATUS; dwBytesNeeded, dwStartType: DWORD; schSCManager, schService: SC_Handle; aLibHndl: THandle; TempP: PChar; ret: boolean; begin schSCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS); if schSCManager = 0 then raise Exception.Create(SysErrorMessage(GetLastError)); // Need to acquire database lock before reconfiguring. sclLock := LockServiceDatabase(schSCManager); try // If the database cannot be locked, report the details. if (sclLock = nil) then begin // Exit if the database is not locked by another process. if (GetLastError() <> ERROR_SERVICE_DATABASE_LOCKED) then raise Exception.Create(SysErrorMessage(GetLastError)); // Allocate a buffer to get details about the lock. lpqslsBuf := PQueryServiceLockStatus(LocalAlloc(LPTR, sizeof(QUERY_SERVICE_LOCK_STATUS) + 256)); if (lpqslsBuf = nil) then raise Exception.Create(SysErrorMessage(GetLastError)); // Get and print the lock status information. if not (QueryServiceLockStatus( schSCManager, lpqslsBuf^, sizeof(QUERY_SERVICE_LOCK_STATUS) + 256, dwBytesNeeded)) then raise Exception.Create(SysErrorMessage(GetLastError)); if (lpqslsBuf^.fIsLocked > 0) then begin OutputDebugString(pchar('Locked by: ' + lpqslsBuf^.lpLockOwner + ' duration: ' + IntToStr(lpqslsBuf^.dwLockDuration) + ' seconds')); end else OutputDebugString(pchar('No longer locked')); LocalFree(cardinal(lpqslsBuf)); raise Exception.Create(SysErrorMessage(GetLastError)); end; // The database is locked, so it is safe to make changes. // Open a handle to the service. schService := OpenService( schSCManager, // SCManager database pchar(ServiceName), //'Sample_Srv', // name of service SERVICE_CHANGE_CONFIG); // need CHANGE access if (schService = 0) then raise Exception.Create(SysErrorMessage(GetLastError)); try if fDisable then dwStartType := SERVICE_DISABLED else dwStartType := SERVICE_DEMAND_START; // Make the changes. // display name: no change if not (ChangeServiceConfig( schService, // handle of service SERVICE_WIN32_OWN_PROCESS or SERVICE_INTERACTIVE_PROCESS, //SERVICE_NO_CHANGE, // service type: no change dwStartType, // change service start type SERVICE_NO_CHANGE, // error control: no change nil, // binary path: no change nil, // load order group: no change nil, // tag ID: no change nil, // dependencies: no change nil, // account name: no change nil, // password: no change nil)) then begin raise Exception.Create(SysErrorMessage(GetLastError)); end else OutputDebugString('ChangeServiceConfig SUCCESS'); // sdBuf.lpDescription := lpDesc; aLibHndl := GetModuleHandle(advapi32); ret := aLibHndl <> 0; if not ret then Exit; try DynChangeServiceConfig2 := GetProcAddress(aLibHndl, 'ChangeServiceConfig2A'); ret := @DynChangeServiceConfig2 <> nil; if not ret then Exit; TempP := PChar(lpDesc); //ChangeServiceConfig2 ret := DynChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, @TempP); if not ret then raise Exception.Create(SysErrorMessage(GetLastError)) else OutputDebugString('ChangeServiceConfig2 SUCCESS'); finally FreeLibrary(aLibHndl); end; finally CloseServiceHandle(schService); end; finally // Release the database lock. UnlockServiceDatabase(sclLock); // Close the handle to the service. CloseServiceHandle(schService); end; end;procedure TForm1.btnConfigServiceClick(Sender: TObject); var sN, sStatus: string; i: integer; begin sN := lbServices.Items[lbServices.ItemIndex]; i := Pos('---', sN); delete(sN, 1, i + 2); edit1.Text := sn; ConfigService(Sn, false, 'service test by ari'); end;
BOOL ChangeServiceConfig(
SC_HANDLE hService,
DWORD dwServiceType,
DWORD dwStartType,
DWORD dwErrorControl,
LPCTSTR lpBinaryPathName,
LPCTSTR lpLoadOrderGroup,
LPDWORD lpdwTagId,
LPCTSTR lpDependencies,
LPCTSTR lpServiceStartName,
LPCTSTR lpPassword,
LPCTSTR lpDisplayName
);reference: http://www.bugtraq.ru/cgi-bin/forum.mcgi?type=sb&b=2&m=104683sample:procedure ConfigService(ServiceName: string; fDisable: boolean; lpDesc: string);
type
PQueryServiceLockStatus = ^TQueryServiceLockStatus;
const
SERVICE_CONFIG_DESCRIPTION: DWord = 1;
var
DynChangeServiceConfig2: function(
hService: SC_HANDLE; // handle to service
dwInfoLevel: DWORD; // information level
lpInfo: Pointer): Bool; StdCall; // new data
sclLock: SC_LOCK;
lpqslsBuf: PQueryServiceLockStatus; //LPQUERY_SERVICE_LOCK_STATUS;
dwBytesNeeded, dwStartType: DWORD;
schSCManager, schService: SC_Handle;
aLibHndl: THandle;
TempP: PChar;
ret: boolean;
begin
schSCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS); if schSCManager = 0 then raise Exception.Create(SysErrorMessage(GetLastError));
// Need to acquire database lock before reconfiguring.
sclLock := LockServiceDatabase(schSCManager);
try
// If the database cannot be locked, report the details.
if (sclLock = nil) then
begin
// Exit if the database is not locked by another process.
if (GetLastError() <> ERROR_SERVICE_DATABASE_LOCKED) then
raise Exception.Create(SysErrorMessage(GetLastError)); // Allocate a buffer to get details about the lock. lpqslsBuf := PQueryServiceLockStatus(LocalAlloc(LPTR, sizeof(QUERY_SERVICE_LOCK_STATUS) + 256));
if (lpqslsBuf = nil) then
raise Exception.Create(SysErrorMessage(GetLastError)); // Get and print the lock status information. if not (QueryServiceLockStatus(
schSCManager,
lpqslsBuf^,
sizeof(QUERY_SERVICE_LOCK_STATUS) + 256,
dwBytesNeeded)) then
raise Exception.Create(SysErrorMessage(GetLastError)); if (lpqslsBuf^.fIsLocked > 0) then
begin
OutputDebugString(pchar('Locked by: ' + lpqslsBuf^.lpLockOwner +
' duration: ' + IntToStr(lpqslsBuf^.dwLockDuration) + ' seconds'));
end
else
OutputDebugString(pchar('No longer locked')); LocalFree(cardinal(lpqslsBuf));
raise Exception.Create(SysErrorMessage(GetLastError));
end; // The database is locked, so it is safe to make changes.
// Open a handle to the service.
schService := OpenService(
schSCManager, // SCManager database
pchar(ServiceName), //'Sample_Srv', // name of service
SERVICE_CHANGE_CONFIG); // need CHANGE access
if (schService = 0) then
raise Exception.Create(SysErrorMessage(GetLastError)); try
if fDisable then
dwStartType := SERVICE_DISABLED
else
dwStartType := SERVICE_DEMAND_START; // Make the changes.
// display name: no change
if not (ChangeServiceConfig(
schService, // handle of service
SERVICE_WIN32_OWN_PROCESS or SERVICE_INTERACTIVE_PROCESS, //SERVICE_NO_CHANGE, // service type: no change
dwStartType, // change service start type
SERVICE_NO_CHANGE, // error control: no change
nil, // binary path: no change
nil, // load order group: no change
nil, // tag ID: no change
nil, // dependencies: no change
nil, // account name: no change
nil, // password: no change
nil)) then
begin
raise Exception.Create(SysErrorMessage(GetLastError));
end
else
OutputDebugString('ChangeServiceConfig SUCCESS'); // sdBuf.lpDescription := lpDesc;
aLibHndl := GetModuleHandle(advapi32);
ret := aLibHndl <> 0;
if not ret then Exit;
try
DynChangeServiceConfig2 := GetProcAddress(aLibHndl, 'ChangeServiceConfig2A');
ret := @DynChangeServiceConfig2 <> nil;
if not ret then Exit;
TempP := PChar(lpDesc); //ChangeServiceConfig2 ret := DynChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, @TempP); if not ret then
raise Exception.Create(SysErrorMessage(GetLastError))
else
OutputDebugString('ChangeServiceConfig2 SUCCESS');
finally
FreeLibrary(aLibHndl);
end;
finally
CloseServiceHandle(schService);
end;
finally
// Release the database lock.
UnlockServiceDatabase(sclLock);
// Close the handle to the service.
CloseServiceHandle(schService);
end;
end;procedure TForm1.btnConfigServiceClick(Sender: TObject);
var
sN, sStatus: string;
i: integer;
begin
sN := lbServices.Items[lbServices.ItemIndex];
i := Pos('---', sN);
delete(sN, 1, i + 2);
edit1.Text := sn;
ConfigService(Sn, false, 'service test by ari');
end;
具体还真忘了,开启服务的还有印象
找到服务的句柄hService后用StartService(),
就搞定了,不过还是需要用循环测试QueryServiceStatus()的,用以证明已开启服务关闭的也可以两句搞定的,呵呵实在忘了,》》如何用Delphi启/禁用服务程序,主意不是启动
你说的是不是START_PENDING状态?