【问题标题】:"The handle is invalid" when running .net console via java通过 java 运行 .net 控制台时出现“句柄无效”
【发布时间】:2008-11-29 10:23:18
【问题描述】:

我正在尝试通过 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;

你知道为什么吗?

【问题讨论】:

    标签: c# java .net console


    【解决方案1】:

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

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

    你不应该使用 Console 类 在无人看管的情况下显示输出 应用程序,例如服务器 应用程序。同样,调用 Write 和 WriteLine 等方法 在 Windows 中无效 应用程序。

    控制台工作的类成员 通常当底层流是 定向到控制台可能会抛出一个 如果流被重定向,则异常, 例如,一个文件。最后, 对您的应用程序进行编程以捕获 如果您重定向 System.IO.IOException 标准流。

    【讨论】:

    • 自动化时为什么没有控制台?有没有办法以编程方式检查(除了异常)控制台窗口是否存在?
    • @xr280xr 使用 MSDN 引用和参考更新了答案。捕获异常是如何在 .NET 应用程序中检测它。或者您可以调用 C Windows API 函数 GetConsoleWindow(),此处记录:msdn.microsoft.com/en-us/library/ms683175(v=vs.85).aspx
    【解决方案2】:

    我遇到了同样的问题,只是它是通过 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);
    }
    

    【讨论】:

      【解决方案3】:

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

      如果您没有得到任何结果,您可以尝试使用 reflector 来查看 .NET 应用在“检测”期间正在做什么 - 这可能有助于确定原因。

      【讨论】:

      • 我找到了这条线:Console.CursorLeft = 0;你为什么会导致处理问题? (仅当通过 Java 运行时)
      • @Shaul - 也许它与流重定向有关?即它找不到本机 IO 缓冲区?怪异...不确定这对您有多大帮助...
      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          【解决方案6】:

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

          【讨论】:

            猜你喜欢
            • 2015-09-29
            • 2020-11-29
            • 1970-01-01
            • 2015-04-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多