【问题标题】:How to find the UpgradeCode and ProductCode of an installed application in Windows 7如何在 Windows 7 中查找已安装应用程序的 UpgradeCode 和 ProductCode
【发布时间】:2011-07-01 02:12:46
【问题描述】:

我的机器上安装了一个应用程序。我也有它的源代码,但不知怎的,这个应用程序的 ProductCode 和 UpgradeCode 被改变了。

现在我想获取这个已安装应用程序的 UpgradeCode 和 ProductCode。我觉得必须有一些工具来解决这个问题。

谁能告诉我如何获取已安装应用程序的 UpgradeCode 和 ProductCode?​​p>

【问题讨论】:

  • 您的应用程序是用什么语言开发的?

标签: automation wix installation windows-installer


【解决方案1】:

重要提示这个答案最初发布已经有一段时间了,聪明的人想出了更明智的答案。如果您需要可靠而全面的方法,请查看来自@Stein Åsmul 的How can I find the Upgrade Code for an installed MSI file?


这是另一种方式(您不需要任何工具):

  • 打开系统注册表并搜索 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall 键(如果它是 64 位机器上的 32 位安装程序,则可能在 HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall 下)。
  • 该键下列出的 GUID 是此计算机上安装的产品
  • 找到您正在谈论的那个 - 一步一步地直到您在右侧窗格中看到它的名字

您停止使用的 GUID 是 ProductCode。

现在,如果您确定重新安装此应用程序会正常运行,您可以运行以下命令行:

msiexec /i {PRODUCT-CODE-GUID-HERE} 重新安装=全部重新安装模式=omus /l*v 日志.txt

这将“修复”您的应用程序。现在查看日志文件并搜索“UpgradeCode”。这个值被转储在那里。

注意:只有在您确定重新安装流程已正确实施并且不会破坏已安装的应用程序时,您才应该这样做。

【讨论】:

  • 虽然这是一个令人印象深刻的解决方法,但缺乏好的工具,这听起来像一个糟糕的练习,充满了潜在的错误来源。借助 Powershell,我们无需任何第三方工具即可获得更好的方法。
  • @codekaizen:同意,您可以添加链接开始吗?编辑看到你的答案
  • 哎呀,这是一种繁琐且具有潜在破坏性和危险性的发现方法。我宁愿选择下面@ssdi 提供的非侵入式 Orca 方法
  • 这个 PowerShell 脚本也应该有帮助 scconfigmgr.com/2014/08/22/…
  • 使用 PowerShell 获取升级代码产品代码完整列表以及包名称How can I find the Upgrade Code for an installed MSI file?。这将为您提供真实的 MSI 数据库值,无需任何手动注册表查找或黑客攻击。
【解决方案2】:

返回结果需要一些时间,很容易几十秒,但wmic 效果很好,可以编写脚本:

wmic product where "Name like '%Word%'" get Name, Version, IdentifyingNumber

结果:

IdentifyingNumber                       Name                                      Version
{90140000-001B-0409-0000-0000000FF1CE}  Microsoft Office Word MUI (English) 2010  14.0.6029.1000

IdentifingNumber 是产品代码。我没有看到 UpgradeCode 的属性,但也许它可能被其他东西掩埋了。更多示例请参见http://quux.wiki.zoho.com/WMIC-Snippets.htmlincluding uninstall

wmic path win32_product where "name = 'HP Software Update'" call Uninstall

【讨论】:

【解决方案3】:

致所有使用:

Get-WMIObject win32_product

您应该知道,这将在 PC 上安装的每个 MSI 应用程序上运行自我修复。如果您要检查 eventvwr,它会说它已完成重新配置每个产品。

在这种情况下,我使用以下方法(Yan Sklyarenko 方法的混合):

$Reg = @( "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*", "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" )
$InstalledApps = Get-ItemProperty $Reg -EA 0
$WantedApp = $InstalledApps | Where { $_.DisplayName -like "*<part of product>*" }

现在如果你要输入:

$WantedApp.PSChildName

您将获得以下信息:

PS D:\SCCM> $WantedApp.PSChildName
{047904BA-C065-40D5-969A-C7D91CA93D62}

如果您的组织在安装应用程序时使用大量 MST,您可能希望避免运行自我修复,因为它们会恢复一些关键设置。

  • 注意 - 这将找到您的产品代码,然后可以按照 Yan 所说的那样找到升级。不过,我通常只使用“InstEd It!”。或“Orca”,然后转到 MSI 的属性表,它将它们列在顶部。

【讨论】:

  • 访问 Win32_Product 时会运行 包完整性检查。除非在任何 MSI 软件包中找到损坏的组件密钥路径,否则不会触发自我修复。但是,这种完整性检查确实使数据的检索变得非常缓慢。
【解决方案4】:

如果您有 msi 安装程序,请使用 Orca(Microsoft 的工具)、表格属性(行 UpgradeCode、ProductCode、产品版本等)或表格升级列升级代码打开它。

尝试通过注册表查找安装程序:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall 找到所需的子项并观察值 InstallSource。也许一路上你就能找到 MSI 文件。

【讨论】:

    【解决方案5】:

    Powershell 可以相当轻松地处理这样的任务:

    $productCode = (gwmi win32_product | `
                    ? { $_.Name -Like "<PRODUCT NAME HERE>*" } | `
                    % { $_.IdentifyingNumber } | `
                    Select-Object -First 1)
    

    然后您也可以使用它来获取卸载信息:

    $wow = ""
    $is32BitInstaller = $True # or $False
    
    if($is32BitInstaller -and [System.Environment]::Is64BitOperatingSystem) 
    {
        $wow = "\Wow6432Node" 
    }
    
    $regPath = "HKEY_LOCAL_MACHINE\SOFTWARE$wow\Microsoft\Windows\CurrentVersion\Uninstall"
    
    dir "HKLM:\SOFTWARE$wow\Microsoft\Windows\CurrentVersion\Uninstall" | `
    ? { $_.Name -Like "$regPath\$productCode"  }
    

    【讨论】:

      【解决方案6】:

      您可以使用MsiEnumProductsExMsiGetProductInfoEx 方法枚举系统上所有已安装的应用程序并将数据与您的应用程序匹配

      【讨论】:

        【解决方案7】:

        在使用 PowerShell 5 的 Windows 10 预览版中,我可以看到您可以这样做:

        $info = Get-Package -Name YourInstalledProduct
        $info.Metadata["ProductCode"]
        

        不熟悉甚至不确定是否所有产品都有UpgradeCode,但是根据这篇文章你需要从这个注册表路径中搜索UpgradeCode:

        HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UpgradeCodes
        

        不幸的是,注册表项的值是 ProductCode,而注册表项的值是 UpgradeCode。

        【讨论】:

        • this post 不是有效的网址
        【解决方案8】:

        如果有人想获得安装的应用程序包代码,只需在命令提示符下使用您的应用程序名称执行以下命令。您将获得产品代码和包装代码。

        wmic product where "Name like '%YOUR_APPLICATION_NAME%'" get IdentifyingNumber, PackageCode

        【讨论】:

          【解决方案9】:

          另一种过于复杂的解决方法,其好处是不必像以前的解决方法那样重新安装应用程序。这要求您可以访问 msi(或嵌入了 msi 的 setup.exe)。

          如果您有 Visual Studio 2012(或可能的其他版本)并安装了免费的“InstallShield LE”,那么您可以使用 InstallShield 创建一个新的安装项目。

          “组织设置”步骤中的一个配置选项称为“升级路径”。打开升级路径的属性,在左窗格中右键单击“升级路径”并选择“新升级路径”...现在浏览到 msi(或包含 msi 的 setup.exe)并单击“打开”。升级代码将在您现在应该看到的右窗格的设置页面中为您填充。

          【讨论】:

            【解决方案10】:

            在看到上面的Yan Sklyarenkoworkaround(当前)之前,没有找到从已安装的应用程序中找出升级代码的任何方法。但是,如果您/其他人能找到一种方法(至少)从 MSI 中找出 UpgradeCode 和 ProductCode,请继续阅读。

            http://www.dwarfsoft.com/blog/2010/06/22/msi-package-code-fun/,修改为允许(使用wscript.exe 启动时)每个MSI 有一个信息弹出框(由于wscript.echo 限制,截断为1023 个字符);能够从 GUI 和 CLI 输入 MSI;一些基本的人工输入验证;删除了调试代码('Set oDatabase)和 1 个错误修复(DB.OpenView)。

            'Created by:   Chris Bennett
            'Created Date: 22/06/2010
            'Description:
            '   Opens up MSI file(s) Passed as Arguments & returns ProductName, ProductCode,
            '   The HKCR key created from ProductCode (a Packed GUID of ProductCode), the 
            '   PackageCode and the UpgradeCode of the MSI. Much quicker than getting these
            '   out of the MSI's the Manual Way.
            

            参考资料:
            http://msdn.microsoft.com/en-us/library/aa369794%28VS.85%29.aspx http://www.eggheadcafe.com/forumarchives/platformsdkmsi/Jan2006/post25948124.asp

            if wscript.arguments.count = 0 then
              MSIs = inputbox("Enter in * delimited list of MSI's to query (Max 254 characters)", "MSI Product Details")
              MSIs = split(MSIs,"*")
            else
              set MSIs = wscript.arguments
            end if
            
            set objFS = createobject("scripting.filesystemobject")
            For Each MSIPath in MSIs
              if objFS.fileexists(MSIPath) then
                Set MSIDetails = EvaluateMSI(MSIPath)
                MSIDetails = MSIPath & ": " & vbcrlf & vbcrlf & "Product Name: " &_
                MSIDetails("ProductName") & vbcrlf & "Product Code: " &_
                MSIDetails("ProductCode") & vbcrlf & "Product Key : " &_
                "HKCR\Installer\Products\" & PackGUID(MSIDetails("ProductCode")) &_
                vbcrlf & "Package Code: " & MSIDetails("PackageCode") & vbcrlf &_
                "Upgrade Code: " & MSIDetails("UpgradeCode") & vbcrlf
                WScript.Echo MSIDetails
              else
                wscript.echo "Inaccessible; Non-existant; or Error in Path for:" & vbcrlf & MSIPath & vbcrlf & "... skipping"
              end if
            Next
            
            Function EvaluateMSI(MSIPath)
              On Error Resume Next
              ' create installer object
              Set oInstaller = CreateObject("WindowsInstaller.Installer")
              ' open msi in read-only mode
              Set oDatabase = oInstaller.OpenDatabase(MSIPath, 0)
              Set objDictionary = CreateObject("Scripting.Dictionary")
              ' Get Package Code from Summary Information Stream   
              Set streamobj = oDatabase.SummaryInformation(0) '0 = read only
              objDictionary("PackageCode") = streamobj.Property(9)
              ' Get Product Name from MSI Database
              Set View = oDatabase.OpenView("Select `Value` From Property WHERE `Property`='ProductName'")
              View.Execute
              Set ProductName = View.Fetch
              objDictionary("ProductName") = ProductName.StringData(1)
            
              ' Get Product Code from MSI Database
              Set View = oDatabase.OpenView("Select `Value` From Property WHERE `Property`='ProductCode'")
              View.Execute
              Set ProductCode = View.Fetch
              objDictionary("ProductCode") = ProductCode.StringData(1)
            
              ' Get Upgrade Code from MSI Database
              Set View = oDatabase.OpenView("Select `Value` From Property WHERE `Property`='UpgradeCode'")
              View.Execute
              Set UpgradeCode = View.Fetch
              objDictionary("UpgradeCode") = UpgradeCode.StringData(1)
            
              Set EvaluateMSI = objDictionary
              On Error Goto 0
            End Function
            
            Function PackGUID(guid)  
              PackGUID = ""  
              '*  
              Dim temp  
              temp = Mid(guid,2,Len(guid)-2)  
              Dim part  
              part = Split(temp,"-")  
              Dim pack  
              pack = ""  
              Dim i, j  
              For i = LBound(part) To UBound(part)
                Select Case i
                  Case LBound(part), LBound(part)+1, LBound(part)+2
                    For j = Len(part(i)) To 1 Step -1  
                      pack = pack & Mid(part(i),j,1)  
                    Next  
                  Case Else
                    For j = 1 To Len(part(i)) Step 2  
                      pack = pack & Mid(part(i),j+1,1) & Mid(part(i),j,1)  
                  Next  
                End Select
              Next  
              '*  
              PackGUID = pack  
            End Function
            

            如果需要在弹出窗口中复制和粘贴任何 GUID,我倾向于使用后续输入框最简单,例如 inputbox "","",MSIDetails

            【讨论】:

              【解决方案11】:

              如果您没有 msi 并且您需要升级代码而不是产品代码,那么答案就在这里:How can I find the upgrade code for an installed application in C#?

              【讨论】:

                猜你喜欢
                • 2011-02-15
                • 2011-06-18
                • 2014-11-20
                • 2018-03-15
                • 1970-01-01
                • 2016-04-27
                • 1970-01-01
                • 2011-11-17
                • 2023-03-03
                相关资源
                最近更新 更多