«Неверный дескриптор» при запуске консоли .net через Java - PullRequest
9 голосов
/ 29 ноября 2008

Я пытаюсь запустить консольное приложение dot net через 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;

Знаете почему?

Ответы [ 6 ]

11 голосов
/ 23 января 2009

Консольное приложение пытается установить положение курсора для консоли. Это невозможно, поскольку на самом деле консоли нет. Все операции, которые не приводят к простому чтению или записи, могут привести к ошибкам при отсутствии консоли (поскольку большинству из них для работы требуется буфер вывода консоли).

Плохо делать такие вещи, как установка позиции курсора или очистка экрана в консольных приложениях, которые вы хотите автоматизировать. Основной обходной путь - просто поставить ошибочный оператор в try-catch и отбросить исключение. Со страницы MSDN на System.Console :

Вы не должны использовать класс Console отображать вывод в автоматическом режиме приложения, такие как сервер Приложения. Аналогичным образом, звонки такие методы, как Write и WriteLine не имеют никакого эффекта в Windows приложения.

Консольные члены класса, которые работают обычно, когда основной поток направленный на консоль может бросить исключение, если поток перенаправлен, например, в файл. Как следствие, запрограммируйте ваше приложение, чтобы поймать System.IO.IOException, если вы перенаправляете стандартный поток.

1 голос
/ 22 августа 2013

Я столкнулся с той же проблемой, только при запуске консольного приложения c # через планировщик задач SQL.

Я считаю, что проблема в том, что некоторые методы и свойства консоли (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);
}
0 голосов
/ 23 января 2009

Это может зависеть от того, как работает ваше Java-приложение. Если ваше Java-приложение не имеет консоли, то могут возникнуть проблемы, когда наличие консоли необходимо для вашего внутреннего процесса. Прочитайте это .

0 голосов
/ 23 января 2009

Попробуйте получить поток вывода команды вызова

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();
        }
    }

}
0 голосов
/ 29 ноября 2008

Я не думаю, что есть проблема с программой вашего друга. Возможно, вам нужно получить поток вывода объекта процесса, полученного из Runtime.getRuntime (). Exec (commandLine), и вызвать метод read () или что-то в этом роде. Это может сработать.

0 голосов
/ 29 ноября 2008

Трудно диагностировать без более подробной информации - возможно, разрешений ... немного обработки исключений (возможно, запись трассировки стека в stderr) очень помогло бы. но не сильно поможет, если вы не являетесь владельцем приложения.

Если вы ничего не получите, вы можете попробовать отражатель , чтобы увидеть, что приложение .NET делает во время «Обнаружения» - это может помочь определить причину.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...