views:

405

answers:

2

The following code produces an error hr=0x80020005 (wrong type).

#import <msi.dll>
using namespace WindowsInstaller;
main()
{
   ::CoInitialize(NULL);
   InstallerPtr pInstaller("WindowsInstaller.Installer");
   DatabasePtr pDB = pInstaller->OpenDatabase(
          "c:\\foo\\bar.msi", 
          msiOpenDatabaseModeTransact);
}

I think the reason is that behind the scene, there is MsiOpenDatabase(), which take a LPCTSTR as second argument. This second argument can be MSIDBOPEN_TRANSACT whose definition is

#define MSIDBOPEN_TRANSACT     (LPCTSTR)1

I do not know if it is possible to give a variant with the good inner type as second argument. The _variant_t constructor does many checks, so I can't disguise an int into a char* so easily.

Has anyone tried to use this method in C++?

Edit:

My version of msi.dll is 3.1.4000.2805, my system is XP SP 2, and the code is supposed to run on any machine with XP or Vista.

urls to MSDN articles are welcome.

On the same machine, the call to the low-level equivalent:

MsiOpenDatabase("c:\\foo\\bar.msi", MSIDBOPEN_TRANSACT);

works perfectly.

+1  A: 

MSDN says OpenDatabase is available from MSI version 4.0 onwards, transactions in general from MSI 4.5 onwards. Just a hunch, but could it be that your MSI is outdated? I once had some mysterious trouble with an outdated MSI version.

Tuminoid
+1  A: 

I finally got the answer on msdn forums

DatabasePtr pDB = pInstaller->OpenDatabase(
                            "c:\\foo\\bar.msi", 
                            (long)msiOpenDatabaseModeTransact);
Fabien