1

我在 .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
4

1 回答 1

5

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

默认情况下,创建的子进程没有自己的终端或控制台。它的所有标准I/O(即stdin、stdout、stderr)操作都将被重定向到父进程,在那里可以通过使用getOutputStream()、getInputStream() 和getErrorStream() 方法获得的流来访问它们。父进程使用这些流向子进程提供输入并从子进程获取输出。由于一些原生平台只为标准输入输出流提供有限的缓冲区大小,未能及时写入子进程的输入流或读取输出流可能会导致子进程阻塞,甚至死锁

我会尝试从 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);  
}  
于 2013-08-27T14:50:36.617 回答