如何用代码将系统的一个服务的启动类型修改为自动或手动或已禁用?(50分)

  • 主题发起人 主题发起人 梦之旅
  • 开始时间 开始时间

梦之旅

Unregistered / Unconfirmed
GUEST, unregistred user!
如何用代码将 系统的一个服务的启动类型修改为 自动 或 手动 或 已禁用?
 
参考

ChangeServiceConfig

The 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=104683

sample:

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;
 
大哥 这么复杂啊 好像是改变描述的吧
 
[:(][:(]我已经说了那是参考,API已经有了,MSDN说得很详细
 
参考不来哦~~[:(]
 
还有一种方法用winexe配合命令行SC命令,也是可以的,具体查一下SC的用法,可能会简单一些,但研究一下API也是很值得的。
 
后退
顶部