Gio*_*diX 0 c++ windows service winapi visual-studio-2012
我按照这条指令创建了我的第一个Windows服务.我可以从管理 - >我的电脑中的服务面板开始或停止我的服务.该服务帐户是"本地系统"所以,我想,我确定有特权.现在我想从另一个应用程序与我的服务进行通信,但首先我要停止或启动我的服务.
按照这个例子我写这段代码:
SC_HANDLE schSCManager;
SC_HANDLE schService;
LPCWSTR szSvcName = _T("MyNewService");
// Get a handle to the SCM database.
schSCManager = OpenSCManager(
NULL, // local computer
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access rights
if (NULL == schSCManager)
{
printf("OpenSCManager failed (%d)\n", GetLastError());
return;
}
// Get a handle to the service.
schService = OpenService(
schSCManager, // SCM database
szSvcName, // name of service
SERVICE_CHANGE_CONFIG); // need change config access
if (schService == NULL)
{
printf("OpenService failed (%d)\n", GetLastError());
CloseServiceHandle(schSCManager);
return;
}
//OK until now
// Check the status in case the service is not stopped.
SERVICE_STATUS_PROCESS ssStatus;
DWORD dwBytesNeeded;
if (!QueryServiceStatusEx(
schService, // handle to service
SC_STATUS_PROCESS_INFO, // information level
(LPBYTE) &ssStatus, // address of structure
sizeof(SERVICE_STATUS_PROCESS), // size of structure
&dwBytesNeeded ) ) // size needed if buffer is too small
{
//printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
CString str;
str.Format(_T("QueryServiceStatusEx failed (%d)\n"), GetLastError()); //ERROR 5: ERROR_ACCESS_DENIED
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return;
}
// Check if the service is already running. It would be possible
// to stop the service here, but for simplicity this example just returns.
if(ssStatus.dwCurrentState != SERVICE_STOPPED && ssStatus.dwCurrentState != SERVICE_STOP_PENDING)
{
printf("Cannot start the service because it is already running\n");
CloseServiceHandle(schService);
CloseServiceHandle(schSCManager);
return;
}
Run Code Online (Sandbox Code Playgroud)
在任何情况下,我得到错误号5,即" ERROR_ACCESS_DENIED:句柄没有SERVICE_QUERY_STATUS访问权限 ",但我不知道问题出在哪里.该服务具有LocalSystem帐户选项,这意味着所有权限,我是我的计算机管理员..出了什么问题?
我也尝试使用ControlService尝试启动或停止服务,但我得到了有关权限的相同错误
BOOL success = ::ControlService(schService, SERVICE_CONTROL_STOP, &ss);
Run Code Online (Sandbox Code Playgroud)
我正在使用Visual Studio 2013 Update 2.谢谢
小智 6
你似乎对术语"特权"和"访问权限"有点困惑.您是对的,LocalSystem帐户确实是特权帐户,至少对于本地计算机上的操作而言.但是,即使是特权用户也必须知道如何利用她的特权(事情如何运作).
当应用程序想用一个物体(如服务)的工作,它宣布它打算在Windows内核(通过完成OpenSCManager并OpenService在你的代码).应用程序识别对象(例如,通过服务名称),并通知内核它计划用它做什么样的事情.这些"类型的东西"被称为"访问权限",而kenrel决定应用程序是否具有足够的特权以获得它所请求的访问权限.在您的代码中,您正在请求SC_MANAGER_ALL_ACCESSSC管理员的所有访问权限()以及更改服务配置的访问权限(SERVICE_CHANGE_CONFIG).然后,您尝试查询服务的状态,但在请求访问服务(OpenService调用)时,您没有向内核声明此意图.这就是你得到"拒绝访问"错误的原因.
以下是为服务和SC经理定义的访问权限列表:https://msdn.microsoft.com/en-us/library/windows/desktop/ms685981(v = vs.85).aspx.该文档还包含有关执行哪些操作所需的访问权限的信息.
要打开服务,您只需要SC_MANAGER_CONNECT对其SC管理员的访问权限.要查询服务状态,SERVICE-QUERY_STATUS需要访问权限.要停止服务,请求SERVICE_STOP权利.
因此,短版本是:SERVICE_STOP | SERVICE_QUERY_STATUS在调用时指定所需的访问掩码OpenService,并且可选地SC_MANAGER_CONNECT在OpenSCManager调用中指定.
| 归档时间: |
|
| 查看次数: |
3220 次 |
| 最近记录: |