Wix工具集:“禁止卸载组件后完全清理,因为存在另一个客户端”

时间:2014-11-04 15:58:53

标签: wix installer windows-installer wix3.8 uninstaller

今天我发现我的安装程序不再正确卸载了。这意味着从那里卸载后我的应用程序不再显示在控制面板中,但所有文件仍然存在。我查看了日志文件,我看到很多"禁止卸载组件,因为另一个客户端存在" afaik意味着我搞砸了..

那么清理我的电脑并防止它在将来发生的最佳方法是什么?可能是什么导致了这个? afaik没有完全卸载我的应用程序的先前版本是出现此错误的原因?

不幸的是,出于各种原因无法使用VM ..

仅供参考:为了开发和测试目的,我通常使用1.0.xxxxx测试和创建安装程序,其中xxxxx通常保持不变。我的升级代码总是一样的。另外我使用的是热量,只要有可能,我就让wix自动生成GUID。此外,我有一个CA在安装后显示我的自述文件,一个用于执行批处理文件(使用powercfg修改注册表项)。卸载后,运行可执行文件以导入.reg文件以恢复已修改的注册表项(因为它们将由wix卸载)。

4 个答案:

答案 0 :(得分:8)

即使这是一个有点旧的链接,但是发布我的发现可能对其他人有帮助,他们面临同样的情况。

如果您在日志文件中找到了"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

答案 1 :(得分:7)

听起来您需要卸载已安装不需要的组件的功能(或整个产品)。 Windows Installer具有用于查询组件,功能和产品的API。 WiX工具集在API周围加入了一个名为DTF的包装器。您可以使用它按组件查询功能。

所以,打破你最喜欢的.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>仅删除安装该组件的功能。

答案 2 :(得分:1)

我们最近遇到的情况是,我们的某台开发机器在卸载时无法删除所有组件。但是,在其他计算机上,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

答案 3 :(得分:0)

遵循此工作流程非常完美:

How to fix "disallowing uninstallation of component since another client exists"?

在那里创建两个文件之后,有必要在应用下一步之前为其删除BOM。我已经使用了记事本++(Encoding> Encode in UTF-8)。

使用记事本++的多光标功能很容易为每行添加/ f选项-使用SHIFT + ALT + Arrows

激活它