5

新しいサービスを開始しようとしているWindows7のVisualStudio2008にc++プロジェクトがあります。管理者としてVisualStudioを実行しています。サービスを開始できません(serviceMainも呼び出されません)。

これが私の主な機能です:

wchar_t str[] = {'s','e','s','m'};

int _tmain(int argc, _TCHAR* argv[])
{
    SERVICE_TABLE_ENTRY dispTable[] =
    {
        {(wchar_t*)str, ServiceWork::ServiceMain}, 
        {NULL, NULL}
    };

    int i = StartServiceCtrlDispatcher(dispTable);
    int j = GetLastError();
    return 0; 
}

出力は次のとおりです。

。。。

'SessionMonitor.exe':ロード済み'C:\ Windows \ SysWOW64 \ cryptbase.dll'

'SessionMonitor.exe':ロード済み'C:\ Windows \ SysWOW64 \ imm32.dll'

'SessionMonitor.exe':ロード済み'C:\ Windows \ SysWOW64 \ msctf.dll'

SessionMonitor.exeの0x7638b9bcでの初回例外:0x00000005:アクセスが拒否されました。スレッド'Win32Thread'(0x129c)がコード0(0x0)で終了しました。プログラム'[2492]SessionMonitor.exe:Native'がコード0(0x0)で終了しました。

デバッグ時、jは1063-ERROR_FAILED_SERVICE_CONTROLLER_CONNECT

誰かが以前にこの問題に遭遇したことがありますか?解決策はありますか?

ありがとう、リロン

4

6 に答える 6

5

問題は、ビジュアル スタジオ内でサービスを起動しているという事実にあります。

これはできません。Visual Studio でサービスをコンパイルし、sc コマンドを使用して (またはここで説明されているようにプログラムで) コマンド プロンプトに登録するだけです。すべての正しい方法は、この質問の受け入れられた回答に記載されています。

サービス コードをデバッグする場合は、ServiceMain を直接発行する必要があります。次に例を示します。

int _tmain(int argc, _TCHAR* argv[])
{
#ifdef AS_SERVICE
    SERVICE_TABLE_ENTRY dispTable[] =
    {
        {(wchar_t*)str, ServiceWork::ServiceMain}, 
        {NULL, NULL}
    };

    int i = StartServiceCtrlDispatcher(dispTable);
    int j = GetLastError();
    return 0;
#else
    ServiceMain(argc, argv);
#endif
}

StartServiceCtrlDispatcher失敗してGetLastError戻った場合にも同じ問題が発生する可能性がありますERROR_FAILED_SERVICE_CONTROLLER_CONNECT (1063)

于 2014-10-03T13:10:45.000 に答える
2

Microsoft Visual Studio などの IDE またはコマンド ラインから Windows サービスを開始しようとしている場合は、ConsoleHandler をセットアップして ServiceStart を手動で呼び出す必要があります。

SetConsoleCtrlHandler( myConsoleHandler, TRUE ); ServiceStart( argc, argv, TRUE );

このアプリでは、Windows サービスではなくコンソール プログラムとして実行するようにアプリに指示する -debug フラグを渡します。

于 2014-01-24T17:51:26.497 に答える
1

Windows 7 で StartServiceCtrlDispatcher アクセスが拒否されました

これは Windows のバグだと思います。MSDNによると、StartServiceCtrlDispatcherは失敗時にゼロを返す必要がありますが、Microsoft の誰かが、代わりに API の境界を越えてカスタム (非 C++) 例外をスローすることをお勧めします。

AddVectoredExceptionHandlerを使用して、この特殊なタイプの例外をキャッチして無視し、問題を回避できます。

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

LONG WINAPI handle_exception(EXCEPTION_POINTERS* exception_data)
{
  switch (exception_data->ExceptionRecord->ExceptionCode)
  {
  case 0x00000005:  // thrown by StartServiceCtrlDispatcher for fun.
    // Ignore these specific type of exceptions and continue execution.
    // Note: There are several more interesting exceptions to catch here,
    // which are out of scope of this question.
    return EXCEPTION_CONTINUE_SEARCH;

  case 0xE06D7363:  // C++ exception code.
  default:
    // Pass all other type of exceptions to their regular exception handlers.
    return EXCEPTION_EXECUTE_HANDLER;
  }
}

auto handle = AddVectoredExceptionHandler(1, &handle_exception);
// Your code here. Now you can check for the return value of
// StartServiceCtrlDispatcher to see whether the application
// was started as a service or not without crashing.
RemoveVectoredExceptionHandler(handle);
于 2017-05-29T08:01:06.857 に答える
0

これは間違っています:

wchar_t str[] = {'s','e','s','m'};

終了 NUL を省略しました。使用する

wchar_t str[] = L"sesm";
于 2012-07-25T20:46:50.330 に答える
0

サービス開始の経緯は?

ユーザーが管理者グループに属していても、UAC を通過するか、既に昇格されたコンテキストから起動されるまで、プログラムは完全に昇格された状態では実行されません。Visual Studio を使用してデバッグしようとしている場合は、Visual Studio を右クリックして、管理者として実行する必要がある場合があります。

Explorer からサービスを起動できるようにするには、マニフェストで requestedExecutionLevel を「level=requireAdministrator」に設定する必要があります。コマンド プロンプトから起動する場合も、'net start yourservice' を使用している場合を除き、コマンド プロンプトを昇格する必要があります。システム サービス プラグインからの起動には特別な準備は必要なく、Windows 7 (Vista ではなく) で MS 署名済みアプリの高度なブーストが隠されています。

于 2012-08-24T12:37:17.727 に答える