Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Inserting a property using the sdk

37 views
Skip to first unread message

Martin Wirth

unread,
Apr 13, 2001, 11:34:34 AM4/13/01
to
Hi there.....
I'm desparately trying to insert e.g. the ProductID into my installer
package ( I'm using the msi sdk 1.2 ). I've created a standard set of tables
by merging some of the sample msi's into my msi. Now I understand that I
have to insert a column 'ProductID' into the 'Property' table.
But how is this done ? The sdk talks of a method called MsiSetProperty()
.... but what I need is at least some sample code what to do before and
after the call to MsiSetProperty().

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


Todd Thompson

unread,
Apr 16, 2001, 1:01:47 PM4/16/01
to
Assuming you want to be able to do this programmatically:
http://msdn.microsoft.com/library/psdk/msi/qref_56nt.htm

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...

Martin Wirth

unread,
Apr 16, 2001, 9:21:45 PM4/16/01
to
First of all, thanks for your reply !
I'm using the sdk 1.2, trying to write a C++ programm for authoring msi
files,
and have been using the MsiSetProperty() function as you pointed out:

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>...

Todd Thompson

unread,
Apr 18, 2001, 12:19:09 PM4/18/01
to
It's not very clearly spelled out in the SDK but using the MsiOpenDatabase
will get you a handle to the database. In order to use the MsiSetProperty
you need to use a handle to an install session. Both handles are of the
MSIHANDLE type but in the prototype they call an install handle hInstall and
a database handle hDatabase.

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...

Martin Wirth

unread,
Apr 18, 2001, 2:00:10 PM4/18/01
to
Man ! Thanks a million for your in-depth explanation, Todd ! And thanks for
taking the time to write this little guide for me !

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 ;)


0 new messages