2016-10-11 7 views
0

C++には、実行時に他の関連するプロセスが実行されていないと思われるアプリケーションがあり、いくつかのサービスをインストールしようとしています。Windowsサービスのインストール/アンインストール

ワークフローは、サービスが存在する場合はアンインストールされ、それ以外の場合はアンインストールされ、アンインストールされてから再インストールされます。 Installing a service

は残念ながら、何かがインストールまたはアンインストールと間違って行くようだ:

私のようないくつかのチュートリアルを追っていました。

サービスがインストールされていないと仮定して、サービスのインストールを進めると、サービスがインストールされ、設定を遅延自動開始に変更しようとします。

この段階ではサービスがインストールされていますが、サービスが見つからないというエラーが表示されるため、サービスを開始できません。

サービスをアンインストールすると、アンインストールが失敗し、サービスが削除対象としてマークされているというエラー1060が表示されます。

SC_HANDLE schSCManager; 
SC_HANDLE schService; 

schSCManager = OpenSCManager(
    NULL,     // local computer 
    NULL,     // ServicesActive database 
    SC_MANAGER_ALL_ACCESS); // full access rights 

if (schSCManager == nullptr) 
{ 
    continue; 
} 
if (bInstall) 
{ 
    schService = CreateService(
     schSCManager,    // SCM database 
     szServiceName,     // name of service 
     szDisplayName,     // service name to display 
     SERVICE_ALL_ACCESS,  // desired access 
     SERVICE_WIN32_OWN_PROCESS, // service type 
     SERVICE_DEMAND_START,  // start type 
     SERVICE_ERROR_NORMAL,  // error control type 
     szDirectory,     // path to service's binary 
     NULL,      // no load ordering group 
     NULL,      // no tag identifier 
     NULL,      // no dependencies 
     NULL,      // LocalSystem account 
     NULL);      // no password 

    if (schService == NULL) 
    { 
     TraceAdvice(L"CreateService failed (%d)\n", GetLastError()); 

     CloseServiceHandle(schSCManager); 
     continue; 
    } 
    else 
    { 
     if (!ChangeServiceConfig(
      schService,   // handle of service 
      SERVICE_NO_CHANGE,  // service type: no change 
      SERVICE_CONFIG_DELAYED_AUTO_START_INFO, // service start type 
      SERVICE_NO_CHANGE,  // error control: no change 
      NULL,     // binary path: no change 
      NULL,     // load order group: no change 
      NULL,     // tag ID: no change 
      NULL,     // dependencies: no change 
      NULL,     // account name: no change 
      NULL,     // password: no change 
      NULL))    // display name: no change 
     { 
      TraceAdvice(L"ChangeServiceConfig failed (%d)\n", GetLastError()); 
     } 
     TraceAdvice(L"Service installed successfully\n"); 
    } 

    CloseServiceHandle(schService); 
    CloseServiceHandle(schSCManager); 
    /*TraceFatal(_T("Now installing : %s"), szServiceName); 
    _stprintf_s(szTmp, _T("SC create %s binpath= \"%s%s.exe\" displayName= \"%s\" start= delayed-auto"), szServiceName, szDirectory, szServiceName, szDisplayName); 
    TraceFatal(_T("Command is : %s"), szTmp);*/ 
} 
else 
{ 

    _wsystem(_T("taskkill /F /IM mmc.exe")); // Need to kill any instance of MMC running 
    _wsystem(_T("taskkill /F /IM procexp.exe")); 

    schService = OpenService(
     schSCManager,  // SCM database 
     szServiceName,   // name of service 
     DELETE);   // need delete access 

    if (schService == NULL) 
    { 
     TraceAdvice(L"OpenService failed (%d)\n", GetLastError()); 
     CloseServiceHandle(schSCManager); 
     continue; 
    } 

    DWORD dwBytesNeeded; 
    SERVICE_STATUS_PROCESS ssp; 

    if (!QueryServiceStatusEx(
     schService, 
     SC_STATUS_PROCESS_INFO, 
     (LPBYTE)&ssp, 
     sizeof(SERVICE_STATUS_PROCESS), 
     &dwBytesNeeded)) 
    { 
     printf("QueryServiceStatusEx failed (%d)\n", GetLastError()); 
    } 
    if (ssp.dwCurrentState == SERVICE_RUNNING) 
    { 
     _stprintf_s(szTmp, _T("taskkill /F /IM %s.exe"), szServiceName); 
     _wsystem(szTmp); 
    } 
    // Delete the service. 

    if (!DeleteService(schService)) 
    { 
     TraceAdvice(L"DeleteService failed (%d)\n", GetLastError()); 
    } 
    else TraceAdvice(L"Service deleted successfully\n"); 

    CloseServiceHandle(schService); 
    CloseServiceHandle(schSCManager); 
} 

}

私はすべての点、すなわちことを確実なものとしました。

  • タスクマネージャは
  • サービスコンソールが閉じた閉鎖されました。
  • MMCのすべてのインスタンスが閉じられました。
  • サービスが...
  • サービスは、Visual Studioのデバッガで開いていなかった

を停止した。しかし、それは役に立つものではありません。システムを再起動するまでサービスがアンインストールされません(サービスにリンクされているレジストリを削除することもできません)。

私はこれらの関数に渡すパラメータをチェックしていて、正しいと思われます。

正しいインストールを確実にするため、またはアンインストールを成功させるために、何を確認する必要がありますか?

+0

mmcインスタンスを強制終了する必要があると思われる理由は何ですか?それはエンドユーザーにやっているかなり恐ろしいことです! –

+0

詳細については、ください。どのようにサービスを開始しようとしていますか、* exact *エラーメッセージは何ですか?あなたは 'szDirectory'にサービス実行可能ファイルへの*フル*パスが含まれていることを確かめますか?アンインストールすると、QueryServiceStatusExの呼び出しの結果はどうなりますか? –

+0

また、TraceAdvice()は何をしていますか? –

答えて

1

サービスを先に停止する必要があります。それ以外の場合は、この保留中の削除状態で停止します。サービスを強制終了することは、サービスを停止することと同じではありません。 documentationの同じ地域からは、ControlService(SERVICE_CONTROL_STOP)が必要です。