1

手動で完全に正常に実行されるコンソール アプリがありますが、SQL Server エージェントによって実行されると、まったく実行に失敗し、次のような奇妙なエラー メッセージが表示されます:-

Executed as user: I01SVTD21\SYSTEM.
Unhandled Exception: System.IO.IOException: The handle is invalid.       
     at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)     
     at System.Console.GetBufferInfo(Boolean throwOnNoConsole, Boolean& succeeded)
     at System.Console.Clear()
     at ActiveDirectoryImport.Program.SendReports()
     at ActiveDirectoryImport.Program.GetUserInfo()
     at ActiveDirectoryImport.Program.Main(String[] args).
Process Exit Code 255.  The step failed.

ActiveDirectoryImport.Program.SendReports() が ActiveDirectoryImport.Program.GetUserInfo() によって呼び出される最後のメソッドであり、ほとんどのコードが実行されたように見えるまで、これは最初は奇妙なエラー メッセージのようには見えないかもしれません。ただし、コードが最初に行うことの 1 つはデータベース テーブル内のレコードの更新であるため、これは当てはまりません。

だから私は2つの質問が残っています。同じ場所から手動で正常に実行されているのに、ジョブがまったく失敗するのはなぜですか? そして、明らかにそこまで進んでいないのに、コードの後半で失敗していると私に言っているのはなぜですか?

コンソール アプリはコンソール画面に書き込みますが、ユーザー入力は受け取りません。基本的にアプリケーションのステータスを画面に書き込みますが、これは一見エラーです....

どんな助けでも大歓迎です。

4

1 に答える 1

2

おそらくこれはコメントである必要がありますが、例外(および少しの精神的なデバッグ)から、それは非常に「明らか」です。

プロセスのSystem.Console.Clear()標準出力がコンソールの出力に接続されていない場合、表示される例外が発生します。コマンドラインからアプリケーションを呼び出し、その出力をリダイレクトすると、最も簡単に再現できます。

MyConsoleApplication.exe > NUL

Check that your SQL Agent command line doesn't contain such a redirection - actually, I'm not sure about it, but SQL Agent might automatically redirect your process' output to show it in it's log. So best thing would be to either remove the System.Console.Clear() call altogether , arguably it doesn't make a lot of sense in this scenario anyway. Alternatively, simply wrap it like this

   try
   {
      System.Console.Clear();
   }
   catch (IOException)
   {
   }

To ignore this particular error. Note that other Console functions/properties like CursorVisible, may also throw an IOException in that case.

BTW, CursorVisible is actually a "good" candidate to write such a helper function:

 bool ConsoleInputIsRedirected
 {
     get
     {
         try
         {
             bool f = System.Console.CursorVisible;
             return false;
         }
         catch (IOException)
         {
             return true;
         }
     }
 }

If you need to, you can then use this function to conditionally execute the code that does only work when the output is not redirected (like Clear()).

于 2012-07-04T12:07:32.223 に答える