none
how to check if next record exists in an msi file? RRS feed

  • Question

  • With MsiViewFetch we are able to get the record from the sql query to msi. But is there any constant or function to check whether next record exists or number of rows/records in a file table msi?

    HasNext is not supporting for this view.


    Thanks and Regards, Uday Kiran Reddy Project Engineer Technology Infrastructure Services, Wipro Technologies ____________________________________________ Mob: +91-900-061-2578 | Email: uday1kiran@live.in

    Friday, November 17, 2017 1:09 PM

All replies

  • You loop on MsiViewFetch() while == ERROR_SUCCESS

    (ERROR_NO_MORE_ITEMS is returned when no more record)

    Friday, November 17, 2017 1:27 PM

  • Hi   uday1kiran,

    As Castorix31 suggested, you need to cycle through your information (by changing the SQL query conditions)

    MsiViewFetch function: The MsiViewFetch function fetches the next sequential record from the view.

    If you use C# to get the record exists in an msi file, you can refer the following code.

            [DllImport("msi.dll", SetLastError = true)]
            static extern uint MsiOpenDatabase(string szDatabasePath, IntPtr phPersist, out IntPtr phDatabase);
    
            [DllImport("msi.dll", CharSet = CharSet.Unicode)]
            static extern int MsiDatabaseOpenViewW(IntPtr hDatabase, [MarshalAs(UnmanagedType.LPWStr)] string szQuery, out IntPtr phView);
    
            [DllImport("msi.dll", CharSet = CharSet.Unicode)]
            static extern int MsiViewExecute(IntPtr hView, IntPtr hRecord);
    
            [DllImport("msi.dll", CharSet = CharSet.Unicode)]
            static extern uint MsiViewFetch(IntPtr hView, out IntPtr hRecord);
    
            [DllImport("msi.dll", CharSet = CharSet.Unicode)]
            static extern int MsiRecordGetString(IntPtr hRecord, int iField,
               [Out] StringBuilder szValueBuf, ref int pcchValueBuf);
    
            [DllImport("msi.dll", ExactSpelling = true)]
            static extern IntPtr MsiCreateRecord(uint cParams);
    
            [DllImport("msi.dll", ExactSpelling = true)]
            static extern uint MsiCloseHandle(IntPtr hAny);
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                string sqlStatement = "SELECT * FROM Property WHERE Property = 'ProductVersion'";
                IntPtr phDatabase = IntPtr.Zero;
                IntPtr phView = IntPtr.Zero;
                IntPtr hRecord = IntPtr.Zero;
                StringBuilder szValueBuf = new StringBuilder();
                int pcchValueBuf = 255;
    
                // Open the MSI database in the input file 
                uint val = MsiOpenDatabase(@"D:\7z1701-x64.msi", IntPtr.Zero, out phDatabase);
                hRecord = MsiCreateRecord(1);
                // Open a view on the Property table for the version property 
                int viewVal = MsiDatabaseOpenViewW(phDatabase, sqlStatement, out phView);
                // Execute the view query 
                int exeVal = MsiViewExecute(phView, hRecord);
                // Get the record from the view 
                uint fetchVal = MsiViewFetch(phView, out hRecord);
                // Get the version from the data 
                int retVal = MsiRecordGetString(hRecord, 2, szValueBuf, ref pcchValueBuf);
    
                 uint uRetCode = MsiCloseHandle(phDatabase);
                 uRetCode = MsiCloseHandle(phView);
                 uRetCode = MsiCloseHandle(hRecord);
    
                MessageBox.Show(szValueBuf.ToString());
                //return szValueBuf.ToString();
            }
    


    Best Regards,

    Yong Lu



    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, November 20, 2017 5:05 AM
    Moderator