10

Java経由でドットネットコンソールアプリケーションを実行しようとしています。

process = Runtime.getRuntime().exec(commandLine);

次の出力が得られます。

Detecting
The handle is invalid.

コンソール(Windows)から直接実行する場合、問題はありません。

Detecting
100%
Done.
100%

このフォームでさらに多くのアプリケーションを実行していますが、問題はありません。

このスタックトレースを取得しました:

Detecting at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
 at System.Console.GetBufferInfo(Boolean throwOnNoConsole, Boolean& succeeded)
 at System.Console.get_CursorTop()
 at AutomaticImageOrientation.HelperClasses.General.WriteProgressToConsole(Int32 lastIndex, Int32 totalImages)
 at AutomaticImageOrientation.MainManager.DetectImage(String[] files, String outputPath, String& globalErrorMessage, Dictionary`2& foundRotations)

問題は、.netアプリがコンソールに書き込もうとしているときです。解決策は何ですか?

問題の原因となっている行が見つかりました:

Console.CursorLeft = 0;

なぜなのかご存知ですか?

4

6 に答える 6

12

コンソール アプリケーションが、コンソールのカーソル位置を設定しようとしています。実際にはコンソールがないため、これは不可能です。単純な読み取りまたは書き込みにならないすべての操作は、コンソールがない場合にエラーを引き起こす可能性があります (ほとんどの操作にはコンソール出力バッファーが必要なため)。

自動化したいコンソールアプリケーションでカーソル位置の設定や画面のクリアなどを行うのは悪い考えです。基本的な回避策は、問題のあるステートメントを try-catch に入れ、例外を破棄することです。System.ConsoleのMSDN ページから:

Console クラスを使用して、サーバー アプリケーションなどの無人アプリケーションで出力を表示しないでください。同様に、Write や WriteLine などのメソッドの呼び出しは、Windows アプリケーションでは効果がありません。

基になるストリームがコンソールに向けられたときに正常に動作するコンソール クラス メンバーは、ストリームがファイルなどにリダイレクトされた場合に例外をスローする可能性があります。したがって、標準ストリームをリダイレクトする場合は、System.IO.IOException をキャッチするようにアプリケーションをプログラムします。

于 2009-01-23T07:46:40.080 に答える
1

私は同じ問題に遭遇しましたが、SQL タスク スケジューラを介して ac# コンソール アプリケーションを実行したことが原因でした。

問題は、一部のコンソール メソッドとプロパティ (Console.WindowWidth、Console.CursorLeft) がコンソール出力を操作しようとしていることにあると思いますが、これはコンソールがリダイレクトされた場合には不可能です。

コードのセクションを単純な try catch ブロックでラップしたところ、問題なく動作するようになりました。

//This causes the output to update on the same line, rather than "spamming" the output down the screen.
//This is not compatible with redirected output, so try/catch is needed.
try
{
    int lineLength = Console.WindowWidth - 1;
    if (message.Length > lineLength)
    {
        message = message.Substring(0, lineLength);
    }

    Console.CursorLeft = 0;
    Console.Write(message);
}
catch 
{
    Console.WriteLine(message);
}
于 2013-08-21T20:04:34.247 に答える
0

詳細なしで診断するのは難しい-おそらくパーミッション...少しの例外処理(おそらくスタックトレースをstderrに書き込む)は非常に役立つでしょう。ただし、アプリを所有していない場合はあまり役に立ちません。

どこにも行かない場合は、リフレクターを使用して、「検出」中に.NETアプリが何をしているかを確認してみてください。原因を特定するのに役立つ場合があります。

于 2008-11-29T11:03:30.650 に答える
0

お友達のプログラムに問題はないと思います。おそらく、Runtime.getRuntime().exec(commandLine) から受け取ったプロセス オブジェクトの出力ストリームを取得し、read() メソッドなどを呼び出す必要があります。それはうまくいくかもしれません。

于 2008-11-29T13:23:59.480 に答える
0

call コマンドの出力ストリームを取得するには、これを試してください

Runtime r = Runtime.getRuntime();
mStartProcess = r.exec(applicationName, null, fileToExecute);

StreamLogger outputGobbler = new StreamLogger(mStartProcess.getInputStream());
outputGobbler.start();

int returnCode = mStartProcess.waitFor();


class StreamLogger extends Thread{

   private InputStream mInputStream;

   public StreamLogger(InputStream is) {
        this.mInputStream = is;
    }

   public void run() {
        try {
            InputStreamReader isr = new InputStreamReader(mInputStream);
            BufferedReader br = new BufferedReader(isr);
            String line = null;
            while ((line = br.readLine()) != null) {
                    System.out.println(line);
            }
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

}
于 2009-01-23T08:25:16.197 に答える