[在Windows中以管理员身份重新启动c ++服务

问题描述 投票:0回答:1

我正在尝试在Windows 10上的C ++应用程序中重新启动“ postgres”服务,但是访问权限存在一些问题(我的猜测)。我尝试以具有本地管理员权限的域用户身份和本地管理员身份运行代码,但这些似乎都不起作用。我可以通过services.msc手动重新启动服务。该代码在OpenSCManager处已经失败,返回NULL。我还尝试了其他访问权限,但是OpenService失败。这是我的代码

auto showError = []()
{
    std::ostringstream os;
    os << GetLastError();

    qDebug() << "Restart PostgreSQL service failed : " << QString::fromStdString( os.str());
};

SERVICE_STATUS Status;

SC_HANDLE SCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS );

if(SCManager == NULL)
    showError();

SC_HANDLE SHandle = OpenService(SCManager, L"postgres", SERVICE_ALL_ACCESS );

if(SHandle == NULL)
    showError();

if(!ControlService(SHandle, SERVICE_CONTROL_STOP, &Status))
    showError();

do
{
    QueryServiceStatus(SHandle, &Status);
    qDebug() << "Checking Service Status...\n";
}while(Status.dwCurrentState != SERVICE_STOPPED);


if(!StartService(SHandle, 0, NULL))
    showError();

std::cin.sync();
std::cin.ignore();

CloseServiceHandle(SCManager);
CloseServiceHandle(SHandle);
c++ windows api service
1个回答
0
投票

您正在请求太多实际上不需要的权限。不要使用SC_MANAGER_ALL_ACCESSSERVICE_ALL_ACCESS。绝不要索要超出您真正需要的权限。在这种情况下,您真正​​需要的只是SC_MANAGER_CONNECTOpenSCManager()SERVICE_STOPSERVICE_STARTSERVICE_QUERY_STATUSOpenService()

如果在代码中更正此错误后,仍然出现“拒绝访问”错误,则该服务确实需要您的帐户具有启动/停止该服务的权限。因此,要么在提升的管理过程中运行代码,要么至少为您的用户帐户配置适当的权限。

而且,仅供参考,您的查询循环过于简单。您忽略了Status报告的ControlService(),并且没有考虑服务进入挂起状态或拒绝停止的可能性。仅在初始状态为待定状态时,才需要检查初始状态,然后进入查询循环直到不再处于待定状态为止,然后检查最终状态为已停止,然后再尝试启动服务。另外,请确保每次服务挂起时,都要检查状态的检查点。

尝试其他类似方法:

auto showError = []()
{
    DWORD err = GetLastError();
    qDebug() << "Restart PostgreSQL service failed. Error: " << err << "\n";
};

SERVICE_STATUS Status;

SC_HANDLE SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (!SCManager)
{
    showError();
    return;
}

SC_HANDLE SHandle = OpenService(SCManager, L"postgres", SERVICE_STOP | SERVICE_START | SERVICE_QUERY_STATUS);
if (!SHandle)
{
    showError();
    CloseServiceHandle(SCManager);
    return;
}

if (!ControlService(SHandle, SERVICE_CONTROL_STOP, &Status))
{
    showError();
    CloseServiceHandle(SHandle);
    CloseServiceHandle(SCManager);
}

if (Status.dwCurrentState == SERVICE_STOP_PENDING)
{
    qDebug() << "Waiting for Service to stop...\n";

    DWORD dwLastCheckPoint = Status.dwCheckPoint;

    do
    {
        Sleep(Status.dwWaitHint);

        qDebug() << "Checking Service Status...\n";

        if (!QueryServiceStatus(SHandle, &Status))
        {
            showError();
            CloseServiceHandle(SHandle);
            CloseServiceHandle(SCManager);
            return;
        }

        if ((Status.dwCurrentState != SERVICE_STOP_PENDING) || (Status.dwCheckPoint == dwLastCheckPoint))
            break;

        dwLastCheckPoint = Status.dwCheckPoint;
    }
    while (true);
}

if (Status.dwCurrentState != SERVICE_STOPPED)
{
    qDebug() << "Restart PostgreSQL service failed. Service dis not stop correctly.\n";
    CloseServiceHandle(SHandle);
    CloseServiceHandle(SCManager);
    return;
} 

if (!StartService(SHandle, 0, NULL))
    showError();

CloseServiceHandle(SHandle);
CloseServiceHandle(SCManager);
© www.soinside.com 2019 - 2024. All rights reserved.