2011-06-23 21 views
0

UDPメッセージをキャッチし、ユーザーとしてプロセスを作成し、名前付きパイプ経由でプロセスにメッセージを送信し、繰り返しを実行するWindowsサービスを作成しました。サービスはXPではうまくいますが、1回の反復後にWindows 7で予期せず終了します。イベントビューアには、メッセージをサービスに渡すとアプリケーションエラーが発生し、サービスが予期せず終了したことが示されます。アプリケーションエラーは、障害モジュールがntdll.dllであることを示します。私のサービスをデバッグすると、コードがどこで停止するかが示されます。Windows 7でWindowsサービスが予期せず終了する

ここに私のワークループがあります。 XPで

do 
{ 
    DebugLog("Waiting For UDP message"); 
    if(recvfrom(socketId, buffer, buffSize, 0, &clientAddrCast, &size) >= 0) 
    { 
     DebugLog("Create Named Pipe"); 
     hPipe = CreateNamedPipe(lpszPipename,  // pipe name 
       PIPE_ACCESS_DUPLEX,  // read/write access 
       PIPE_TYPE_MESSAGE |  // message pipe 
       PIPE_READMODE_MESSAGE, // message read mode 
       1,      // maximum Instaces 
       buffSize,    // output buffer size 
       buffSize,    // input buffer size 
       5000,     // client time-out 
       &pSecAttrib);   // security attributes 

     if (hPipe == INVALID_HANDLE_VALUE) 
      ErrorLog("CreateNamedPipe"); 


     DebugLog("Create User Process"); 
     if(!CreateProcessAsUser(hTokenDupe, "C:\\Services\\UDPClient_UserApp.exe", NULL, NULL, NULL, false, dwCreationFlags, NULL, NULL, &si, &pi)) 
     { 

      // if client app fails use SendMessage as failsafe 
      //WTSSendMessage(WTS_CURRENT_SERVER_HANDLE, sessionID, pTitle, sizeof(pTitle), 
       //buffer, sizeof(buffer), MB_OK, 30, &resp, false); 
       ErrorLog("CreateProcess"); 
     } 
     else 
     { 
      DebugLog("Writing to User Process"); 
      // Open pipe to client 
      if(cSuccess = ConnectNamedPipe(hPipe, NULL) == 0) 
       ErrorLog("ConnectNamedPipe"); 
      else 
      { 
       Sleep(2000); 

       cbToWrite = (lstrlen(buffer)+1)*sizeof(TCHAR); 

       if(!WriteFile( 
        hPipe,     // pipe handle 
        buffer,     // message 
        cbToWrite,    // message length 
        &cbWritten,    // bytes written 
        NULL))     // not overlapped 
        ErrorLog("WriteFile"); 
      } 
     } 

    } 

    DebugLog("Cleanup"); 
    DestroyEnvironmentBlock(&pEnv); 
    DisconnectNamedPipe(hPipe); 
    CloseHandle(hPipe); 
    ErrorLog("test");  

}while(gServiceStatus.dwCurrentState == SERVICE_RUNNING); 

私のデバッグログはDebugLog("Cleanup")後、それはDebugLog("Waiting For UDP message")にループバックすることを示しています。 Windows 7では、それはDebugLog("Cleanup")の後に停止します。コードが作成する可能性がある問題を探しています。他の提案は非常に高く評価されます。

おかげで、 ジョセフG.

+0

申し訳ありません。 'DebugLog(" Cleanup ")'が呼ばれた後、どこかで失敗します。私はすでに私の投稿を編集しています。 –

答えて

0

私の推測では、win7のでタイトなセキュリティがあなたを取得しているだろう。

ここにコードがありません。たとえば、pSecAttribのコードはありますか?パイプの作成が失敗した場合や、失敗したAPIとその理由を正確に把握している場合は、ループ処理の残りの部分を実行しないようにエラー処理を強化してください。

CreateProcessAsUser - あなたはどのサービスを実行していますか?そのユーザーは適切なアクセス権を持っていますか?Win7とWin7では異なる場合があります。

ログGetLastError()の値の後すべて Win32の失敗です。あなた自身の人生を楽にしてください。これはいつか遠隔地のProductionのプロダクションになることがあります。

Sleep(2000);は?疑わしい。パイプが開いている場合は、単にデータを送信してこの遅延を避けるのはなぜですか。名前付きパイプサーバーコードがパイプ上で読み取り要求を送信するのが遅いのですか?

+0

'pSecAttrib'はアクティブユーザのセキュリティ属性を取得します。 'CreateProcessAsUser'はアクティブユーザとして実行するように設定されています。 –

+0

'GetLastErrot'はすべての' ErrorLog'関数で呼び出されます。 'Sleep(2000)'は、サービスによって作成されたプロセスの終了までに時間がかかるためです。それは全体の2秒を必要としないかもしれません。その数は任意に決められた。 –

+0

エラーを記録していると聞いて良かったです。 DestroyEnvironmentBlockの呼び出しが不思議です。これはループ内にありますが、ループ内にinitが表示されません。それはバグかもしれませんが、最初の2回目のパスで失敗すると思うでしょう( '' pEnv''を全く初​​期化しない限り)。あなたは例外を打つまで、デバッガでこれを実行して適切なコールスタックを取得できませんか?これを絞り込む際には、「クリーンアップログの後」よりも優れた処理能力が必要です。また、**すべての** Win32 API呼び出しでエラーをチェックしてください。 1つが失敗し、その事実が間違っていると、さらに行動が予想外になる可能性があります。 –

関連する問題