cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
tigergrace
Level 6

Help for chained .msi and prerequisites

Hello,

I encountered a problem when create a package.

I have product A and product B, both of them need to use product c. how can I create the package.

solution 1: chained .msi
Both of product A and B use chained .msi with product c. the problem is that I install both product A and B in my PC, when product A is uninstalled, the chained.msi product c is also uninstalled, so the product C will does not work.

solution 2: prerequsistes
the problem is the product c will not be uninstalled for ever unless you uninstall manual. I want to the product c will be uninstalled it when A and B are uninstalleld.

so how can I do it, does someone can help me?

thanks
grace,
Labels (1)
0 Kudos
(17) Replies
MichaelU
Level 12 Flexeran
Level 12 Flexeran

There's no great built-in solution here, but if you know that you just have products A and B that will chain install/uninstall C, you can add Detect-Only Major Upgrade items to each of A and B to detect the other. Then modify the uninstall condition on the chained package to require the other product isn't found. (Perhaps something like NOT ACTIONPROPB and REMOVE="ALL".) Unfortunately this doesn't scale very well if you have to later detect further products that might also chain install/uninstall C.

Another approach you could take is to create a component (empty) that acts as a reference counter. If this exact component is attached to all features of products that chain install C, its action state should tell you whether it's time to remove C. Just check for the action state to become removed instead of absent. Unfortunately it's not clear from the Conditional Statement Syntax help article what value this would be - give it a test with a few packages. In this scenario your remove condition may look something like $package-c-component=1 (just be sure to double-check the 1 there), and it should scale to further packages so long as you remember to include this exact component.
0 Kudos
tigergrace
Level 6

MichaelU,

I am very thanks for your reply.

I'd like to further understand the second approach you mentioned. Could please help to understand what you said?

Just an example to create a empty component named SharedComponent, it will be included in product A and Product B. when I install both of them, how can I set the removal condition in chained .msi. what does mean of $package-c-component=1.

Thanks a lot,
grace
0 Kudos
MichaelU
Level 12 Flexeran
Level 12 Flexeran

Calling it SharedComponent is fine, but you must ensure they also have the same Component Code or they will not be tracked correctly. Regarding the $component syntax, see Conditional Statement Syntax under Feature and Component State Values. In the case you describe, it would become $SharedComponent instead of $package-c-component.
0 Kudos
tigergrace
Level 6

Hello,MichaelU

I appreciate your help very much.

I tried to use the method you showed me. There are still problem here:

I used the removal condition $SharedComponent=1, and after I uninstalled product A or both of Products A and B, the product C(chained .msi) can not be uninstalled. I read the Conditional Statement Syntax and found the INSTALLSTATE_ADVERTISED=1 does not available for components, just feature, so I tried to new feature, but it still does not work. Is right for the removal condition with $SharedComponent=1? Could you help with me? I am confused.

Thanks,
grace.
0 Kudos
MichaelU
Level 12 Flexeran
Level 12 Flexeran

I should preface this with a note that I haven't explicitly tried the procedure I recommended. But let's see if we can't get it working anyway. 😉

If you take a verbose log of your uninstallations, you should be able to find lines shortly after InstallValidate that look something like this one, only it'll take it from Local to, say, Absent or Removed.[CODE]MSI (s) (0C:4C) [12:23:06:828]: Component: ComponentNameHere; Installed: Absent; Request: Local; Action: Local[/CODE]Then if we cross-reference with msi.h, you can look up the numeric meaning of the various states InstallValidate will describe.
typedef enum tagINSTALLSTATE
{
INSTALLSTATE_NOTUSED = -7, // component disabled
INSTALLSTATE_BADCONFIG = -6, // configuration data corrupt
INSTALLSTATE_INCOMPLETE = -5, // installation suspended or in progress
INSTALLSTATE_SOURCEABSENT = -4, // run from source, source is unavailable
INSTALLSTATE_MOREDATA = -3, // return buffer overflow
INSTALLSTATE_INVALIDARG = -2, // invalid function argument
INSTALLSTATE_UNKNOWN = -1, // unrecognized product or feature
INSTALLSTATE_BROKEN = 0, // broken
INSTALLSTATE_ADVERTISED = 1, // advertised feature
INSTALLSTATE_REMOVED = 1, // component being removed (action state, not settable)
INSTALLSTATE_ABSENT = 2, // uninstalled (or action state absent but clients remain)
INSTALLSTATE_LOCAL = 3, // installed on local drive
INSTALLSTATE_SOURCE = 4, // run from source, CD or net
INSTALLSTATE_DEFAULT = 5, // use default, local or source
} INSTALLSTATE;
The two states I've highlighted (INSTALLSTATE_REMOVED and INSTALLSTATE_ABSENT) are the ones I expect to see. As action states, these should differentiate between the refcount of one product being removed (its claim on the component being released), and the final product being removed and thus the component removed with it.

These numbers are the ones you will want to compare with in your condition. What does your verbose log say, both about the component, and about the chained condition's evaluation?
0 Kudos
tigergrace
Level 6

Hello MichaelU,

Maybe I did a misunderstanding.
Below is my setting for chined.msi, do I need to set the removal conditional for the Shared Component, I only created a shared component in Product A and B with the same component code. I just want to make sure whether I did the wrong setting.


I will try it again with your feedback. Thanks.

grace,
0 Kudos
MichaelU
Level 12 Flexeran
Level 12 Flexeran

Those settings look reasonable to me. What does the verbose log say about the component and the chaining (look for actions InstallValidate and ISChainPackagePrepare)?
0 Kudos
tigergrace
Level 6

MichaelU,

Thanks for your patience.

At begining, I did not how to find verbose log, after research, I used /l*v %WINDIR%\Installation.log under setup.exe tab in release view to generate the log file, please let me know if it is inccorect.

For reason, I am afraid of the inccorect information, so I attached the log file, could you please check the information you want to?


Regards,
grace,
0 Kudos
MichaelU
Level 12 Flexeran
Level 12 Flexeran

Well, that's a start, but it looks like you logged the installation. It sounded like you were having problems with the uninstallation instead, or do I misunderstand?
0 Kudos
tigergrace
Level 6

MichaelU,

You are right, the problem is for uninstallation. I found when I uninstall my product from control pannel, the log file can not be generated.

Below is the uninstall log file. I generate with the method like this, first I install my package, after installation, I launch the setup package again, it will ask me to repaire or remove the package, I select remove and then genrete the log after removing.


Could you tell me how to generate the uninstall log if this log file is still not you want to.

Thanks.
grace
0 Kudos
MichaelU
Level 12 Flexeran
Level 12 Flexeran

This looks like the right file. The relevant lines are:[CODE]MSI (s) (A4:F0) [01:10:24:764]: Doing action: InstallValidate
Action 1:10:24: InstallValidate. Validating install
Action start 1:10:24: InstallValidate.
MSI (s) (A4:F0) [01:10:24:764]: Feature: TEST_Files; Installed: Local; Request: Absent; Action: Absent
...
MSI (s) (A4:F0) [01:10:24:764]: Component: SharedComponent; Installed: Local; Request: Absent; Action: Absent
[/CODE]and[CODE]MSI (s) (A4:F0) [01:10:24:764]: Doing action: ISChainPackagePrepare
Action 1:10:24: ISChainPackagePrepare.
Action start 1:10:24: ISChainPackagePrepare.
MSI (s) (A4:88) [01:10:24:811]: Invoking remote custom action. DLL: C:\WINDOWS\Installer\MSIF88.tmp, Entrypoint: ISChainPackages
MSI (s) (A4:08) [01:10:24:811]: Generating random cookie.
MSI (s) (A4:08) [01:10:24:873]: Created Custom Action Server with PID 340 (0x154).
MSI (s) (A4:6C) [01:10:24:889]: Running as a service.
MSI (s) (A4:6C) [01:10:24:905]: Hello, I'm your 32bit Impersonated custom action server.
Action ended 1:10:24: ISChainPackagePrepare. Return value 1.
[/CODE]but something's odd. ISChainPackagePrepare should look more like it does in the first log, where it mentions that it has scheduled a package for installation (although this time it should be removal, or ignoring it because the conditions say not to bother). Are you testing on a reverted virtual image each time, or could the machine be in a messy state?
0 Kudos
tigergrace
Level 6

MichaelU,

Thanks for your reply. I have a vacation for 5 days. I just back to home. I will try to test it in a virtual PC tomorrow.

grace,
0 Kudos
tigergrace
Level 6

MichaelU,

I try to this on serveral PC, and It still does not uninstall the chained.msi package. I think maybe there is a bug for uninstall. I do not know whether you can try to create a single package chained in the parent package and process install and unistall.

Do you have someother suggestion for this? or something I can try it, if not I will give up this way.

Thank for your help.

grace,
0 Kudos
MichaelU
Level 12 Flexeran
Level 12 Flexeran

You might want to try my alternate suggestion - the less clean one that requires you to know everything ahead of time. Or concoct your own variant of that.

Or you could debug what the action states truly are, in case I'm misreading the header files, and guessing wrong. Since it's a throwaway action, you could even write it in VB Script using Session.ComponentRequestState. Or just try the value 2 instead of 1. I haven't had time to create and run my own tests on this one. 😮
0 Kudos
tigergrace
Level 6

MichaelU,

I appreciate your help veru much!

I just used the condtion with $sharedComponent=2, it works when I uninstall ProductA, the chained.msi had not been uninstalled. After I uninstall ProductB, the chained.msi is uninstalled. I am afraid of makimg a mistake, so I create a ProductD which also include the chained.msi ProductC, everything works fine for me.

The question is that INSTALLSTATE_ABSENT in help file is for the component not present, could you help to understand why $sharedComponent=2 works fine. Because the shared component is still in my PC when I uninstall the last parent product.
State---------------------Value -Meaning
INSTALLSTATE_ADVERTISED-- 1 ----Advertised feature. This state is not available for components.
INSTALLSTATE_ABSENT-------2 ----Feature or component is not present.

grace,
0 Kudos
MichaelU
Level 12 Flexeran
Level 12 Flexeran

The value of 1 is, for components, INSTALLSTATE_REMOVED. I'm unclear why the meanings of absent and removed are the way they are; they confuse me this way! One of them means that one of the multiple clients (that is, an installation that installed or refcounted this component) has been uninstalled; the other means the last client has been uninstalled. Regardless, I'm glad to hear it's working!
0 Kudos
tigergrace
Level 6

MichaelU,

I hope you can record this issue and follow up with it. I really do not want to see the other person do this like me. they can not understand what means of $sharedComponent=2, Maybe your team can update this in future although it's a throwaway action. hopefully, it can help someone else.

Thanks for your help.
grace
0 Kudos