2011-02-07 56 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

相关问题