I'm trying to use MsiDatabaseOpenView
to manipulate an .msi
installer and I am receiving an error that I cannot diagnose.
When invoking MixDatabaseOpenView
, the method is returning the error code 1615
. The method documentation indicates ERROR_BAD_QUERY_SYNTAX
as a possible error result, and 1615
maps to ERROR_BAD_QUERY_SYNTAX
according to the installer error codes. Calling MsiGetLastErrorRecord
for additional details and passing the resulting handle to MsiFormatRecord
results in the following data (line breaks and indenting added at whitespace for readibility; generified service name and msi installer/database path):
1: 2237
2: C:\path\to\myinstaller.msi
3: INSERT INTO `ServiceInstall`
(`ServiceInstall`,`Name`, `DisplayName`, `ServiceType`, `StartType`,
`ErrorControl`, `LoadOrderGroup`, `Dependencies`, `StartName`,
`Password`, `Arguments`, `Component_`, `Description` )
VALUES
('ServiceInstall.ServiceName','ServiceName' ,'My Service' , 16 , 2 ,
1 ,'' ,'' ,'' ,'' ,'' ,'C__E2E295F8B94A1C97F5DA47AACC498002' ,
'My Service Description' )
4:
The first value -- 2237
-- is a windows installer error message number that corresponds to "Invalid or missing query string" (which is consistent with the ERROR_BAD_QUERY_SYNTAX
result code). The query string, however, seems fine to me. It's certainly not missing as the data is provided back from MsiGetLastErrorRecord
, and as far as I can see (though I may be missing something), it conforms to the proper format for the insert query, and the columns match the valid columns.
Any ideas on what may be causing this operation to fail and how it may be resolved?
Also, though I don't think it should matter, here are the declarations I am using to gain access to the Msi API methods:
[DllImport("msi")]
private static extern int MsiDatabaseOpenView(IntPtr handle, string query, ref IntPtr viewhandle);
[DllImport("msi")]
private static extern IntPtr MsiGetLastErrorRecord();
[DllImport("msi")]
private static extern int MsiFormatRecord(IntPtr empty, IntPtr errhandle, StringBuilder extradata, ref int len);
After quite a bit of experimentation, removing the data insertion for the
Description
field allows things to work properly, although I'm not sure why this would be the case. The behavior was not fixed or otherwise changed when using an empty (""
) or null ("[~]
") value forDescription
, nor did changing the order of where Description was in the field list made any difference; removing was the only way that I could get it to work.