Editing already packaged MSI
Posted 19 June 2006 - 21:14
i have the following problem with one MSI file. i am trying to update one field of the CustomAction table from an InstallShield project. This i am trying to do by loading msi.dll and using the functions within it. So far i am able to read the values, but i can't update it anyway. Neither with SQL query or MsiModifyView(). I am getting the state of the database as read-write. All functions exits normally and i am able to set a string to the record with MsiRecordSetStringA, note that i am using the ANSI functions because the Unicode are getting me unhandled exceptions.
Can someone say where i am wrong , and is that possible at all?
thanx in advance.
Posted 20 June 2006 - 00:23
Posted 20 June 2006 - 08:32
What i actually wants to be done is to insert some info into the package, which to be read and used at install time. As i read the help for transforms, the transform could be performed at install time, but this does not suits me. To create a patch i actually have to create a different build, right, which is another thing that i prefer not to do.
i found this at another post.
"As far as I know changing records in the msi file is not supported and often doesn't work. Only adding temporary rows is allowed.
Why don't you use a property in the condition and set that property programmatically?"
Do you have any idea how this could be done?
thanx in advance
Posted 20 June 2006 - 10:28
are you trying to modify the msi file during installation, or are you trying to modify a msi file on your development machine, then save the changed file and sent it to the users (basically what you could do with Orca)? In the latter case look at the sample VBScripts in the platform SDK which show how to run SQL commands to edit a msi file.
Posted 20 June 2006 - 15:11
Thank you for the hint with the VBScript, it is actually working.
And i still cannot understand why this VBscript is working, and the functions which i call from my InstallShield installscript product (not MSI) don't.
this is the code:
nResult = MsiOpenDatabaseA( szFileName, MSIDBOPEN_TRANSACT, hMSIDatabase); // return 0
nResult = MsiGetDatabaseState(hMSIDatabase); // return 1
nResult = MsiDatabaseOpenViewA( hMSIDatabase, "UPDATE `CustomAction` SET `CustomAction`.`Target`='the_exe_info' WHERE `CustomAction`.`Action`='exe'", hMSIReturnView ); // return 0
nResult = MsiViewExecute(hMSIReturnView, NULL); // return 0
nResult = MsiDatabaseCommit( hMSIDatabase ); // return 0
nResult = MsiCloseHandle(hMSIReturnView); // return 0
nResult = MsiCloseHandle(hMSIDatabase); // return 0
All this handles are installscript HWND, not MSIHANDLE or PMSIHANDLE:
here are the prototypes:
#define MSIDBOPEN_TRANSACT "1"
prototype stdcall NUMBER msi.MsiOpenDatabaseA(BYVAL STRING, BYVAL STRING, BYREF HWND);
prototype stdcall NUMBER msi.MsiViewExecute(BYVAL HWND, BYVAL HWND);
prototype stdcall NUMBER msi.MsiDatabaseOpenViewA(BYVAL HWND, BYVAL STRING, BYREF HWND);
prototype stdcall NUMBER msi.MsiGetDatabaseState(BYVAL HWND);
prototype stdcall NUMBER msi.MsiDatabaseCommit(BYVAL HWND);
prototype stdcall NUMBER msi.MsiCloseHandle(BYVAL HWND);
All prototypes are taken and reworked abit from "ISMsiQuery.h"
Is there a case when get the handle to the database, and the code returned that it is read-write handle, actually it to be read-only handle. Or my question is: do the msi class objects give more control over MSI package file?
Edited by shino, 20 June 2006 - 15:12.