1 I have to determine current installation context (MSIINSTALLCONTEXT as result). How (and when - in InstallExecuteSequence) can I do it ?
2 How to acces list of products that skipped by FindRelatedProduct due to different per-user/per-machine install mode? Is it possible?
This is a ready-only archive of the InstallSite Forum. You cannot post any new content here. / Dies ist ein Archiv des InstallSite Forums. Hier können keine neuen Beiträge veröffentlicht werden.
Current installation context
Started by
igodunov
, Jan 06 2006 10:55
11 replies to this topic
Posted 06 January 2006 - 15:09
Not sure if this script I wrote for my own purposes answers any questions?
Set oInst = CreateObject("WindowsInstaller.Installer")
Const sPRODCODE = "{350C97B0-3D7C-4EE8-BAA9-00BCB3D54227}"
Const msiInstallStateAbsent = 2
Const msiInstallStateDefault = 5
Const msiInstallStateAdvertised = 1
Const msiInstallStateInvalidArg = -2
Const msiInstallStateBadConfig = -6
iState = oInst.ProductState(sPRODCODE)
Select Case iState
Case msiInstallStateAbsent
Msgbox "The product is installed 'per-user' for a different user."
Case msiInstallStateDefault
iAssignType = oInst.ProductInfo(sPRODCODE, "AssignmentType")
If iAssignType = 1 Then
Msgbox "The product is installed 'per-machine' (for all users)."
Else
Msgbox "The product is installed 'per-user' for the current user."
End If
Case msiInstallStateAdvertised
Msgbox "The product is advertised but not installed."
Case msiInstallStateInvalidArg
Msgbox "An invalid parameter was passed to the function."
Case msiInstallStateBadConfig
Msgbox "The configuration data is corrupt."
Case Else
Msgbox "The product is absent or in an unrecognised state!!"
End Select
Set oInst = Nothing
I wrote it so I could easily check whether a product was installed fot the current user and whether it was installed per-user or per-machine.
Sorry it's not a custom action!
Set oInst = CreateObject("WindowsInstaller.Installer")
Const sPRODCODE = "{350C97B0-3D7C-4EE8-BAA9-00BCB3D54227}"
Const msiInstallStateAbsent = 2
Const msiInstallStateDefault = 5
Const msiInstallStateAdvertised = 1
Const msiInstallStateInvalidArg = -2
Const msiInstallStateBadConfig = -6
iState = oInst.ProductState(sPRODCODE)
Select Case iState
Case msiInstallStateAbsent
Msgbox "The product is installed 'per-user' for a different user."
Case msiInstallStateDefault
iAssignType = oInst.ProductInfo(sPRODCODE, "AssignmentType")
If iAssignType = 1 Then
Msgbox "The product is installed 'per-machine' (for all users)."
Else
Msgbox "The product is installed 'per-user' for the current user."
End If
Case msiInstallStateAdvertised
Msgbox "The product is advertised but not installed."
Case msiInstallStateInvalidArg
Msgbox "An invalid parameter was passed to the function."
Case msiInstallStateBadConfig
Msgbox "The configuration data is corrupt."
Case Else
Msgbox "The product is absent or in an unrecognised state!!"
End Select
Set oInst = Nothing
I wrote it so I could easily check whether a product was installed fot the current user and whether it was installed per-user or per-machine.
Sorry it's not a custom action!
Posted 06 January 2006 - 15:30
Btw, anything installed for the current user ("msiInstallStateDefault") will be detected by the "FindRelatedProducts" action.
A return of "msiInstallStateAbsent" would indicate that it was installed per-user for another user.
But, your problem is finding this information using the "UpgradeCode" -not the "ProductCode" (as in my script)?
A return of "msiInstallStateAbsent" would indicate that it was installed per-user for another user.
But, your problem is finding this information using the "UpgradeCode" -not the "ProductCode" (as in my script)?
Posted 06 January 2006 - 16:39
UpgradeCode is unavailable for MsiGetProductInfo - and I can't decide, how to determine wich products in installer database are mentioned in my Upgrade Table. But, "FindRelatedProducts" action should use legal way to resolve upgrades, isn't it?
Posted 06 January 2006 - 17:08
Assuming you can retrieve the UpgradeCode, look at MsiEnumRelatedProducts(). Note that this function may return multiple products. You can use MsiEnumRelatedProducts() in a custom action.
Posted 07 January 2006 - 21:24
Although I'm willing to be proved wrong, I'm not convinced that "MsiEnumRelatedProducts" returns products installed "per-user" for other users.
The following vbscript CA should detect products having the same upgrade code as the current MSI which are installed/advertised "per-user" (current or other user).
On Error Resume Next
Const msiOpenDatabaseModeDirect = 2
Set oInst = Me.Installer
Set oProducts = oInst.ProductsEx("","s-1-1-0",3)
For Each oProduct in oProducts
sLocalPkg = oProduct.InstallProperty("LocalPackage")
Set oDB = oInst.OpenDataBase(sLocalPkg, msiOpenDatabaseModeDirect)
sQuery = "SELECT `Value` FROM `Property` WHERE `Property` = 'UpgradeCode'"
Set oView = oDB.OpenView(sQuery)
oView.Execute
Set oRecord = oView.Fetch
sUpgradeCode = oRecord.StringData(1)
Set oRecord = Nothing
Set oView = Nothing
Set oDB = Nothing
If sUpgradeCode = Property("UpgradeCode") Then Msgbox "Product '" & oProduct.ProductCode &_
"' is installed for user '" & oProduct.UserSid & "'"
Next
Set oInst = Nothing
The following vbscript CA should detect products having the same upgrade code as the current MSI which are installed/advertised "per-user" (current or other user).
On Error Resume Next
Const msiOpenDatabaseModeDirect = 2
Set oInst = Me.Installer
Set oProducts = oInst.ProductsEx("","s-1-1-0",3)
For Each oProduct in oProducts
sLocalPkg = oProduct.InstallProperty("LocalPackage")
Set oDB = oInst.OpenDataBase(sLocalPkg, msiOpenDatabaseModeDirect)
sQuery = "SELECT `Value` FROM `Property` WHERE `Property` = 'UpgradeCode'"
Set oView = oDB.OpenView(sQuery)
oView.Execute
Set oRecord = oView.Fetch
sUpgradeCode = oRecord.StringData(1)
Set oRecord = Nothing
Set oView = Nothing
Set oDB = Nothing
If sUpgradeCode = Property("UpgradeCode") Then Msgbox "Product '" & oProduct.ProductCode &_
"' is installed for user '" & oProduct.UserSid & "'"
Next
Set oInst = Nothing
QUOTE |
UpgradeCode is unavailable for MsiGetProductInfo - and I can't decide, how to determine wich products in installer database are mentioned in my Upgrade Table... |
Notice that I have circumvented this problem by reading the upgrade code from the property table of the locally cached MSI database.
Here's a stand-alone (non-CA) version of the same script:
On Error Resume Next
Set oInst = CreateObject("WindowsInstaller.Installer")
Const msiOpenDatabaseModeDirect = 2
sInput = InputBox("Please enter a valid UpgradeCode:","UpgradeCode","{E1D7CB1A-C0D9-483F-BD2E-D0A4CCDE0624}")
Set oProducts = oInst.ProductsEx("","s-1-1-0",3)
For Each oProduct in oProducts
sLocalPkg = oProduct.InstallProperty("LocalPackage")
Set oDB = oInst.OpenDataBase(sLocalPkg, msiOpenDatabaseModeDirect)
sQuery = "SELECT `Value` FROM `Property` WHERE `Property` = 'UpgradeCode'"
Set oView = oDB.OpenView(sQuery)
oView.Execute
Set oRecord = oView.Fetch
sUpgradeCode = oRecord.StringData(1)
Set oRecord = Nothing
Set oView = Nothing
Set oDB = Nothing
If UCase(sUpgradeCode) = UCase(sInput) Then Msgbox "Product '" & oProduct.ProductCode &_
"' is installed for user '" & oProduct.UserSid & "'"
Next
Set oInst = Nothing
Posted 07 January 2006 - 22:41
After MsiEnumRelatedProducts() you can call MsiQueryProductState() to filter products installed for other users.
Posted 08 January 2006 - 16:16
You may have missed this part of my last post...
QUOTE |
...I'm not convinced that "MsiEnumRelatedProducts" returns products installed "per-user" for other users. |
This conviction is based on the following extract from the SDK:
QUOTE |
The read-only RelatedProducts property returns a StringList object enumerating the set of all products installed or advertised for the current user and machine with a specified UpgradeCode property in their Property table. |
Admittedly, this refers to the "RelatedProducts" property of the "Installer" object, but I doubt that "MsiEnumRelatedProducts" will be any different in that respect.
Posted 09 January 2006 - 10:59
Mandy,
The idea is to check every related product with MsiQueryProductState(); it returns INSTALLSTATE_ABSENT when a product is installed for a different user; and INSTALLSTATE_DEFAULT when it is installed for all users or the current user.
The idea is to check every related product with MsiQueryProductState(); it returns INSTALLSTATE_ABSENT when a product is installed for a different user; and INSTALLSTATE_DEFAULT when it is installed for all users or the current user.
Posted 09 January 2006 - 18:29
QUOTE (Zweitze @ 2006-01-07 21:41) |
After MsiEnumRelatedProducts() you can call MsiQueryProductState() to filter products installed for other users. |
If "MsiEnumRelatedProducts" doesn't return those "related" products that are installed for other users, you'll have no products to filter.