3 delphi windows-services windows-7
我有一个使用Delphi创建的服务应用程序,并设法使用提升的权限从另一个Delphi应用程序安装它.
该服务设置为以本地系统帐户登录(在Delphi中创建服务应用程序时是默认的).
我有另一个Delphi应用程序,其中普通用户应该能够启动或停止上述服务.
我的问题是:Windows允许这样做吗?当我尝试使用Delphi中的代码启动服务时,它只是失败了"Code 5. Access被拒绝".如何防止发生此错误?我希望能够让普通用户运行应用程序(不是在管理员模式下,因此没有提升权限)来启动/停止服务.有可能,如果可能,怎么样?以下是我的代码:
function ServiceStart(sMachine, sService: string): boolean;
var
schm, schs: SC_Handle;
ss: TServiceStatus;
psTemp: PChar;
dwChkP: DWord; // check point
begin
ss.dwCurrentState := 0;
// connect to the service control manager
schm := OpenSCManager(PChar(sMachine), nil, SC_MANAGER_CONNECT);
// if successful...
if (schm <> 0) then
begin
// open a handle to the specified service
// we want to start the service and query service
// status
schs := OpenService(schm, PChar(sService), SERVICE_START or SERVICE_QUERY_STATUS);
// if successful...
if (schs <> 0) then
begin
psTemp := nil;
if (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
else
begin
if MessageDlg('Start Service failed. Do you want remove it?',
mtWarning, [mbYes, mbNo], 0) = mrYes then
begin
InstallUninstallService(1);
end;
end;
// close service handle
CloseServiceHandle(schs);
end else RaiseLastOSError;
// close service control manager handle
CloseServiceHandle(schm);
end;
// Return TRUE if the service status is running
Result := SERVICE_RUNNING = ss.dwCurrentState;
end;
Run Code Online (Sandbox Code Playgroud)
默认情况下,您需要具有管理员权限才能启动,停止,安装和删除服务.
您必须安排您的服务以公开其自己的Active属性,这与Windows术语的运行区别不同.安排它始终以Windows术语运行,但在其Active属性为false时是惰性的.
您必须为您的用户应用实施控制机制.我用命名管道完成了这个,但是其他IPC方法也可用.