Jump to content


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.
Photo

Current installation context


11 replies to this topic

igodunov

igodunov
  • Full Members
  • 61 posts

Posted 06 January 2006 - 10:55

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?


mandy

mandy
  • Members
  • 121 posts

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!


mandy

mandy
  • Members
  • 121 posts

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)?


igodunov

igodunov
  • Full Members
  • 61 posts

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?


Zweitze

Zweitze
  • Full Members
  • 522 posts

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.

igodunov

igodunov
  • Full Members
  • 61 posts

Posted 06 January 2006 - 18:23

Thank you very much! It is really good idea!

mandy

mandy
  • Members
  • 121 posts

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


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


Zweitze

Zweitze
  • Full Members
  • 522 posts

Posted 07 January 2006 - 22:41

After MsiEnumRelatedProducts() you can call MsiQueryProductState() to filter products installed for other users.

mandy

mandy
  • Members
  • 121 posts

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.


Zweitze

Zweitze
  • Full Members
  • 522 posts

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.


mandy

mandy
  • Members
  • 121 posts

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. wink.gif


igodunov

igodunov
  • Full Members
  • 61 posts

Posted 10 January 2006 - 10:47

Thanks for interesting examples & discussion.