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
- :
- Find out which features are installed (Basic msi) from outside a setup?
Subscribe
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Subscribe
- Mute
- Printer Friendly Page
‎Oct 14, 2014
05:02 AM
Find out which features are installed (Basic msi) from outside a setup?
Hi!
I'm having a Basic msi setup that is often executed by a separate software in order to allow our users to install different products sequentially. We call that software out install wizard as it makes the installations for our users easier. Now we have come to a point that it is necessary that our install wizard needs to know which features of an existing installation are installed/selected.
I've searched my registry with Product and UpdateCodes for my installed setup but never saw any hint on which featrures are actually installed. When doing a web search I only found threads on how to detect the installed state of a feature from wihtin a setup. Could anyone please point me in the right direction?
I'm quite sure there is a way to find out which features were installed for a setup, but where is that information kept and how can I access it from a regular application?
Regards
Ralf
I'm having a Basic msi setup that is often executed by a separate software in order to allow our users to install different products sequentially. We call that software out install wizard as it makes the installations for our users easier. Now we have come to a point that it is necessary that our install wizard needs to know which features of an existing installation are installed/selected.
I've searched my registry with Product and UpdateCodes for my installed setup but never saw any hint on which featrures are actually installed. When doing a web search I only found threads on how to detect the installed state of a feature from wihtin a setup. Could anyone please point me in the right direction?
I'm quite sure there is a way to find out which features were installed for a setup, but where is that information kept and how can I access it from a regular application?
Regards
Ralf
(5) Replies
‎Oct 14, 2014
08:14 AM
There are several Windows Installer APIs designed for querying the state of a machine; in particular you might be able to use MsiQueryFeatureState. However a lot of the functions are not supported from within custom actions, so there are limitations in what you can safely perform during an installation. Those limitations shouldn't apply from your application.
‎Oct 14, 2014
08:21 AM
Hi MichaelU,
I think you misunderstood me: I want to check the installed features of a installed MSI setup from outside the setup/installer (in my case it would be a .Net application that would need to know what features are installed)
Regards
Ralf
I think you misunderstood me: I want to check the installed features of a installed MSI setup from outside the setup/installer (in my case it would be a .Net application that would need to know what features are installed)
Regards
Ralf
‎Oct 15, 2014
09:20 AM
I did miss that on my first read through, but when I noticed it I added the last bit about the limitations not applying to your application.
It is a little more work to call these things from .NET unless you choose to use the COM layer, but I'm unfamiliar with where the COM layer exposes the same information that's available with MsiQueryFeatureState. You can use resources like pinvoke.net to help invoke C++ APIs correctly. MsiQueryFeatureState will still be the core function you need to call.
It is a little more work to call these things from .NET unless you choose to use the COM layer, but I'm unfamiliar with where the COM layer exposes the same information that's available with MsiQueryFeatureState. You can use resources like pinvoke.net to help invoke C++ APIs correctly. MsiQueryFeatureState will still be the core function you need to call.
‎Oct 15, 2014
09:39 AM
I recommend the book "VB/VBA Developer's Guide to the Windows Installer" from Mike Gunderloy.
May be it is sufficient for you to download the source code from ftp://ftp.sybex.com/2745/
Chapter 8 is with a sample about MsiQueryFeatureState.
regards
Markus
May be it is sufficient for you to download the source code from ftp://ftp.sybex.com/2745/
Chapter 8 is with a sample about MsiQueryFeatureState.
regards
Markus
‎Oct 17, 2014
04:38 AM
Hi MichaelU,
you pointed me to the right direction! Thank you!
After a little research I ended up on the website pinvoke.com, which describes how .Net applications can access native dlls such as the msi.dll which holds the said MSIQueryFeatureState. While the access to native dlls from .Net itself is not a big deal I'm happy with the fact that this site provides a lot of example code. Equipped with the knowledge of this website I was quickly able to create a small C# test application that does exactly what I was looking for.
For the highly unrealistic case that someone else ever runs into the same or a similar problem I post the relevant code of the said test application here:
[CODE]
namespace MSITestApplication
{
public partial class MainWindow : Window
{
public enum INSTALLSTATE
{
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
}
[DllImport("msi.dll", CharSet = CharSet.Unicode)]
static extern Int32 MsiGetProductInfo(string product, string property, [Out] StringBuilder valueBuf, ref Int32 len);
[DllImport("msi.dll", CharSet = CharSet.Unicode)]
static extern INSTALLSTATE MsiQueryFeatureState(string product, string feature);
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
//Int32 len = 512;
//System.Text.StringBuilder builder = new System.Text.StringBuilder(len);
//MsiGetProductInfo("{6F113CFE-83BC-4311-AE7E-098B182C89C4}", "InstallSource", builder, ref len);
//MessageBox.Show(builder.ToString());
INSTALLSTATE res = MsiQueryFeatureState("{6F113CFE-83BC-4311-AE7E-098B182C89C4}", "CommonFiles");
MessageBox.Show(res.ToString());
}
}
}
[/CODE]
Cheers!
Ralf
you pointed me to the right direction! Thank you!
After a little research I ended up on the website pinvoke.com, which describes how .Net applications can access native dlls such as the msi.dll which holds the said MSIQueryFeatureState. While the access to native dlls from .Net itself is not a big deal I'm happy with the fact that this site provides a lot of example code. Equipped with the knowledge of this website I was quickly able to create a small C# test application that does exactly what I was looking for.
For the highly unrealistic case that someone else ever runs into the same or a similar problem I post the relevant code of the said test application here:
[CODE]
namespace MSITestApplication
{
public partial class MainWindow : Window
{
public enum INSTALLSTATE
{
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
}
[DllImport("msi.dll", CharSet = CharSet.Unicode)]
static extern Int32 MsiGetProductInfo(string product, string property, [Out] StringBuilder valueBuf, ref Int32 len);
[DllImport("msi.dll", CharSet = CharSet.Unicode)]
static extern INSTALLSTATE MsiQueryFeatureState(string product, string feature);
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
//Int32 len = 512;
//System.Text.StringBuilder builder = new System.Text.StringBuilder(len);
//MsiGetProductInfo("{6F113CFE-83BC-4311-AE7E-098B182C89C4}", "InstallSource", builder, ref len);
//MessageBox.Show(builder.ToString());
INSTALLSTATE res = MsiQueryFeatureState("{6F113CFE-83BC-4311-AE7E-098B182C89C4}", "CommonFiles");
MessageBox.Show(res.ToString());
}
}
}
[/CODE]
Cheers!
Ralf