簡體   English   中英

c ++以管理員身份在Windows中重新啟動服務

[英]c++ restart service in windows as admin

我正在嘗試在 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);

您要求的權限過多,但實際上並不需要。 不要使用SC_MANAGER_ALL_ACCESSSERVICE_ALL_ACCESS 永遠不要要求比你真正需要的更多的權限。 在這種情況下,您真正​​需要的是OpenSCManager() SC_MANAGER_CONNECTOpenService() SERVICE_STOPSERVICE_STARTSERVICE_QUERY_STATUS

如果您在代碼中修復此問題后仍然收到“拒絕訪問”錯誤,則該服務確實需要您的帳戶具有啟動/停止服務的權限。 因此,要么在提升的管理進程中運行您的代碼,要么至少使用適當的權限配置您的用戶帳戶。

僅供參考,您的查詢循環太簡單了。 您忽略了ControlService()報告的Status ,並且您沒有考慮服務進入掛起狀態或拒絕停止的可能性。 您需要檢查初始狀態,只有當它處於掛起狀態時才進入查詢循環,直到它不再處於掛起狀態,然后在嘗試啟動服務之前檢查最終狀態是否已停止。 還要確保在嘗試停止服務時檢查服務是否掛起。

請參閱 MSDN 上的停止服務

嘗試更像這樣的事情:

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 (!QueryServiceStatus(SHandle, &Status))
{
    showError(); 
    CloseServiceHandle(SHandle);
    CloseServiceHandle(SCManager);
    return;
}

if (Status.dwCurrentState != SERVICE_STOPPED)
{
    qDebug() << "Stopping PostgreSQL service...\n";

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

    DWORD dwStartTime = GetTickCount();
    DWORD dwTimeout = 30000; // 30-second time-out
    DWORD dwWaitTime;

    while (Status.dwCurrentState == SERVICE_STOP_PENDING)
    {
        qDebug() << "Waiting for PostgreSQL service to stop...\n";

        dwWaitTime = Status.dwWaitHint / 10;
        if (dwWaitTime < 1000)
            dwWaitTime = 1000;
        else if (dwWaitTime > 10000)
            dwWaitTime = 10000;

        Sleep(dwWaitTime);

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

        if (Status.dwCurrentState != SERVICE_STOP_PENDING)
            break;

        if (GetTickCount() - dwStartTime > dwTimeout)
        {
            qDebug() << "Stop of PostgreSQL service timed out.\n";
            CloseServiceHandle(SHandle);
            CloseServiceHandle(SCManager);
            return;
        }
    }

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

    qDebug() << "PostgreSQL service stopped successfully.\n";
}

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

CloseServiceHandle(schService); 
CloseServiceHandle(schSCManager);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM