通过java运行.net控制台时“句柄无效”

时间:2008-11-29 10:23:19

标签: c# java .net console

我正在尝试通过Java运行dot net console应用程序:

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 个答案:

答案 0 :(得分:11)

控制台应用程序正在尝试设置控制台的光标位置。这是不可能的,因为实际上没有控制台。所有不会导致简单读取或写入的操作都可能在没有控制台时导致错误(因为大多数操作都需要控制台输出缓冲区才能工作)。

在您希望自动执行的控制台应用程序中执行设置光标位置或清除屏幕等操作是个坏主意。一个基本的解决方法是将违规语句放在try-catch中,并丢弃该异常。来自MSDN page on System.Console

  

您不应该使用Console类   以无人值守方式显示输出   应用程序,例如服务器   应用。同样,打电话给   Write和WriteLine等方法   在Windows中没有任何效果   应用

     

可用的控制台类成员   通常当底层流是   指向控制台可能会抛出一个   如果流被重定向,则异常   例如,到文件。所以,   编程你的应用程序来捕获   如果重定向,则为System.IO.IOException   标准流。

答案 1 :(得分:1)

我遇到了同样的问题,只是通过SQL任务调度程序运行c#控制台应用程序。

我认为问题在于某些控制台方法和属性(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);
}

答案 2 :(得分:0)

很难在没有更多细节的情况下进行诊断 - 也许权限......一点点异常处理(可能将堆栈跟踪写入stderr)会有很大帮助。但如果您不拥有该应用程序,则没什么帮助。

如果你没有到达任何地方,你可以尝试使用reflector来查看.NET应用程序在“检测”过程中正在做什么 - 它可能有助于确定原因。

答案 3 :(得分:0)

我认为你朋友的节目没有问题。您可能需要获取从Runtime.getRuntime()。exec(commandLine)接收的进程对象的输出流,并调用read()方法或其他东西。它可能会奏效。

答案 4 :(得分:0)

尝试此操作以获取调用命令的输出流

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

}

答案 5 :(得分:0)

这可能取决于您的Java应用程序的运行方式。如果您的Java应用程序没有控制台,那么当您的内部进程需要控制台存在时可能会出现问题。阅读this