10

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

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

试试这个来获取调用命令的输出流

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 回答
0

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

于 2009-01-23T08:51:09.747 回答
0

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

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

于 2008-11-29T11:03:30.650 回答
0

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

于 2008-11-29T13:23:59.480 回答