1

C# アプリケーションを使用して Java Web アプリケーションを起動しています。ユーザーがいつ Java アプリケーションを終了したかを C# アプリケーションに認識させたいと考えています。私はこのコードを使用しています:

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) 特定の子プロセスを待つ方法はありますか?

--

この関連記事を発見しました: 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();

javawこれにより、マシンで他の Java Web アプリが実行されている場合に、最後に開始されたプロセスのみを待機するという追加の利点が提供されます。

4

2 に答える 2

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だけでなくすべての子プロセスを強制終了するには、 javawsのプロセス ID を取得し、それを実行中のすべてのプロセスの親 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));
    }
}
于 2011-02-15T13:15:03.347 に答える
2

いくつかのドキュメントを見ると、「-wait」をパラメーターとして javaws に渡して、アプリケーションが終了するまで待機させることができるようです。 http://download.oracle.com/javase/1.5.0/docs/guide/javaws/developersguide/javaws.html

于 2011-02-08T20:57:42.920 に答える