簡體   English   中英

卸載應用程序后如何刪​​除安裝文件夾? 安裝文件夾碰巧被msiexec.exe進程鎖定了

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM