2014-11-04 56 views
2

今天我發現我的安裝程序無法正確卸載。這意味着我的應用程序在卸載後不再顯示在控制面板中,但所有文件仍然存在。我查看了日誌文件,並看到很多「不允許卸載組件,因爲另一個客戶端存在」,這意味着我搞砸了..Wix工具集:完成「禁止組件卸載,因爲另一個客戶端存在」之後的清理完畢

那麼,清理我的電腦並防止它發生的最佳方式是什麼在將來?這可能導致什麼? afaik一個沒有完全卸載我的應用程序的以前版本是這個錯誤的原因?

不幸的是,使用虛擬機是不可能的種種原因..

FYI:爲了開發和測試目的,我平時的測試,並與1.0.xxxxx創建安裝其中XXXXX經常保持不變。我的升級代碼總是一樣的。另外,我正在使用熱量,並且儘可能讓wix自動生成GUID。此外,我有一個CA在安裝後顯示我的自述文件,另一個執行批處理文件(使用powercfg修改註冊表項)。卸載後,運行一個可執行文件以導入.reg文件以恢復已修改的註冊表項(因爲它們將被wix卸載)。

+0

不,這不是錯誤;這是信息。由於您在共享組件後的產品之後安裝產品,因此在卸載所有產品之前不應刪除該組件。您可能希望在安裝由下一個版本生成的產品之前確保卸載產品。 – 2014-11-05 04:53:19

回答

4

這聽起來像您需要卸載已安裝不需要的組件的功能(或整個產品)。 Windows Installer具有用於查詢組件,功能和產品的API。 WiX工具集已經在名爲DTF的API中引入了一個包裝器。您可以使用它來按組件查詢功能。

因此,打破你最喜歡的.NET腳本亞軍(我的是LINQPad)並運行查詢。例如,要找出如何刪除 「candle.exe」:

// using System.Linq; 
// using Microsoft.Deployment.WindowsInstaller; 

// <ref>"C:\Program Files (x86)\WiX Toolset v3.8\SDK\ 
     Microsoft.Deployment.WindowsInstaller.dll"</ref> 

ComponentInstallation.AllComponents 
    .Where(c=>c.State == InstallState.Local) 
    .Where(c => c.Path.ToLowerInvariant().EndsWith(@"\candle.exe")) 
    .SelectMany(c => c.ClientProducts 
     .SelectMany(p => p.Features.Where(f => f.Usage.UseCount > 0) 
      .Select(f => new { 
       c.Path, 
       f.FeatureName, 
       p.LocalPackage, 
       p.UserSid, 
       p.ProductCode}))) 

LINQPad Instant Share

LINQPad Output

然後,運行msiexec /x <ProductCode>移除的產品

msiexec /i <LocalPackage> REMOVE=<FeatureName>的所有功能只刪除安裝該組件的功能。

5

儘管這是一箇舊的鏈接,但是張貼我的發現可能有助於其他人,誰面臨着這樣的情況。

如果您在日誌文件中發現了"Disallowing uninstallation of component: {Some GUID} since another client exists",那麼原因可能是您之前的安裝可能仍然指向此組件/ GUID。

此外,如果您冒着嘗試手動刪除註冊表項的風險,則甚至可能無法在註冊表中找到GUID。

但是這些註冊管理機構中很少有可能在那裏,它們可能被隱藏。在這種情況下使用RegSeeker工具http://www.hoverdesk.net/,它可以幫助找到隱藏的註冊表。在處理註冊表時請保持警惕和謹慎。

根據GUID,從解決方案/項目中獲取組件的名稱,並使用此工具的「查找註冊表」選項找到它。驗證並刪除您認爲不需要的條目。

誠然,我就用下面的鏈接

http://www.daviddeley.com/solutions/msiexec/index.htm

0

我們最近有我們開發的一臺機器無法移除對卸載所有組件的情況下了解這個工具。但在其他機器上,WiX設置按預期工作。

因此,如果您錯誤地卸載了早期版本的產品並收到消息Disallowing uninstallation of component: {GUID} since another client exists,那麼很有可能您的孤立組件存在於註冊表中。

有刪除那些隱藏註冊表項與PowerShell而不是使用,如由他人,第三方應用程序提到一個更優雅的解決方案。

$productName = "Path\\YourProductName" # this should basically match against your previous 
# installation path. Make sure that you don't mess with other components used 
# by any other MSI package 

$components = Get-ChildItem -Path HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\ 
$count = 0 

foreach ($c in $components) 
{ 
    foreach($p in $c.Property) 
    { 
     $propValue = (Get-ItemProperty "Registry::$($c.Name)" -Name "$($p)")."$($p)" 
     if ($propValue -match $productName) 
     { 
      Write-Output $propValue 
      $count++ 
      Remove-Item "Registry::$($c.Name)" -Recurse 
     } 
    } 
} 

Write-Host "$($count) key(s) removed" 

如果你想獲得有關消息disallowing uninstallation...原因的更詳細的解釋來看看here

相關問題