Java的waitFor()方法似乎挂了

时间:2013-08-27 14:29:09

标签: c# java

我在.Net中编写了一个简单的例程,我需要从Java调用并检查退出值。出于某种原因,当从Java调用时,waitFor永远不会结束。这是因为从命令提示符调用时.Net例程很快就会结束,当从test.bat调用它时它会正确返回-1。任何人都知道问题是什么?

这是Java代码:

public static int runOnceWait(String[] cmdarray) throws IOException, InterruptedException
{
    Process p;
    p = Runtime.getRuntime().exec(cmdarray);
    int res = p.waitFor();
    p.destroy();
    return res;
}

/**
 * @param args
 * @throws InterruptedException 
 * @throws IOException 
 */
public static void main(String[] args) throws IOException, InterruptedException
{
    String [] cmd = new String[2];
    cmd[0]=signer;
    cmd[1]=fileLocation;
    System.out.println ("\"" + cmd[0] + "\" \"" + cmd[1] + "\"");
    System.out.println (runOnceWait(cmd));
}

这是C#代码:

    static int Main(string[] args)
    {
        if (args.Length != 1 && args.Length != 2)
        {
            Console.WriteLine("Use: ");
            Console.WriteLine("DocumentSigner.exe source");
            Console.WriteLine(" or");
            Console.WriteLine("DocumentSigner.exe source, destination");
            return -100;
        }

        string destination = null;

        try
        {
            if (args.Length == 1) destination = Sign(args[0]);
            else destination = Sign(args[0], args[1]);
            Console.WriteLine("Document signed and saved as " + destination);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            return -1;
        }

        return 0;
    }

出于测试目的,我甚至编写了一个行为符合预期的.bat文件,即返回-1的ERRORLEVEL。

这是.bat文件:

@echo off
rem test.bat
"DocumentSigner.exe" "{5E3C1967-A26E-4FC5-A6A8-3F358F388A3D}.pdf"
@if "%ERRORLEVEL%" == "0" goto good

:fail
    echo Execution Failed
    echo return value = %ERRORLEVEL%
    goto end

:good
    echo Execution succeeded
    echo Return value = %ERRORLEVEL%
    goto end

:end

1 个答案:

答案 0 :(得分:5)

来自java.lang.Process的API参考(强调我的):

  

默认情况下,创建的子进程没有自己的终端或   安慰。所有标准I / O(即stdin,stdout,stderr)操作   将被重定向到父进程,在那里可以访问它们   通过使用方法getOutputStream()获得的流,   getInputStream()和getErrorStream()。父进程使用这些   stream将输入提供给子进程并从子进程获取输出。的因为   某些本机平台仅为标准提供有限的缓冲区大小   输入和输出流,无法及时写入输入流   或者读取子进程的输出流可能会导致子进程   阻止,甚至死锁

我会尝试从java中读取您的c#应用程序使用Console.WriteLine()编写的内容,例如在exec()

之后做这样的事情
BufferedReader in = new BufferedReader(  
                    new InputStreamReader(p.getInputStream()));  
String line = null;  
while ((line = in.readLine()) != null) {  
    System.out.println(line);  
}