How to find the UpgradeCode and ProductCode of an installed application in Windows 7

后端 未结 11 1385
囚心锁ツ
囚心锁ツ 2020-11-27 04:36

I have an application installed on my machine. I also have its source code but somehow the ProductCode and UpgradeCode of this application were changed.

Now I want t

11条回答
  •  一生所求
    2020-11-27 04:50

    Hadn't found any way of finding out the UpgradeCode from an installed application, before seeing Yan Sklyarenko's workaround (currently) above. But if you/anyone else would find a way of finding out (at least) both UpgradeCode and ProductCode from a MSI, read on.

    From http://www.dwarfsoft.com/blog/2010/06/22/msi-package-code-fun/, modified to allow (when launched with wscript.exe) one popup box of info per MSI (Trunicated at 1023 chars, due to wscript.echo limitation); able to input MSI(s) from the GUI as well as the CLI; some basic human input validation; removed debug code (' Set oDatabase) and 1 bug fix (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.
    

    References:
    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
    

    If one needs to copy&paste any of the GUID's in the popup, I tend to find it easiest to use a subsequent inputbox, like inputbox "","",MSIDetails

提交回复
热议问题