如何使用没有.msi文件的产品ID guid与msiexec一起卸载

sno*_*gle 26 windows-installer wix uninstall msiexec

我正在尝试自动卸载使用WiX创建的软件包,以便更改已安装的软件堆栈和配置,而无需重新配置整个操作系统.最终我将使用powershell脚本来执行此操作,但目前我似乎无法使用cmd以交互方式卸载我的测试包.

如果我跑:

msiexec /x '{A4BFF20C-A21E-4720-88E5-79D5A5AEB2E8}'

msiexec /x A4BFF20C-A21E-4720-88E5-79D5A5AEB2E8

我明白了:

"无法打开安装包.验证包是否存在以及您是否可以访问它,或联系应用程序供应商以验证这是否是有效的Windows Installer程序包."

如果我跑: msiexec /x {A4BFF20C-A21E-4720-88E5-79D5A5AEB2E8}

我明白了:

"此操作仅对当前安装的产品有效"

我查看了Windows安装程序指南,WiX文档,msiexec文档,并使用orca自己查看.msi,但我还没有找到任何可以清楚地了解卸载处理方式的内容.是否需要.msi文件,如果没有,那么为什么Windows安装程序在给出GUID时似乎认为它是?

.msi安装程序的WiX代码是:

<?xml version='1.0' encoding='windows-1252'?>
<Wix xmlns='htp://schemas.microsoft.com/wix/2006/wi' >

  <!--DO NOT COPY / PASTE THE PRODUCT ID GUID BELOW TO YOUR OWN WIX SOURCE -->

  <Product Id='A4BFF20C-A21E-4720-88E5-79D5A5AEB2E8' Language='2057' 
           Manufacturer='COMPANYNAME IT-Operations' 
           Name='COMPANYNAMEServerListener' Version='1.0.0' 
           UpgradeCode='PUT-GUID-HERE'>

   <Package Id='*' Manufacturer='COMPANYNAME IT-Operations' Compressed='yes' />
   <Media Id='1' Cabinet='COMPANYNAMEServerListener.cab' EmbedCab='yes' />

    <Directory Id='TARGETDIR' Name='SourceDir'>
      <Directory Id='ProgramFilesFolder' Name='PFiles'>
      <Directory Id='COMPANYNAME' Name='COMPANYNAME'>
        <Directory Id='INSTALLDIR' Name='COMPANYNAMEServerListener'>
        <Component Id='MainExecutable' Guid='*' >
          <File Id='COMPANYNAMEServerListener.exe' 
                Source='COMPANYNAMEServerListener.exe' Vital='yes' 
                KeyPath='yes' />
          <ServiceInstall 
            Id='COMPANYNAMEServerListenerInstall'
            DisplayName='COMPANYNAMEServerListener'
            Description='Accepts and discards TCP connections on port 28028 to indicate that this server is alive and ready to be controlled'
            Name='COMPANYNAMEServerListener'
            Account='NT AUTHORITY\LocalService'
            ErrorControl='normal'
            Start='auto'
            Type='ownProcess'
            Vital='yes'           
          >
            <ServiceDependency Id='tcpip'/>
          </ServiceInstall>
          <ServiceControl Id="StartService" Start="install" Stop="both" Remove="uninstall" Name="COMPANYNAMEServerListener" Wait="yes" />
        </Component>
        </Directory>
        </Directory>
      </Directory>
      </Directory>

    <Feature Id='Complete' Level='1' >
      <ComponentRef Id='MainExecutable' />
    </Feature>

    <CustomTable Id ="COMPANYNAMEMetadata">
      <Column Id="Property" Type="string" Category="Identifier" PrimaryKey="yes"/>
      <Column Id="Value" Type="string"/>
      <Row>
      <Data Column="Property">InstallString</Data>
      <Data Column="Value">/qn</Data>
      </Row>
    </CustomTable>


  </Product>
</Wix>
Run Code Online (Sandbox Code Playgroud)

Ste*_*mul 34

"参考风格"答案:这是下面一个的替代答案,显示了几个不同的选项.在不使用msiexec的情况下从命令行卸载MSI文件.


您指定的命令是正确的:msiexec/x {A4BFF20C-A21E-4720-88E5-79D5A5AEB2E8}

如果您收到" 此操作仅对当前安装的产品有效",则表示您使用了无法识别的产品或包裹代码,并且必须找到正确的产品或包裹代码.通常这可以通过使用错误的包代码而不是产品代码来卸载 - 包代码随着MSI文件的每次重建而改变,并且是您在查看msi文件的属性页时看到的唯一指示.它应该适用于卸载,只要您使用正确的.没有错误的余地.如果要查找产品代码,则需要打开MSI.产品代码可在Property表中找到.


更新,2018年1月:

随着所有注册表重定向的继续,我不确定以下基于注册表的方法是否可行.我没有正确检查,因为我现在依赖于使用PowerShell的以下方法:如何找到已安装的MSI设置的产品GUID?

另请参阅此参考样式的答案,说明卸载MSI软件包的不同方法以及确定已安装的产品版本的方法: 从命令行卸载MSI文件而不使用msiexec


遗产,注册表选项:

您还可以通过使用此基本密钥注册表查找产品代码: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall.按F3键搜索您的产品名称.(如果它是64位计算机上的32位安装程序,则可能位于HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall下).

Legacy,PowerShell选项 :(大致类似于上面的新链接答案)

最后,您可以使用PowerShell找到产品代码:

get-wmiobject Win32_Product | Format-Table IdentifyingNumber, Name
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

类似文章:WiX - 在多实例安装上进行重大升级(如何在MSI中查找产品代码的屏幕截图).

  • 最后一点:您绝不能在MSI文件中对包代码进行硬编码,以便在构建之间重用.根据定义,这将强制Windows Installer将不同的MSI文件视为同一文件 - 即使它们具有不同的内容 - 这会导致许多神秘问题. (2认同)

小智 7

msiexec.exe /x "{588A9A11-1E20-4B91-8817-2D36ACBBBF9F}" /q 
Run Code Online (Sandbox Code Playgroud)

  • 你能给你的答案提供更多的背景吗? (2认同)
  • 原因是你从 PowerShell 中调用它。PowerShell 您需要引用,以便将产品 ID 视为字符串。 (2认同)

Phi*_*ilm 5

好消息是,这个分析真的很容易且确定性地分析:要么,系统上确实没有安装 msi 包,要么你做错了什么。当然正确的调用是:

msiexec /x {A4BFF20C-A21E-4720-88E5-79D5A5AEB2E8}
Run Code Online (Sandbox Code Playgroud)

(当然需要管理员权限 - 此处使用大括号不带任何引号 - 仅需要引号,如果在命令行中指定了带有空白的路径或值。)
如果消息是:“此操作仅对当前安装的产品有效”,那么这是真的。未安装带有此 ProductCode 的软件包或有拼写错误。

要验证故障在哪里:

  1. 首先尝试右键单击(可能)已安装的 .msi 文件本身。您将看到(除了“安装”和“修复”)一个卸载条目。点击那个。
    a) 如果卸载有效,则您的 msi 有另一个超出您预期的 ProductCode(可能您的 WiX 源有误,或者您的构建在 ProductCode 更改的地方具有动态日志记录)。
    b) 如果卸载给出相同的“...仅对已安装的产品有效”,则未安装软件包(这显然是能够卸载它的先决条件)。

  2. 如果 1.a) 是这种情况,如果您使用 Orca、Insted 或其他编辑器/工具打开您的 msi 文件,您可以查找您的包的正确 ProductCode。只需谷歌他们。在表中查找名称为“Property”并在第一列中搜索字符串“ProductCode”。在第二列中有正确的值。

没有其他可能性。

只是对使用的命令行的建议:我至少会为简单的进度条或“/qn”参数添加“/qb”(后者用于完全静默卸载,但只有在您确定它有效时才有意义)。


sno*_*gle 1

感谢大家的帮助 - 原来这是一个 WiX 问题。

当产品 ID GUID 保持显式和硬编码(如问题中所示)时,生成的 .msi 没有 ProductCode 属性,但在使用 orca 检查时有一个 Product ID 属性。

一旦我将 GUID 更改为“*”以自动生成,ProductCode 就会显示出来,并且一切正常,语法得到其他答案的确认。