java.lang.ProcessBuilder генерирует неожиданное IOException - PullRequest
3 голосов
/ 25 марта 2012

возможно, я немного наивен, но я думаю, это не должно вести себя так.
Сначала мой код:

   private String ExeName="dc64cmd.exe";
   private String Dir=System.getenv("ProgramFiles(x86)") +"\\12noon Display Changer\\";           
   private String DetachArgument = "-monitor=\"PnP-Monitor (Standard)\" -detach";
   try {
        System.out.println(new File(Dir+ExeName).exists()); 
        //This prints "true" as expected.


        ProcessBuilder pb = new ProcessBuilder(ExeName, DetachArgument);
        pb=pb.directory(new File(Dir));

        pb=pb.redirectError(ProcessBuilder.Redirect.INHERIT);
        pb=pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
        pb=pb.redirectInput(ProcessBuilder.Redirect.INHERIT);
        //afaik the 3 lines above are not necessary. But just to be sure..

        pb.start();
    } catch (java.io.IOException IOexc) {
        System.err.println(IOexc.toString());
    }

Вывод программы

true
java.io.IOException: Cannot run program "dc64cmd.exe" (in directory "C:\Program Files (x86)\12noon Display Changer"): CreateProcess error=2, Das System kann die angegebene Datei nicht finden

Последняя часть - локализованная на немецком языке версия «Система не может найти файл».

Я не понимаю, почему, с одной стороны, файл существует, а с другой -не может быть найден.

Я немного погрузился в java.lang.ProcessBuilder и обнаружил, что исключение на самом деле выбрасывается в java.lang.ProcessImpl.java в строке 189

handle = create(cmdstr, envblock, path,
                    stdHandles, redirectErrorStream);

Это исключение приводит к тому, что java.lang.ProcessImpl.Start (...) (начиная со строки 83) закрывает FileInputStreams и FileOutputStreams в предложении finally для оператора try. Однако во время отладки я заметил f2.close () (line141) вызывается дважды, что приводит к генерируемому исключению, которое затем интерпретируется как неизвестный файл.

Моим первым предположением будет ошибка, но я думаю, что мой код довольно тривиален и не должен вызыватьнеизвестная ошибка.

Скорее всего, я сделалглупая маленькая ошибка в моем коде, во-первых ....

Я надеюсь, что вы можете читать мой плохой английский и мой плохой стиль, я не привык писать о коде ...

Любая помощь приветствуется.

jdk 1.7.0_03

edit : может быть важно упомянуть, что файл, который я хочу запустить, является 64-битным исполняемым файлом, хотя яустановил его в папку x86.

Ответы [ 2 ]

0 голосов
/ 25 марта 2012

Пожалуйста, попробуйте

new ProcessBuilder(Dir+ExeName, 
     "-monitor=\"PnP-Monitor (Standard)\"", 
     "-detach");

Это решит две вещи:

  • Вы используете полное имя для исполняемого файла.
  • Ваш detachArgument кажетсябыть два аргумента на самом деле.
0 голосов
/ 25 марта 2012

Я почти уверен, что это может быть проблемой

pb=pb.directory(new File(Dir));
pb=pb.redirectError(ProcessBuilder.Redirect.INHERIT);
pb=pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
pb=pb.redirectInput(ProcessBuilder.Redirect.INHERIT);

Для начала pb.directory возвращает файл java.io.File, так что вы просто перенаправили вывод файла каталога?

Может быть, попробовать это;

ProcessBuilder pb = new ProcessBuilder(ExeName, DetachArgument);
pb.directory(new File(Dir));

на немецком языке для полноты

Im ziemlich sicher, dass dies das Problem sein könnte

 pb = pb.directory (new File (dir));
 pb = pb.redirectError (ProcessBuilder.Redirect.INHERIT);
 pb = pb.redirectOutput (ProcessBuilder.Redirect.INHERIT);
 pb = pb.redirectInput (ProcessBuilder.Redirect.INHERIT);

Für einen Start pb.directory gibt einen java.io.File so Ihr gerade Umleiten der Ausgabe einer Datei des Verzeichnisses?

умерла Vielleicht versuchen Sie;

 ProcessBuilder pb = new ProcessBuilder (EXEName, DetachArgument);
 pb.directory (new File (dir));
...