![](/img/trans.png)
[英]How to reference MSI files in a different folder when executing msiexec.exe command in windows batch file?
[英]How to remove installation folder when app is uninstalled? Installation folder happens to be locked by msiexec.exe process
我實際上花了一天時間嘗試做最簡單的事情。 (伙計,MSI / WiX很少!)
我的目標很簡單。 卸載我的應用程序后,我需要刪除安裝文件夾。 我這樣創建(使用WiX):
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFilesFolder' Name='InstallFolder'>
<Directory Id='idCompany.com' Name='$(var.CompanyName)'>
<Directory Id='INSTALLDIR' Name='$(var.ProductThis)' >
<Component Id='CompIDMyEXE1' Guid='{--GUID1--}'>
<File Id='idMyEXE1' Name='MyExe1.exe' DiskId='1' Source='MyExe1.exe' Vital='yes' KeyPath='yes' />
<ServiceControl Id="idSrvc" Name="SrvcName" Stop="both" Wait="yes" />
</Component>
<Component Id='CompIDMyEXE2' Guid='{--GUID2--}'>
<File Id='idMyEXE2' Name='MyExe2.exe' DiskId='1' Source='MyExe2.exe' Vital='yes' KeyPath='yes' />
</Component>
<!-- and so on -->
</Directory>
</Directory>
</Directory>
我首先嘗試使用這里建議的 RemoveFolder WiX關鍵字,但是無論我做了什么,我的安裝文件夾都不想去。 更糟糕的是,無法知道為什么它不起作用。 根本就是看不到我的標簽,還是什么...啊!
因此,我決定添加一個用C編寫的自定義操作,並從那里刪除該文件夾,因為在那里我將擁有更多的控制權。 所以我這樣做:
<CustomAction Id="CA_SetProperties_UninstallFinalize" Property="CA_msiOnUninstallFinalize" Value="[INSTALLDIR]" />
<CustomAction Id='CA_msiOnUninstallFinalize' BinaryKey='CADll' DllEntry='msiOnUninstallFinalize' Execute='deferred' Impersonate='no' />
<InstallExecuteSequence>
<!-- Need to run it for uninstalls only -->
<Custom Action="CA_SetProperties_UninstallFinalize" Before="InstallFinalize">
NOT REINSTALL AND NOT UPGRADINGPRODUCTCODE AND REMOVE
</Custom>
<Custom Action="CA_msiOnUninstallFinalize" After="CA_SetProperties_UninstallFinalize">
NOT REINSTALL AND NOT UPGRADINGPRODUCTCODE AND REMOVE
</Custom>
<!-- ... -->
</InstallExecuteSequence>
但是當我打電話RemoveDirectory API從我msiOnUninstallFinalize
方法對我的空安裝文件夾它一直返回ERROR_SHARING_VIOLATION
錯誤。
因此,我在msiOnUninstallFinalize
方法中msiOnUninstallFinalize
休息(只需添加一個MessageBox
調用),然后檢查了文件夾本身。 事實證明,那時的文件夾已經是空的,但是當我檢查它是否有鎖時,事實證明MSI本身持有該文件夾:
那這里有什么問題呢? 如何完成這個簡單的任務????
真是奇怪的問題。 事實證明,我創建了一個用於卸載應用程序的“卸載”快捷方式,如下所示:
<Shortcut Id="startmenuUninst"
Directory="ProgramMenuDir"
Target="[SystemFolder]msiexec.exe"
Arguments="/x [ProductCode]"
Name="Uninstall $(var.ProductThis)"
WorkingDirectory='INSTALLDIR'
Advertise='no'
Description="Uninstalls $(var.ProductThis)" />
問題恰好是WorkingDirectory
屬性,或者是在調用msiexec
進程時的Windows工作目錄。 由於某種原因,如果將其設置為要刪除的文件夾(在本例中為INSTALLDIR
),則msiexec
進程將具有內部鎖定,因此在卸載期間不會刪除該文件夾。
因此,對於我而言,解決方案非常簡單。 我需要將INSTALLDIR
替換為任何其他文件夾,例如: WorkingDirectory='SystemFolder'
,它會自動刪除它,而無需進行任何自定義操作,就像我上面顯示的那樣。
PS。 順便說一句,如果要使用msiexec.exe /x {Product-Code-GUID}
命令從C / C ++調用CreateProcess來卸載應用程序,請確保指定一個工作目錄,而不是在其中刪除的文件夾。 lpCurrentDirectory
參數。 請勿使用NULL
因為它可能會與我上面解釋的當前工作目錄產生歧義。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.