Groups | Blog | Home
all groups > dotnet interop > april 2004 >

dotnet interop : Win32 Interop: Windows Installer SDK


Shane Warren
4/30/2004 4:58:40 PM
I need to determine the ProductCode from msi (install file) using a .net
application (web service) written in C#. I found a function in the Windows
Installer SDK which seems to be what i want the function is defined as:

UINT MsiOpenDatabase(
LPCTSTR szDatabasePath,
LPCTSTR szPersist,
MSIHANDLE* phDatabase
);

Mostly this isn't too tricky I defined an DLLInport for the function like:

[DllImport("msi.dll", CharSet=CharSet.Auto)]
public static extern int MsiOpenDatabase(String strDatabasePath, String
strPersist, out UInt32 hDatabase);

The tricky part is the szPersist parameter has some interesting preset
params I need to pass in that are defined as follows (from MsiQuery.h):

#define MSIDBOPEN_READONLY (LPCTSTR)0 // database open read-only, no
persistent changes
#define MSIDBOPEN_TRANSACT (LPCTSTR)1 // database read/write in
transaction mode
....etc...

I need to pass in the MSIDBOPEN_READONLY as the szPersist parameter, thats
where I'm a bit fuzzy on what should be done since that technically is a
string parameter but is being used as both string (for specifiying a path)
or a number (for specifying a mode), how does .net win32 interop deal with
this?

I've tried passing empty strings and null (which in my mind seems right),
but when the function is called it returns a successful return code (0) but
the handle returned is bogus (1, which strangely counts up by one each time
I call the MsiOpenDatabase function). I can't use the returned handle in
any of the functions that expect a handle (I get an error code 6, which is
"Handle is invalid").


Phil Wilson
4/30/2004 5:03:01 PM
Try multiple declarations for the different signatures. In your case you
need this kind of thing:

[DllImport("msi", EntryPoint="MsiOpenDatabase")]
public static extern int MsiOpenDatabaseX (string dbpath, IntPtr persist,
ref IntPtr msihandle);
......
IntPtr hand=IntPtr.Zero;
IntPtr persist = new IntPtr(1);
int res = CallMsi.MsiOpenDatabaseX ("setup1.msi", persist, ref hand);
--
Phil Wilson [MVP Windows Installer]
----
[quoted text, click to view]

AddThis Social Bookmark Button