0

I'm facing a problem in my program. I need to catch some infos about different MSIs, so I'm using the MSI Database functions from msi.dll.

In a loop, I'm creating a list of objects (called PackFile). Each object must contains infos about each file installed by the msi, and each list contains all the files installed by a given msi.

I have differents methods for all the data I need to have (like the component, componentcode, installlevel of the feature, etc.). But all the methods fail.

Here's a sample of one of those methods, this one's purpose is to find the component code of the file:

public string findComponentCode(string productCode, string ComponentName)
  {
        int pathLen = 512;
        StringBuilder path = new StringBuilder(pathLen);
        IntPtr phDatabase = IntPtr.Zero;
        IntPtr hView = IntPtr.Zero;
        IntPtr hRecord = IntPtr.Zero;
        int componentCodeLen = 512;
        StringBuilder componentCode = new StringBuilder(componentCodeLen);

        MsiGetProductInfo(productCode, "LocalPackage", path, ref pathLen);
        MsiOpenDatabase(path.ToString(), IntPtr.Zero, ref phDatabase);
        MsiDatabaseOpenView(phDatabase, "SELECT * FROM `Component`", ref hView);
        MsiViewExecute(hView, hRecord);
        while (MsiViewFetch(hView, ref hRecord) != 259)
        {
            int bufferLen = 512;
            StringBuilder buffer = new StringBuilder(bufferLen);

            MsiRecordGetString(hRecord, 1, buffer, ref bufferLen);
            if (String.Compare(buffer.ToString(), ComponentName) == 0)
            {
                MsiRecordGetString(hRecord, 2, componentCode, ref componentCodeLen);
                break;
            }
        }
        MsiViewClose(hView);
        MsiCloseHandle(hRecord);
        MsiCloseHandle(phDatabase);
        return componentCode.ToString();
    }

This function is in a loop, in order to find the code for every files.

My problem is that at a moment there is an error, the MsiOpenDatabase function return 110 (open_failed), and I can't understand why... And every time it is at the same file of the same msi...

Can someone give me a hint ?

PS: I'm quite a newbie in C# and .NET programming...

Quentin S.
  • 328
  • 2
  • 16

1 Answers1

0

I assume you've debugged this enough to see that you're getting the full path to the local package. So if all that's ok, well strictly speaking that last parameter is an out not a ref. So try:

IntPtr pHDatatabase; MsiOpenDatabase(filename, persist, out pHDatatabase);

that kind of thing - that's what I use. See this:

http://www.pinvoke.net/default.aspx/msi.MsiOpenDatabase

And I can't see your interop definition, so you may need to post it if it's not as pinvoke.net describes it.

PhilDW
  • 20,260
  • 1
  • 18
  • 28