2011-02-07 44 views
1

我正在使用C#應用程序來啓動Java Web應用程序。我希望我的C#應用​​程序知道用戶什麼時候關閉了Java應用程序。我使用此代碼:從C#和.NET自動啓動java-web-start應用程序,.WaitForExit();無法正常工作

var javaws = File.Exists(@"C:\Program Files\Java\jre6\bin\javaws.exe") ? @"C:\Program Files\Java\jre6\bin\javaws.exe" : @"C:\Program Files (x86)\Java\jre6\bin\javaws.exe"; 

var psi = new ProcessStartInfo(javaws, String.Format("http://{0}:/appstart.jnlp", hostAddress)); 

Process.Start(psi).WaitForExit(); 

此代碼成功啓動java程序,但是,WaitForExit()被調用,並立即返回。我相信這是因爲「javaws」只是啓動另一個名爲「javaw」的進程,然後「javaws」關閉。是否有任何方法可以A)等待所有子進程完成,或者B)等待特定的子進程?

-

我發現這個相關的職位:Are javaws exit codes really broken?,雖然答案有暗示1.6.0_23已經修好了,我看到完全相同的行爲我的開發機器上使用Java 1.6.0_23。我正在尋找的是一種解決方法,使上面的代碼按預期工作。我需要啓動這個jnlp文件,等待它的執行完成,然後在C#程序中做一些額外的代碼。 Java應用程序超出了我的控制範圍,所以我無法在其中添加功能。

-

大家很奇怪,最終的解決方案是這樣的:

var javaws = File.Exists(@"C:\Program Files\Java\jre6\bin\javaws.exe") ? @"C:\Program Files\Java\jre6\bin\javaws.exe" : @"C:\Program Files (x86)\Java\jre6\bin\javaws.exe"; 
var psi = new ProcessStartInfo(javaws, String.Format("http://{0}:/appstart.jnlp", hostAddress)); 
Process.Start(psi).WaitForExit(); 

var javaw = Process.GetProcessesByName("javaw"); 
javaw.Single(ja => ja.StartTime.Equals(javaw.Max(j => j.StartTime))).WaitForExit(); 

這提供的只是等待最近啓動的javaw過程中,事件的額外好處還有其他在機器上運行的java web應用程序。

回答

5

你可以從正在運行的進程列表中所需的過程,然後等待它退出:

var javaws = File.Exists(@"C:\Program Files\Java\jre6\bin\javaws.exe") ? @"C:\Program Files\Java\jre6\bin\javaws.exe" : @"C:\Program Files (x86)\Java\jre6\bin\javaws.exe"; 
var psi = new ProcessStartInfo(javaws, String.Format("http://{0}:/appstart.jnlp", hostAddress)); 

// make sure child process is already started 
Process.Start(psi).WaitForExit(); 

foreach (Process p in Process.GetProcessesByName("javaw")) 
{ 
    p.WaitForExit(); 
} 

殺不僅javaw進程,但所有孩子的處理,你需要得到的進程ID javaws並將其與所有正在運行的進程的父ID進行比較。下面是完整的代碼: (擴展方法來自here

class Program 
{ 
    static void Main(string[] args) 
    { 
     var javaws = File.Exists(@"C:\Program Files\Java\jre6\bin\javaws.exe") ? @"C:\Program Files\Java\jre6\bin\javaws.exe" : @"C:\Program Files (x86)\Java\jre6\bin\javaws.exe"; 
     var psi = new ProcessStartInfo(javaws, String.Format("http://{0}:/appstart.jnlp", hostAddress)); 

     var parentProc = Process.Start(psi); 
     parentProc.WaitForExit(); 

     foreach (Process p in Process.GetProcesses()) 
     { 
      if (p.Parent().Id == parentProc.Id) 
       p.WaitForExit(); 
     } 
    } 
} 

public static class ProcessExtensions 
{ 
    private static string FindIndexedProcessName(int pid) 
    { 
     var processName = Process.GetProcessById(pid).ProcessName; 
     var processesByName = Process.GetProcessesByName(processName); 
     string processIndexdName = null; 

     for (var index = 0; index < processesByName.Length; index++) 
     { 
      processIndexdName = index == 0 ? processName : processName + "#" + index; 
      var processId = new PerformanceCounter("Process", "ID Process", processIndexdName); 
      if ((int)processId.NextValue() == pid) 
      { 
       return processIndexdName; 
      } 
     } 

     return processIndexdName; 
    } 

    private static Process FindPidFromIndexedProcessName(string indexedProcessName) 
    { 
     var parentId = new PerformanceCounter("Process", "Creating Process ID", indexedProcessName); 
     return Process.GetProcessById((int)parentId.NextValue()); 
    } 

    public static Process Parent(this Process process) 
    { 
     return FindPidFromIndexedProcessName(FindIndexedProcessName(process.Id)); 
    } 
} 
+0

我測試@ rotman的解決方案,它的工作原理。 – Pat 2011-02-15 15:44:52

相關問題