C++ で作成したサービスに少し問題があります。サービス自体は正しく機能し、SYSTEM アカウントで実行されています。実行のある時点で、別のサービスを開始または停止する必要があります。ただし、これは機能していません。への呼び出しOpenService()
は、「アクセスが拒否されました」というエラー コード 5 を返します。
もう少し詳しく説明すると、ネットワーク アダプターでポート 123 を開こうとする独自のタイム プロバイダー サービスを開始する必要があります。このポートは、多くの場合win32time
、Windows のサービスによって既に開かれています。私がやろうとしているのは、サービスの開始時にこのサービスを自動的に停止し、停止したときに再び開始するオプションをユーザーに提供することです。
このサービスは、UAC 対応のシステムで昇格されたユーザー特権でのみアクセスできます。それはわかっていますが、SYSTEM アカウントはデフォルトでこのアクションを実行できるといつも思っていましたが、どうやら間違っているようです。
どうにかして私のサービスを昇格させることはできますか (マニフェストの特権レベルを「requireAdministrator」または同様のものに適合させることによって)? 正直なところ、UACプロンプトがセッション0などで動かなくなるのではないかと心配しているので、まだ試していません。または、SYSTEM で実行されているサービスに、別のサービスのステータスを制御する権限を付与する別の方法はありますか?
どんな提案でも大歓迎です、ありがとう!
編集
さて、ここにコードがありますが、今は少しばかげているように感じます...APIを徹底的にチェックすることを完全に忘れていました.andのパラメータはOpenSCManager()
、OpenService()
デフォルトですべての権限を要求するためにゼロになる可能性があると考えていましたが、合格する必要がありますSC_MANAGER_ALL_ACCESS
. 皆様お騒がせして申し訳ありません。明日これを試して、結果が出たらこの質問を閉じます。
// I am missing SC_MANAGER_ALL_ACCESS here probably...
SC_HANDLE scm = OpenSCManager(nullptr, nullptr, SC_MANAGER_CREATE_SERVICE) ;
if(nullptr == scm) {
/* Handle and return */
}
// ...and possibly here, too
SC_HANDLE svc = OpenService(scm, _T("w32time"), 0);
int lastError = GetLastError();
if(ERROR_SERVICE_DOES_NOT_EXIST == lastError) {
/* Handle and return */
}
if(start) {
if(0 != StartService(svc, 0, nullptr)) {
int lastError = GetLastError();
if(ERROR_SERVICE_ALREADY_RUNNING != lastError) {
/* Handle */
}
}
} else {
SERVICE_STATUS status;
QueryServiceStatus(svc, &status);
if(SERVICE_STOPPED != status.dwCurrentState) {
if(ControlService(svc, SERVICE_CONTROL_STOP, &status)) {
do {
QueryServiceStatus(svc, &status);
} while(SERVICE_STOPPED != status.dwCurrentState);
} else {
/* Handle */
}
}
}
CloseServiceHandle(svc);
CloseServiceHandle(scm);