从C#和.NET自动启动java-web-start应用程序,.WaitForExit(); 不能按预期工作

Nat*_*ate 1 .net c# system.diagnostics java-web-start

我正在使用C#应用程序来启动java Web应用程序.我希望我的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();
Run Code Online (Sandbox Code Playgroud)

这段代码成功启动了java程序,然后WaitForExit()被调用并立即返回.我相信这是因为"javaws"只是启动另一个名为"javaw"的进程,然后"javaws"关闭.有没有办法A)等待所有子进程也完成,或者B)等待特定的子进程?

-

我发现了这个相关的帖子:javaws退出代码真的坏了吗?虽然答案表明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();
Run Code Online (Sandbox Code Playgroud)

如果javaw在计算机上运行其他Java Web应用程序,则仅提供等待最近启动的进程的额外好处.

rot*_*man 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();
}
Run Code Online (Sandbox Code Playgroud)

不仅要杀死javaw,还要杀死所有子进程,需要获取javaws的进程ID,并将其与所有正在运行的进程的父ID进行比较.这是完整的代码:(扩展方法来自这里)

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));
    }
}
Run Code Online (Sandbox Code Playgroud)