I'd be very happy if someone pointed out how this is done for me..... I
really can't figure it out by myself.
Thanks in advance, guys...
- Martin
In the msi itself you will call a custom action to a windows installer aware
dll. The only paramater you will really need to send to your dll is the
handle to the current install session. I use WFWI so I have a bit of a
crutch here when it comes to setting up the entries for a custom action to
do this.
In your program you will use this handle to access the msi tables. For
example if you reference the handle by the name hInst then the function to
set the "ProductID" property would look like the below (minus error
handling):
retVal = MsiSetProperty(hInst, "ProductID", "GOOBLEYGOCK433");
Assuming you just need to do this once then use something like ORCA to add
the entry to the properties table. Microsoft provides ORCA free of charge
as part of the MS Platform SDK.
Todd Thompson
West Corp
tltho...@NOSPAMwest.com
"Martin Wirth" <Martin...@gmx.de> wrote in message
news:#54Ms8CxAHA.2036@tkmsftngp03...
MsiSetProperty(hMsi, "ProductID", m_MsiInfo.m_ProductCode); // hMsi != 0
hMsi is of the type MSIHANDLE and initialized via
MsiOpenDatabase("test.msi", MSIDBOPEN_CREATEDIRECT, &hMsi) before.
hMsi is not null ( e.g. I'm able to merge databases using the msi handle )
but when calling MsiSetProperty() I get an error (ERROR_INVALID_HANDLE).
I hope it doesn't get too confusing here... but It's already become
confusing to me.If this is all nonsense I'm talking here (which is what I
think btw ;)
please tell me where to read up on the topic (i've studied the sdk .chm ..
but it's not enough, i feel).
Regards
- Martin Wirth
"Todd Thompson" <tltho...@NOSPAMwest.com> schrieb im Newsbeitrag
news:<ut6StbpxAHA.2068@tkmsftngp05>...
As far as I can tell you can only get an hInstall handle when the program is
a custom action of a running install, so any function that uses that handle
isn't going to be very helpful.
The way I think you will want to do this is to use the MsiOpenDatabase to
get an hDatabase handle, then use MsiDatabaseOpenView to create a view
handle hView. In order to do this you will need to create query, if you are
inserting then you will probably use the INSERT INTO token and parameterize
the data so that it uses the values of your record. It is important to
point out here that in the query syntax there is a difference between `
(unshifted ~) and ' (unshifted ") and you will need to use both, so make
careful note of which is used where.
Now you will need to create a record specifying the number of fields, note
that this function is a little different in that it has a return type of
MSIHANDLE rather than returning a value by a pointer. Now you need to use
MsiRecordSetInteger, MsiSetStream, and/or MsiSetString for each field of the
record. Take a breather now you'll probably need it.
So you've got handles to a database, a view and a record, now comes the
really hard part. You use the MsiViewExecute and pass it the view handle
(with proper query) and the record handle (populated with the desired data).
If you are especially clever you would write a nifty class or template to
encapsulate all of this tedious details into one nifty call. Oh yeah and
don't forget to commit your changes using MsiDatabaseCommit (you didn't open
it as read-only I hope). And remember to close your handles with
MsiCloseHandle. Also if you are going to reuse an view handle to get a
different result set (different query) then you first need to call the
MsiViewClose function.
Hope that helps.
Todd Thompson
West Corp
tltho...@NOSPAMwest.com
"Martin Wirth" <Martin...@gmx.de> wrote in message
news:ufVBtytxAHA.980@tkmsftngp05...
I will sit down with it and experiment. The template idea is rather cool. I
know some people hate c++ templates - I love do love them.
Regards
- Martin Wirth (a lot happier than before ;)