私のWiXインストーラーでは、まだ実行中の場合に、更新しようとしているアプリケーションを正常に終了したいと考えています。ユーザーを閉じるように促したくないので、プロセスを終了したくありません。アプリケーションを閉じる前に、クリーンアップなどを行う機会が必要です。Wix管理のカスタムアクションでインストールする前に、アプリケーションを正常に終了してください
このアプリケーションは、システムトレイで動作するWinFormsアプリケーションです。メインフォームにはタイトルがありますが、たとえば "mainwindow"としましょうが、隠されていてShowInTaskbar = falseです。いくつかの異なるテスターのアプリがProcess.Kill() Process.CloseMainWindow() FindWindow, SendMessage, PostMessage
などをしようと遊んによって
私は私がこれを行うための最善の方法は、PostMessage
var hWnd = FindWindow(null, "mainwindowtitle");
PostMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
私はOnFormClosingをオーバーライドすることができますこの方法を使用して、任意のクリーンアップIを実行することであることを発見しました必要。これは私が一緒に投げたテスターアプリからうまく動作します。問題は、WiXインストーラで実行しても機能しないことです。私はC#カスタムアクションCA.dllを持っており、インストーラーはカスタムアクションを確実に呼び出します - msiexecログから見ることができます。カスタムアクションコードをProcess.Kill()
に変更すると、正しくアプリケーションが停止します。しかし、それがPostMessage
コードで実行されると、アプリケーションは閉じず、OnFormClosingは呼び出されません。
がここにここに私のCustomActionコード
private const int WM_CLOSE = 0x0010;
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", SetLastError = true)]
static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[CustomAction]
public static ActionResult CloseApplicationGracefully(Session session)
{
session.Log("Starting the CloseApplicationGracefully Custom Action - attempting to stop DUC.");
var hWnd = FindWindow(null, "mainwindowtitle");
session.Log("Window handle found: " + hWnd);
bool result = PostMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
session.Log("Result of calling app to close: " + result);
if (result)
{
return ActionResult.Success;
}
return ActionResult.Failure;
}
が、私は異なる順序で、このカスタムアクションが、運を呼ぶ試してみましたWXセットアップコード
<Binary Id="WixCustomAction.dll"
SourceFile="$(var.WixCustomAction.TargetDir)$(var.WixCustomAction.TargetName).CA.dll" />
<CustomAction Id="WixCustomAction"
BinaryKey="WixCustomAction.dll"
DllEntry="CloseDeploymentUpdater" />
<InstallExecuteSequence>
<Custom Action="WixCustomAction" After="FindRelatedProducts"></Custom>
</InstallExecuteSequence>
です... コードから作品テスターアプリとカスタムアクションは、私がProcess.Killを使用すると動作しますが、コードはカスタムアクションに入れられたときには機能しません - イベントのシーケンスでなければなりませんか?ウィックスからCloseAppのCustomActionを理解していれば
EDIT
WixCloseApplications CAを使用して、次のログエントリに回答結果に以下の提案として
WixCloseApplications: App: DUC.exe found running, 1 processes, attempting to send close message.
WixCloseApplications: Sending close message to process id 0x1978
WixCloseApplications: Result 0x12
WixCloseApplications: Sending close message to process id 0x1978
WixCloseApplications: Result 0x0
WixCloseApplications: Sending close message to process id 0x1978
WixCloseApplications: Result 0x578
WixCloseApplications: Sending close message to process id 0x1978
WixCloseApplications: Result 0x0
.
.
.
MSI (s) (C8!D4) [15:00:47:985]: PROPERTY CHANGE: Adding WixCloseApplicationsDeferred property. Its value is 'DUC.exe5'.
MSI (s) (C8!D4) [15:00:48:000]: Doing action: WixCloseApplicationsDeferred
.
.
Action 15:00:48: WixCloseApplicationsDeferred.
Action start 15:00:48: WixCloseApplicationsDeferred.
.
.
Action ended 15:00:48: WixCloseApplicationsDeferred. Return value 1.
Action ended 15:00:48: WixCloseApplications. Return value 1.
PostMessageの代わりにカスタムアクションでSendMessageコールを試しましたか? –
@ Vijay Sirigiri Yep - 私はSendMessage(SC_CLOSEを使用)を試してみましたが、これは私のテスターアプリでは動作しましたが、WiXインストーラーでは動作しませんでした。興味深いことに、OnFormClosingのEventArgsにはCloseReason列挙型があり、WM_CLOSEを使用するPostMessageは、taskmanagerがクローズを要求した理由と思われ、SC_CLOSEを使用したSendMessageはUserがクローズを要求したように見えます。 –
@rene有効なハンドルを取得できますが、PostMessageの結果はfalseなので、何らかの理由で正しく動作しません。 MSDNはPostMessageでWM_QUITを使用しないことを推奨します。私はとにかくそれを試して何が起こるか見てみましょうが、私はこの場合OnFormClosingイベントが発生しないと思われます。 –