2011-02-08 17 views
2

私の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. 
+0

PostMessageの代わりにカスタムアクションでSendMessageコールを試しましたか? –

+0

@ Vijay Sirigiri Yep - 私はSendMessage(SC_CLOSEを使用)を試してみましたが、これは私のテスターアプリでは動作しましたが、WiXインストーラーでは動作しませんでした。興味深いことに、OnFormClosingのEventArgsにはCloseReason列挙型があり、WM_CLOSEを使用するPostMessageは、taskmanagerがクローズを要求した理由と思われ、SC_CLOSEを使用したSendMessageはUserがクローズを要求したように見えます。 –

+0

@rene有効なハンドルを取得できますが、PostMessageの結果はfalseなので、何らかの理由で正しく動作しません。 MSDNはPostMessageでWM_QUITを使用しないことを推奨します。私はとにかくそれを試して何が起こるか見てみましょうが、私はこの場合OnFormClosingイベントが発生しないと思われます。 –

答えて

2

正しく、あなたはすべてのウィンドウの上に列挙すべきですプロセスで

http://wix.codeplex.com/SourceControl/changeset/view/175af30efe78#src%2fca%2fwixca%2fdll%2fCloseApps.cpp

だから、(processToCloseをHANDLE、EnumCallBack)EnumWindowsを実装する必要があります そして、それぞれのウィンドウのEnumCallBackであなたの実際のPostMessage WM_CLOSE。

+0

CloseAppのソースコードを指し示すのは便利ですが、組み込みのCA WixCloseApplicationsで使用されているものではありませんか?私はそれを試して、アプリケーションを閉じますが、正常には実行されません。つまり、OnFormClosingイベントは発生しません。 –

+0

@Peter Kelly MSIが上昇しているかどうか、またはCAがdefferedされていたかどうか、私は考えていました。ログを投稿できますか? msiexec/i [あなたのmsi]/l * vx logfile.log – rene

+0

@rene util:CloseApplicationを使用した後、いくつかのログエントリを投稿しました。延期の影響は何ですか? –

関連する問題