This website uses cookies. By clicking Accept, you consent to the use of cookies. Click Here to learn more about how we use cookies.
Turn on suggestions
Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.
- Revenera Community
- :
- InstallShield
- :
- InstallShield Forum
- :
- UILevel property from within a custom action
Subscribe
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Subscribe
- Mute
- Printer Friendly Page
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Feb 19, 2013
06:11 PM
UILevel property from within a custom action
I've inherited a fairly complex installer.
There are a few SprintfBox calls there were protected by the following code. The code is a generic logging function that is access from dialog code and custom action code.
This does not seem to work when invoked from the custom action code.
After a little web searching, I tried to rewrite to something this:
This does not work either. In the latter case, UILevelName is the empty string.
What is the best practice for not throwing a pop-up during a silent (unattended) install from a custom action?
Thanks,
Wim
There are a few SprintfBox calls there were protected by the following code. The code is a generic logging function that is access from dialog code and custom action code.
if (MODE != SILENTMODE && msgbox) then
SprintfBox (msgtype, msgtitle, msg);
endif;
This does not seem to work when invoked from the custom action code.
After a little web searching, I tried to rewrite to something this:
nvSize = 256;
MsiGetProperty (hMSI, "UILevel", UILevelName, nvSize);
if (UILevelName != "2") then
SprintfBox (msgtype, msgtitle, msg);
endif;
This does not work either. In the latter case, UILevelName is the empty string.
What is the best practice for not throwing a pop-up during a silent (unattended) install from a custom action?
Thanks,
Wim
(7) Replies
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Feb 20, 2013
03:50 AM
First of all, reading the property "UILevel" instead of the MODE InstallScript variable is correct. The "MODE" system variable makes sense in an InstallScript project, not in a Basic MSI project.
So that's all good.
So am I right in thinking that you are working on a Basic MSI project?
If that's the case, your code looks correct.
But you might want to check the return value of MsiGetProperty. See http://msdn.microsoft.com/en-us/library/windows/desktop/aa370134%28v=vs.85%29.aspx for a list of possible values.
You might also want to check the "In-Script Execution" setting of your custom action. I am not sure whether UILevel is available in custom-action set for "Deferred Execution" or "Commit Execution".
See here: http://helpnet.flexerasoftware.com/installshield19helplib/helplibrary/AccessingProps-DeferredCAs.htm
Does that help?
So that's all good.
So am I right in thinking that you are working on a Basic MSI project?
If that's the case, your code looks correct.
But you might want to check the return value of MsiGetProperty. See http://msdn.microsoft.com/en-us/library/windows/desktop/aa370134%28v=vs.85%29.aspx for a list of possible values.
You might also want to check the "In-Script Execution" setting of your custom action. I am not sure whether UILevel is available in custom-action set for "Deferred Execution" or "Commit Execution".
See here: http://helpnet.flexerasoftware.com/installshield19helplib/helplibrary/AccessingProps-DeferredCAs.htm
Does that help?
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Feb 20, 2013
12:36 PM
Correct, I have Basic MSI project. So I will remove the inherited code (MODE check) and replace with a similar UILevel check.
In the logs, UILevel is set as such when running in silent mode:
MSI (s) (2C:EC) [15:37:32:995]: PROPERTY CHANGE: Adding UILevel property. Its value is '2'.
If I read what you are intending: near initialization, get the UILevel property and set a custom action property with the value -- and then retrieve that value in the logger function.
But please forgive my ignorance, I've just picked up IS in the last 6 weeks -- Are the custom action properties permanent? Meaning if I set them in one custom action I can retrieve it in another? The reason I ask is that I've seen in the custom actions The "Property Value" entry that sets custom action "variables" to property values (i.e.: /InstallDir=[INSTALLDIR]). The Logger is called from just about everywhere -- and it would be untenable (I think) to plumb /UILevel=[UILevel] on every single custom action...
And if I'm talking gibberish, please feel free to educate me!
Wim
In the logs, UILevel is set as such when running in silent mode:
MSI (s) (2C:EC) [15:37:32:995]: PROPERTY CHANGE: Adding UILevel property. Its value is '2'.
If I read what you are intending: near initialization, get the UILevel property and set a custom action property with the value -- and then retrieve that value in the logger function.
But please forgive my ignorance, I've just picked up IS in the last 6 weeks -- Are the custom action properties permanent? Meaning if I set them in one custom action I can retrieve it in another? The reason I ask is that I've seen in the custom actions The "Property Value" entry that sets custom action "variables" to property values (i.e.: /InstallDir=[INSTALLDIR]). The Logger is called from just about everywhere -- and it would be untenable (I think) to plumb /UILevel=[UILevel] on every single custom action...
And if I'm talking gibberish, please feel free to educate me!
Wim
Reureu wrote:
First of all, reading the property "UILevel" instead of the MODE InstallScript variable is correct. The "MODE" system variable makes sense in an InstallScript project, not in a Basic MSI project.
So that's all good.
So am I right in thinking that you are working on a Basic MSI project?
If that's the case, your code looks correct.
But you might want to check the return value of MsiGetProperty. See http://msdn.microsoft.com/en-us/library/windows/desktop/aa370134%28v=vs.85%29.aspx for a list of possible values.
You might also want to check the "In-Script Execution" setting of your custom action. I am not sure whether UILevel is available in custom-action set for "Deferred Execution" or "Commit Execution".
See here: http://helpnet.flexerasoftware.com/installshield19helplib/helplibrary/AccessingProps-DeferredCAs.htm
Does that help?
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Feb 21, 2013
12:36 AM
Well the link I gave you about CustomActionData says:
So you don't need to use a CustomActionData for every single Custom Action. You need to do it if:
I don't think the conditions above apply to all your custom actions, do you?
Bearing that in mind, you need to remember the following points:
Now it's my turn to ask questions... 😉
Deferred, commit, and rollback custom actions in Basic MSI and InstallScript MSI installations have access to only some of the built-in Windows Installer properties: CustomActionData, ProductCode, and UserSID. If you want a custom action to access any other properties during deferred, commit, or rollback execution, you can pass them as CustomActionData. You can do so by scheduling an immediate set-a-property type of custom action to set a property that matches the name of the custom action. The value of this property is then available in the CustomActionData property within the deferred, commit, or rollback custom action.
So you don't need to use a CustomActionData for every single Custom Action. You need to do it if:
- the custom action is scheduled for Deferred, Commit or Rollback Execution
- you need to access properties other than "CustomActionData", "ProductCode", and "UserSID" in your custom action
I don't think the conditions above apply to all your custom actions, do you?
Bearing that in mind, you need to remember the following points:
- Custom Actions scheduled for immediate execution don't need to use this CustomActionData property.
- You need to set a CustomActionData for EVERY custom action that fulfils the 2 conditions above (if I remember well).
Now it's my turn to ask questions... 😉
- Does that help?
- Did you try?
- Did that solve your problem?
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Feb 21, 2013
11:04 AM
The custom actions are defined as "deferred in system context".
I really only want UILevel to determine if a pop-up should be displayed; Again, the reason is that the logger function -- which is called from absolutely everywhere -- has a parameter that indicates whether a message box (actually an SprintfBox) should be thrown in addition to logging to the file. If running in Silent mode (Or unattended install) -- a pop-up throws a monkey wrench into things.
So according to your criteria, both apply. the custom actions are deferred AND I need something that is not ProductCode or UserSID -- and not normally in CustomActionData. Which means to me that I need to add it.
So my real question is that can I add it ONLY ONCE to the CustomActionData, like in an initialization function, and then retrieve it at will, OR do I need to add it on entry to every custom action?
Wim
I really only want UILevel to determine if a pop-up should be displayed; Again, the reason is that the logger function -- which is called from absolutely everywhere -- has a parameter that indicates whether a message box (actually an SprintfBox) should be thrown in addition to logging to the file. If running in Silent mode (Or unattended install) -- a pop-up throws a monkey wrench into things.
So according to your criteria, both apply. the custom actions are deferred AND I need something that is not ProductCode or UserSID -- and not normally in CustomActionData. Which means to me that I need to add it.
So my real question is that can I add it ONLY ONCE to the CustomActionData, like in an initialization function, and then retrieve it at will, OR do I need to add it on entry to every custom action?
Wim
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Feb 21, 2013
12:13 PM
Our custom actions are defined into two separate pieces. One that sets up custom action data, and then the custom action itself.
I found that simply plumbing /UILevel=UIlevel in the custom action data setup and then in the logger code do:
It correctly functions for both normal code flow and custom actions.
Regards,
Wim
I found that simply plumbing /UILevel=UIlevel in the custom action data setup and then in the logger code do:
nvSize = 256;
MsiGetProperty(hMSI, "UILevel", UILevelName, nvSize);
if (UILevelName == "") then
UILevelName = MsiGetCustomActionDataAttribute(hMSI, "/UILevel=");
endif;
if ((UILevelName != "2") && (msgbox)) then //silent install check
SprintfBox (msgtype, msgtitle, msg);
endif;
It correctly functions for both normal code flow and custom actions.
Regards,
Wim
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Feb 22, 2013
12:34 AM
So your project already had this CustomActionData set? Good!
Just as a suggestion: you might also want to treat UILevel=3 differently.
Just as a suggestion: you might also want to treat UILevel=3 differently.
- Mark as New
- Subscribe
- Mute
- Permalink
- Report Inappropriate Content
‎Jan 21, 2020
06:26 AM
Awesome.. this solution works for me. Thank you
