无法查询,运行或停止Windows服务

时间:2016-09-05 08:09:11

标签: c++ windows winapi visual-studio-2012 service

我在this指令后创建了我的第一个Windows服务。我可以从Manage->中的Service面板启动或停止我的服务。我的电脑没有问题。 服务帐户是" LocalSystem" 所以,我认为,我可以使用权限。 现在我想从另一个应用程序与我的服务进行通信,但首先我要停止或启动我的服务。

关注example我写下这段代码:

    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; 
    }

在任何情况下,我都会收到错误编号5 ,即" ERROR_ACCESS_DENIED:句柄没有SERVICE_QUERY_STATUS访问权限",但是我不确定问题出在哪里。该服务具有LocalSystem帐户选项,这意味着所有权限,我是我的计算机的管理员..这是错误的?

我也尝试过使用ControlService尝试启动或停止服务但是我得到了与权利相同的错误

BOOL success = ::ControlService(schService, SERVICE_CONTROL_STOP, &ss);

我在Visual Studio 2013 Update 2上。 谢谢

3 个答案:

答案 0 :(得分:6)

你似乎对术语"特权和#34;有点困惑。和"访问权限"。您是对的,LocalSystem帐户确实是特权帐户,至少对于本地计算机上的操作而言。但是,即使是特权用户也必须知道如何利用她的特权(事情如何运作)。

当应用程序想要使用对象(例如服务)时,它必须向Windows内核声明其意图(通过代码中的OpenSCManagerOpenService完成)。应用程序识别对象(例如,通过服务名称),并通知内核它计划用它做什么样的事情。这些"种类的东西"被称为"访问权限"并且kenrel决定应用程序是否具有足够的特权以获取它请求的访问权限。在您的代码中,您要求SC管理员拥有所有访问权限(SC_MANAGER_ALL_ACCESS)以及更改服务配置的访问权限(SERVICE_CHANGE_CONFIG)。然后,您尝试查询服务的状态,但在请求访问服务(OpenService调用)时,您没有向内核声明此意图。这就是为什么你得到拒绝访问的原因"错误。

以下是为服务和SC经理定义的访问权限列表:https://msdn.microsoft.com/en-us/library/windows/desktop/ms685981(v=vs.85).aspx。该文档还包含有关执行哪些操作所需的访问权限的信息。

要打开服务,您只需要对其SC经理的SC_MANAGER_CONNECT访问权限。要查询服务状态,需要SERVICE-QUERY_STATUS访问权限。要停止服务,请请求SERVICE_STOP权限。

因此,简短版本是:在SERVICE_STOP | SERVICE_QUERY_STATUS调用时OpenService指定SC_MANAGER_CONNECT所需的访问掩码,并在OpenSCManager调用中选择application.properties

答案 1 :(得分:0)

<强>问题

您的示例程序没有正确的权限来停止/启动您的服务。您的服务具有哪些特权并不重要。

<强>解决方案

尝试以管理员身份运行示例程序,方法是右键单击exe文件并选择“以管理员身份运行”。

如果您需要以编程方式提升流程,请查看this article

答案 2 :(得分:0)

interpreter