2013-09-30 28 views
0

我寫了一個java程序來spwan子java進程。當它產生子進程時,它會打開一個命令提示符窗口,並將輸出重定向到命令提示符。你能告訴我如何產生/創建子進程沒有額外的命令窗口和重定向這個進程的輸出到一個文件。我使用的Java 6和JNA 3.5.2在JNA中重定向輸出和spunning子進程默默無聞(沒有彈出命令窗口)

下面是命令創建過程

cmd = "c:\\jdk1.6.0_30\\bin\\java.exe -Xmx256m -Xss1024k -cp <classpath jars>; 
-Dorg.omg.CORBA.ORBClass=org.jacorb.orb.ORB com.xyz.test.MainProgram <program arguments> 

工作代碼彈出命令提示符

private boolean createChildProcess(ProcessData processData,String cmd,String appName){ HANDLEByReference childStdInRead = new HANDLEByReference(); HANDLEByReference childStdOutWrite = new HANDLEByReference();

int STARTF_USESTDHANDLES = 0x00000100; 

    WinBase.PROCESS_INFORMATION.ByReference processInformation = new WinBase.PROCESS_INFORMATION.ByReference(); 
    STARTUPINFO startupInfo = new STARTUPINFO(); 

    // Create the child process. 
    if (!Kernel32.INSTANCE.CreateProcess(
      null, 
      cmd, 
      null, 
      null, 
      true, 
      new DWORD(0x00000020), //new DWORD(0x00000001) 
      null, 
      null, 
      startupInfo, 
      processInformation)){ 
     System.err.println(Kernel32Util.formatMessageFromLastErrorCode(Kernel32.INSTANCE.GetLastError())); 
     return false; 

    }else { 
     System.out.println("Created Process :"+processInformation.dwProcessId.intValue()); 
     processData.setProcessId(processInformation.dwProcessId.intValue()); 
     //processData.sethProcess(processInformation.hProcess); 
     //com.sun.jna.platform.win32.Kernel32.INSTANCE.WaitForSingleObject(processInformation.hProcess, 0xFFFFFFFF); 
     com.sun.jna.platform.win32.Kernel32.INSTANCE.CloseHandle(processInformation.hProcess); 
     com.sun.jna.platform.win32.Kernel32.INSTANCE.CloseHandle(processInformation.hThread); 
     return true; 
    } 
} </pre> 

我嘗試下面的代碼,但它沒't work

private boolean createChildProcess(ProcessData processData,String cmd,String appName){ 

    //Tried with Output to file 
    HANDLEByReference childStdInRead = new HANDLEByReference(); 
    HANDLEByReference childStdInWrite = new HANDLEByReference(); 
    HANDLEByReference childStdOutRead = new HANDLEByReference(); 
    HANDLEByReference childStdOutWrite = new HANDLEByReference(); 

    int STARTF_USESTDHANDLES = 0x00000100; 

    WinBase.PROCESS_INFORMATION.ByReference processInformation = new WinBase.PROCESS_INFORMATION.ByReference(); 
    STARTUPINFO startupInfo = new STARTUPINFO(); 
    startupInfo.cb = new DWORD(processInformation.size()); 
    startupInfo.hStdError = childStdOutWrite.getValue(); 
    startupInfo.hStdOutput = childStdOutWrite.getValue(); 
    startupInfo.hStdInput = childStdInRead.getValue(); 
    startupInfo.dwFlags |= STARTF_USESTDHANDLES; 

    SECURITY_ATTRIBUTES saAttr = new SECURITY_ATTRIBUTES(); 
    saAttr.dwLength = new DWORD(saAttr.size()); 
    saAttr.bInheritHandle = true; 
    saAttr.lpSecurityDescriptor = null; 

    // Create a pipe for the child process's STDOUT. 
    if (!com.sun.jna.platform.win32.Kernel32.INSTANCE.CreatePipe(childStdOutRead, childStdOutWrite, saAttr, 0)){ 
     System.err.println(Kernel32.INSTANCE.GetLastError()); 
    } 

    // Ensure the read handle to the pipe for STDOUT is not inherited. 
    if (!com.sun.jna.platform.win32.Kernel32.INSTANCE.SetHandleInformation(childStdOutRead.getValue(), HANDLE_FLAG_INHERIT, 0)){ 
     System.err.println(Kernel32.INSTANCE.GetLastError());; 
    } 

    // Create the child process. 
    if (!Kernel32.INSTANCE.CreateProcess(
      null, 
      cmd, 
      null, 
      null, 
      true, 
      new DWORD(0x00000020), //new DWORD(0x00000001) 
      null, 
      null, 
      startupInfo, 
      processInformation)){ 
     System.err.println(Kernel32Util.formatMessageFromLastErrorCode(Kernel32.INSTANCE.GetLastError())); 
     return false; 

    }else { 
     System.out.println("Created Process :"+processInformation.dwProcessId.intValue()); 
     processData.setProcessId(processInformation.dwProcessId.intValue()); 
     //processData.sethProcess(processInformation.hProcess); 
     //com.sun.jna.platform.win32.Kernel32.INSTANCE.WaitForSingleObject(processInformation.hProcess, 0xFFFFFFFF); 

     HANDLE inputFile = com.sun.jna.platform.win32.Kernel32.INSTANCE.CreateFile(
       "c:\\"+processInformation.dwProcessId.intValue()+".txt", 
       GENERIC_READ, 
       0, 
       null, 
       OPEN_EXISTING, 
       FILE_ATTRIBUTE_READONLY, 
       null); 
     //ReadFromPipe(childStdOutRead,childStdOutWrite); 
     com.sun.jna.platform.win32.Kernel32.INSTANCE.CloseHandle(processInformation.hProcess); 
     com.sun.jna.platform.win32.Kernel32.INSTANCE.CloseHandle(processInformation.hThread); 
     return true; 
    } 
} 

回答

0

我可以在創建過程選項中使用以下修改來創建靜默過程(無控制檯)。 但仍需你重定向輸出過程

Kernel32.INSTANCE.CreateProcess(
      null, 
      cmd, 
      null, 
      null, 
      true, 
      new DWORD(WinBase.CREATE_NO_WINDOW), 
      null, 
      null, 
      startupInfo, 
      processInformation) 
1

在窗口上,調用javaw.exe而不是java.exe。這將避免「控制檯」窗口。

至於重定向到文件,最簡單的方法可能是將一個參數傳遞給Java子進程以指示所需的文件,然後重定向System.outSystem.err以寫入該文件。

System.outSystem.errPrintStream S,所以在啓動時,你可以簡單地創建你自己的(映射到FileOutputStream)重定向所有控制檯輸出。詳細信息請參見this question on SO

+0

javaw進程並沒有解決我的問題的幫助。請參閱下面的答案以創建靜默過程。 – Debopam

+0

爲什麼運行javaw.exe不會阻止顯示控制檯窗口?順便說一句,你應該編輯你的原始問題,而不是添加部分「答案」。 – technomage

+0

您是否閱讀過上面描述如何重定向Java過程輸出的StackOverflow鏈接? – technomage

相關問題