2008-11-29 35 views
8

Estoy tratando de ejecutar la aplicación de consola a través de la red del punto de Java:"El identificador no es válido" cuando se ejecuta la consola .NET a través de Java

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

me sale el siguiente resultado:

Detecting 
The handle is invalid. 

cuando ejecutarlo directamente a través de la consola (ventanas) no hay ningún problema:

Detecting 
100% 
Done. 
100% 

estoy corriendo más aplicaciones de esta forma, pero no tienen ningún problema .

conseguí este seguimiento de la pila:

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) 

El problema es cuando la aplicación .NET intentar escribir en la consola ¿Cuál es la solución?

conocer la línea que causa el problema:

Console.CursorLeft = 0; 

¿Sabe por qué?

Respuesta

0

Difícil de diagnosticar sin más detalles, quizás permisos ... un poco de manejo de excepciones (tal vez escribir stack-trace a stderr) ayudaría enormemente. pero no es de mucha ayuda si no tienes la aplicación.

Si no llega a ninguna parte, puede intentar usar reflector para ver qué hace la aplicación .NET durante la "Detección": podría ayudar a identificar la causa.

+1

Encontré la línea: Console.CursorLeft = 0; ¿por qué causa para manejar el problema? (solo cuando se ejecuta a través de Java) –

+0

@Shaul - ¿Tal vez se relaciona con la redirección de flujo? es decir, ¿no puede encontrar el buffer IO nativo? Freaky ... no estoy seguro de que eso te ayude ... –

0

No creo que haya un problema con el programa de su amigo. Probablemente necesites obtener el flujo de salida del objeto de proceso que recibes de Runtime.getRuntime() .exec (commandLine) y llamar a un método read() o algo así. Podría funcionar.

10

La aplicación de consola está tratando de establecer la posición del cursor para una consola. Esto no es posible, ya que de hecho no hay consola. Todas las operaciones que no dan como resultado una lectura o escritura simple pueden causar errores cuando no hay consola (ya que la mayoría de ellas requieren que funcione un búfer de salida de la consola).

Es una mala idea hacer cosas como establecer la posición del cursor o borrar la pantalla en aplicaciones de consola que desea automatizar. Una solución básica es simplemente colocar la declaración ofensiva en un try-catch, y descartar la excepción. Desde el MSDN page on System.Console:

Usted no debe usar la clase Console para mostrar la salida en desatendidas aplicaciones, tales como servidor de aplicaciones . Del mismo modo, las llamadas a los métodos , como Write y WriteLine no tienen ningún efecto en las aplicaciones de Windows . miembros

clase de consola que trabajan normalmente cuando la corriente subyacente es dirigida a una consola podría lanzar una excepción si se redirige la corriente, por ejemplo, en un archivo. En consecuencia, programa su aplicación para capturar System.IO.IOException si redirige una secuencia estándar.

+1

¿Por qué no hay consola cuando está automatizada? ¿Hay alguna manera de verificar mediante programación (a excepción de una excepción) si existe la ventana de la consola? – xr280xr

+1

@ xr280xr Respuesta actualizada con cita y referencia de MSDN. La captura de la excepción es cómo puede detectarlo en una aplicación .NET. O puede llamar a la función API de Windows C GetConsoleWindow(), documentada aquí: http://msdn.microsoft.com/en-us/library/ms683175(v=vs.85).aspx – waqas

0

probar este para obtener el flujo de salida del comando de llamada

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

que puede depender de la forma en la aplicación Java se está ejecutando. Si su aplicación Java no tiene consola, puede haber problemas cuando la presencia de la consola es necesaria para su proceso interno. Lee this.

0

Me encontré con el mismo problema, solo que se trataba de ejecutar una aplicación de consola C# a través del programador de tareas SQL.

Creo que el problema es que algunos métodos y propiedades de consola (Console.WindowWidth, Console.CursorLeft) están intentando manipular la salida de la consola, lo que no es posible cuando se redirige la consola.

Envolví la sección del código en un simple bloque try catch, y funciona bien ahora.

//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); 
} 
Cuestiones relacionadas