Changing a Service Configuration
In the following example, a service configuration program uses the ChangeServiceConfig and ChangeServiceConfig2 functions to change the configuration parameters of an installed service. The program first tries to lock the database, to prevent the SCM from starting a service while it is being reconfigured. If it successfully locks the database, the program opens a handle to the service object, modifies its configuration, unlocks the database, and then closes the service object handle. If the program does not successfully in lock the database, it uses the QueryServiceLockStatus function to retrieve information about the lock.
#include <windows.h>
#include <stdio.h>
BOOL ReconfigureSampleService(BOOL fDisable, LPSTR lpDesc)
{
SC_LOCK sclLock;
LPQUERY_SERVICE_LOCK_STATUS lpqslsBuf;
SERVICE_DESCRIPTION sdBuf;
DWORD dwBytesNeeded, dwStartType;
BOOL bSuccess=TRUE;
// Need to acquire database lock before reconfiguring.
sclLock = LockServiceDatabase(schSCManager);
// If the database cannot be locked, report the details.
if (sclLock == NULL)
{
// Exit if the database is not locked by another process.
if (GetLastError() != ERROR_SERVICE_DATABASE_LOCKED)
{
printf("Database lock failed (%d)/n", GetLastError());
return FALSE;
}
// Allocate a buffer to get details about the lock.
lpqslsBuf = (LPQUERY_SERVICE_LOCK_STATUS) LocalAlloc(
LPTR, sizeof(QUERY_SERVICE_LOCK_STATUS)+256);
if (lpqslsBuf == NULL)
{
printf("LocalAlloc failed (%d)/n", GetLastError());
return FALSE;
}
// Get and print the lock status information.
if (!QueryServiceLockStatus(
schSCManager,
lpqslsBuf,
sizeof(QUERY_SERVICE_LOCK_STATUS)+256,
&dwBytesNeeded) )
{
printf("Query lock status failed (%d)", GetLastError());
return FALSE;
}
if (lpqslsBuf->fIsLocked)
printf("Locked by: %s, duration: %d seconds/n",
lpqslsBuf->lpLockOwner,
lpqslsBuf->dwLockDuration);
else
printf("No longer locked/n");
LocalFree(lpqslsBuf);
}
// The database is locked, so it is safe to make changes.
// Open a handle to the service.
schService = OpenService(
schSCManager, // SCManager database
"Sample_Srv", // name of service
SERVICE_CHANGE_CONFIG); // need CHANGE access
if (schService == NULL)
{
printf("OpenService failed (%d)/n", GetLastError());
return FALSE;
}
dwStartType = (fDisable) ? SERVICE_DISABLED :
SERVICE_DEMAND_START;
// Make the changes.
if (! ChangeServiceConfig(
schService, // handle of service
SERVICE_NO_CHANGE, // service type: no change
dwStartType, // change service start type
SERVICE_NO_CHANGE, // error control: no change
NULL, // binary path: no change
NULL, // load order group: no change
NULL, // tag ID: no change
NULL, // dependencies: no change
NULL, // account name: no change
NULL, // password: no change
NULL) ) // display name: no change
{
printf("ChangeServiceConfig failed (%d)/n", GetLastError());
bSuccess = FALSE;
}
else
printf("ChangeServiceConfig succeeded./n");
sdBuf.lpDescription = lpDesc;
if( !ChangeServiceConfig2(
schService, // handle to service
SERVICE_CONFIG_DESCRIPTION, // change: description
&sdBuf) ) // value: new description
{
printf("ChangeServiceConfig2 failed/n");
bSuccess = FALSE;
}
else
printf("ChangeServiceConfig2 succeeded/n");
// Release the database lock.
UnlockServiceDatabase(sclLock);
// Close the handle to the service.
CloseServiceHandle(schService);
return bSuccess;
}
博客介绍了更改服务配置的示例,服务配置程序使用ChangeServiceConfig和ChangeServiceConfig2函数更改已安装服务的配置参数。程序先尝试锁定数据库,防止SCM在重新配置时启动服务,若锁定成功则修改配置,若失败则用QueryServiceLockStatus函数获取锁定信息。
101

被折叠的 条评论
为什么被折叠?



