在看到上面的Yan Sklyarenko 的workaround(当前)之前,没有找到从已安装的应用程序中找出升级代码的任何方法。但是,如果您/其他人能找到一种方法(至少)从 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