我正在尝试在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_ACCESS
和SERVICE_ALL_ACCESS
。绝不要索要超出您真正需要的权限。在这种情况下,您真正需要的只是SC_MANAGER_CONNECT
为OpenSCManager()
,SERVICE_STOP
为SERVICE_START
,SERVICE_QUERY_STATUS
和OpenService()
。
如果在代码中更正此错误后,仍然出现“拒绝访问”错误,则该服务确实需要您的帐户具有启动/停止该服务的权限。因此,要么在提升的管理过程中运行代码,要么至少为您的用户帐户配置适当的权限。
而且,仅供参考,您的查询循环过于简单。您忽略了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);