2015-10-20 48 views
1

我想解決如何防止重新啓動管理器檢測到卸載我的應用程序時需要重新啓動。MSI安裝程序InstallValidate如何確定正在使用的文件?

我的應用程序具有使用本地DLL(狸包裝),並創建另一個進程(Java),它寫入一些日誌文件的Windows服務。我使用的是WiX Toolset,但我對MSI安裝程序本身更感興趣。我一直在嘗試使用Orca手動進行一些更改。爲了參考的相關維克斯構型是(有我已經省略了JAR文件等一些其他部件):

<DirectoryRef Id="logs3327407xx"> 
    <Component Guid="344ec345-bdd7-4c1d-801f-55ddf9e07735" Id="logs_wrapper_log88580873x"> 
     <File DiskId="1" Id="fl_logs_wrapper_log88580873x" Name="wrapper.log" Source="logs\wrapper.log"/> 
    </Component> 
</DirectoryRef> 
<DirectoryRef Id="bin97543xxxx"> 
    <Component Guid="67c93dd8-36ad-427f-9d79-64a07c719eea" Id="bin_wrapper_windows_x86_64_exe189026768"> 
     <File DiskId="1" Id="fl_bin_wrapper_windows_x86_64_exe189026768" KeyPath="yes" Name="wrapper-windows-x86-64.exe" Source="bin\wrapper-windows-x86-64.exe"/> 
     <ServiceInstall Account="LocalSystem" Arguments="-s &quot;..\conf\wrapper.conf&quot; wrapper.console.flush=true" Description="My Example Service." DisplayName="My Service" ErrorControl="ignore" Id="srvc_i_bin_wrapper_windows_x86_64_exe189026768" Interactive="no" Name="MyService" Start="auto" Type="ownProcess" Vital="yes"/> 
     <ServiceControl Id="srvc_c_bin_wrapper_windows_x86_64_exe189026768" Name="MyService" Remove="uninstall" Start="install" Stop="both" Wait="yes"/> 
    </Component> 
</DirectoryRef> 
<DirectoryRef Id="bin_wrapper_native490235675"> 
    <Component Guid="d7e4295a-1ce5-4dd2-aa92-230caac34247" Id="bin_wrapper_native_wrapper_windows_x86_64_dll156404367"> 
     <File DiskId="1" Id="fl_bin_wrapper_native_wrapper_windows_x86_64_dll156404367" Name="wrapper-windows-x86-64.dll" Source="bin\wrapper\native\wrapper-windows-x86-64.dll"/> 
    </Component> 
</DirectoryRef> 

我明白,有在InstallValidate動作確定文件是否在使用中的邏輯。它將使用基於MSIRESTARTMANAGERCONTROL property的重新啓動管理器或FilesInUse。

如果我使用的重新啓動管理器,然後它打開的對話框中說,需要重新啓動。日誌說:

MSI (s) (1C:7C) [12:27:14:679]: Doing action: InstallValidate 
Action ended 12:27:14: MigrateFeatureStates. Return value 0. 
MSI (s) (1C:7C) [12:27:14:679]: PROPERTY CHANGE: Deleting MsiRestartManagerSessionKey property. Its current value is 'f2947dee632d694f8b4f1795ff254092'. 
... 
MSI (s) (1C:7C) [12:27:14:679]: Component: bin_wrapper_windows_x86_64_exe189026768; Installed: Local; Request: Absent; Action: Absent; Client State: Local 
MSI (s) (1C:7C) [12:27:14:679]: Component: bin_wrapper_native_wrapper_windows_x86_64_dll156404367; Installed: Local; Request: Absent; Action: Absent; Client State: Local 
MSI (s) (1C:7C) [12:27:14:679]: Component: logs_wrapper_log88580873x; Installed: Local; Request: Absent; Action: Absent; Client State: Local 
... 
MSI (s) (1C:7C) [12:27:14:741]: RESTART MANAGER: Detected that application with id 11368, friendly name 'java.exe', of type RmCritical and status 1 holds file[s] in use. 
MSI (s) (1C:7C) [12:27:14:741]: RESTART MANAGER: Did detect that a critical application holds file[s] in use, so a reboot will be necessary. 
MSI (s) (1C:7C) [12:27:14:741]: Note: 1: 1610 

它實際上並沒有說的文件,但如果我禁用重啓管理器,並使用FilesInUse,而不是將不會出現任何對話框。這一次的日誌說:

Info 1603. The file C:\...\wrapper-windows-x86-64.exe is being held in use by the following process: Name: wrapper-windows-x86-64, Id: 11004, Window Title: '(not determined yet)'. Close that application and retry. 
MSI (s) (1C:8C) [12:33:23:458]: 2 application(s) had been reported to have files in use. 
Info 1603. The file C:\...\wrapper-windows-x86-64.dll is being held in use by the following process: Name: java, Id: 8284, Window Title: '(not determined yet)'. Close that application and retry. 
MSI (s) (1C:8C) [12:33:23:458]: Note: 1: 2727 2: 
MSI (c) (AC:28) [12:33:23:458]: File In Use: -wrapper-windows-x86-64- Window could not be found. Process ID: 11004 
MSI (c) (AC:28) [12:33:23:458]: File In Use: -java- Window could not be found. Process ID: 8284 
MSI (c) (AC:28) [12:33:23:458]: No window with title could be found for FilesInUse 

是否有人可以解釋InstallValidate如何確定哪些文件正在使用中?

另外我怎麼能防止重啓管理器的說文件正在使用中,一旦該服務被停止,將被釋放?

作爲一個方面的問題,爲什麼是重啓管理器不顯示MsiRMFilesInUse對話?我已經檢查了MsiRMFilesInUse Dialog的所有要求,據我所知他們都是真的。

我記得使用ServiceControl而不是自定義操作幫助重新啓動管理器知道服務使用那File中的那些File。我曾嘗試將文件添加到該Component,但它似乎沒有任何區別。

回答

4

InstallValidate的行爲和使用有關的ServiceControl文件並不複雜。如果服務正在使用文件,並且該服務位於ServiceControl表中,並且被標記爲在卸載時停止,那麼它將忽略這些文件與使用中的行爲一樣。將文件放在同一個組件中並沒有什麼區別,顯然Windows無法知道服務代碼將關閉正在導致文件使用情況的進程。據我所知,沒有辦法告訴InstallValidate某些文件在卸載時真的不會被使用。

當不使用重啓管理器,因爲它需要的可提示用戶關閉關閉應用程序的活動窗口,您不會得到一箇舊式FilesInUse對話框。這是沒有活動窗口的托盤應用程序不會導致FilesInUse對話框的原因。我無法確定,但在我看來,引用Restart Manager的第一個日誌提取實際上是RMFilesInUse,我認爲這就是您所看到的對話框。

如果僅文件在使用你看到的都涉及到java程序,該服務將關閉問題則可能的解決方案是:

  1. 禁止所有在文件正在使用對話框卸載。
  2. 使用ServiceControl關閉您的服務。
  3. 確保您的ServiceControl爲Wait = 1,並且在java進程已終止之前它不響應「停止服務」請求,前提是您可以明確關閉它。

Windows並沒有那麼愚蠢,僅僅因爲在InstallValidate時間使用的文件,它會強制重啓,但在實際的刪除時間不是這樣。因此,如果您可以確保文件在實際需要移除/替換時不再使用,則無需重新啓動。看到對話並不罕見,然後發現重新啓動實際上不是必需的。因此,如果您禁止對話並關閉所有內容,則不會看到重新啓動請求。

相關問題