0

私は2つの部分を持つアプリケーションを開発しています:

1) システム トレイから実行される WPF アプリケーション。sys-trayアイコンを右クリックしてコンテキストメニューのオプションを選択することで起動できるGUIウィンドウがありますが、頻繁に必要とされるわけではなく、ほとんどの場合、アプリはsys-trayから実行されます時間。さらに、MainWindow の Closing() イベントを変更して、ユーザーがアプリを閉じようとした場合にアプリを最小化するようにしました。

2) コンソールを表示せずに実行されるコンソール アプリケーション。その目的は、別のアプリケーションの起動/終了をポーリングすることです。他のアプリケーションが起動/終了するとすぐに、コンソール アプリケーションも WPF アプリケーションを起動/終了します。(Windows サービスを使用してこれを行うように言わないでください。以前にこのルートを調査しました。いくつかの理由でうまくいきません。ここでは取り上げません)。

問題: コンソール アプリケーションから WPF アプリケーションを閉じることができません。私がやっていることは次のとおりです。まず、WPF アプリケーションのプロセスを取得します。

Process AppProcess = Process.GetProcessById((int)AppID);

この後、次のように多くのオプションを試しました。

1) プロセスの強制終了: AppProcess.Kill();

これは機能した唯一のものですが、非常に洗練されていません。また、SysTray アイコンが未処理のままになるため、受け入れられません。

2) AppProcess.Close();

まったく機能しません。理由はわかりません。

3) AppProcess.Dispose();

まったく機能しません。理由はわかりません。

4) AppProcess.CloseMainWindow();

これは、ユーザーが WPF アプリの GUI を開いたままにしている場合にのみ機能します。これは、前に述べたように非常にまれです。したがって、通常、これも機能しません。(ウィンドウを閉じるのを防ぐために Closing() イベントをハッキングしたと言うかもしれません。心配する必要はありません。私はそれを処理するために適切な注意を払いました。アプリを閉じるための他の方法を提供しました。ブール変数があります。 Closing アクションをキャンセルするかどうかを決定します。)

5) カスタム/標準メッセージを WPF アプリケーションのメイン ウィンドウに渡します。

これは、WPF アプリのメイン ウィンドウ (GUI) が開いている場合にのみ機能し、それ以外の場合はメッセージを受信しません。

したがって、全体として、どの方法も機能していません。コンソール アプリから WPF アプリを正常に閉じるための信頼できる方法が必要です。何か提案してください。

私が現在行っている方法は次のとおりです。

コンソール アプリで:

const uint WM_CUSTOMCLOSE = 0xFE;
IntPtr hWnd = AppProcess.MainWindowHandle;
SendMessage(hWnd, WM_CUSTOMCLOSE, 0, 0);

WPF アプリで:

protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
source.AddHook(WndProc);
}

private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    if(msg == 0xFE)
    {
        ExitFlag = true;  //Exitflag is checked later to decide whether closing is to be cancelled.
        this.Close();
    }
    return IntPtr.Zero;
}
4

2 に答える 2

0

OK、WPF アプリを閉じる方法を見つけました。メッセージを受信して​​いなかった理由は、WPF アプリがシステム トレイから実行されたときに、何らかの理由で AppProcess.MainWindowHandle が WPF アプリのメイン ウィンドウのハンドルを与えていなかったためです。

そのため、代わりに Win32 API にある user32.dll:FindWindow() メソッドを使用して、WPF アプリのメイン ウィンドウを見つけます。その後、カスタム メッセージを渡すと、WPF アプリは正常にシャットダウンします。

于 2013-06-26T06:13:34.380 に答える
0

JeffRSon が提案した IPC を使用します。MSMQ は、2 つのプロセスが同じマシン上にある場合に非常に簡単で効果的な方法です。

WPF アプリケーションのキューを定義し、起動時に UI を表示するかどうかに関係なく、キューをリッスンします。コンソール アプリケーションは、アプリケーション メッセージを閉じてキューにメッセージを送信できます。データ コントラクトを定義する必要があります。以下を参照できます。

http://www.codeproject.com/Articles/3944/Programming-MSMQ-in-NET-Part-1

于 2013-06-25T18:47:41.373 に答える