Programmatically Build .MSI Database

145 views
Skip to first unread message

Le Chaud Lapin

unread,
Jan 29, 2008, 1:54:10 AM1/29/08
to
Hi All,

First of all, there is something I need to say, and though some of you
might think me foolish for saying it, knowing that it will make those
to whom I am about to say it less-inclined to answer the question I am
about to ask, I will will say it anyway, because after browsing to
previous posts over the last 10 years in this group, I really think it
needs to be said:

Many of us "outsiders" who come to this group, and are new to .MSI
technology, have zero or near-zero understanding of how .MSI works.
Even the word "database" is foreign to some of us, until we are forced
to read the Windows Installer documentation ourselves, only to
discoverd that .MSI tables are based upon databases, the kind that are
accessed with SQL statements. But was is _extremely_ frustrating is
that there seems to be a breach of communication between the
"outsiders" and "insiders" when questions are asked. For example, as I
began to ask the question I am about to ask, I started lamenting,
preemptively, that my question will go unanswered, and instead, some
good-hearted fellow like Dennis Bareis will suggest that I not do what
I would like to do, but use his tool instead. :) [Note: Dennis, I
honestly appreciate your helpful nature, so please do not take this as
a personal attack against you. It's not.]

Please try to understand: Many of us are engineers ourselves, with 20+
or 30+ years experience writing code in10+ languages in user-mode as
well-as kernel mode, and have been using Microsoft technology,
including its compilers, from the very early days when rebooting 40
times a day was a standard part of application development and
installation was done using DOS .bat files.

We are not dumb. We are just ignorant. You help us greatly when you
understand that we are highly receptive to the "how it works" part of
your explanation. I doubt that any of us would be put off by
relational database concepts, for example.

So when we ask for help, please, please, try to understand this, and
also try to understand that the reason we ask is not because we did a
thorough read of the documentation and did not understand it. [The
whole point of asking here is so that we do not have to read too much
of the documentation.] It is often because we are simply ewbies,
asking simple questions that another engineer, like ourselves, having
experienced the pain of having to learn himself/herself, should be
able to dump to our brains with minimum effort.

WITH THAT SAID..(whew)...

I *did* look at the Windows Installer documenation. I do understand
the model enough to know how to use the API. I get the concepts of
components, files, the cabinet-versus-no-cabinet model...the seuqence
numbers matching up, whether duplicates are allowed or not, etc..my
feeling is that, if another zero-knowledge newbie stepped into this
group and asked questions that have been asked here, I could at least
get him/her up to speed on the technology in a couple of paragraphs...
[.MSI files are relational databases, there's api in this .dll, header
file here, transactional model, tables, use orca.exe to view
databases, yada...]. The engineer would "get it" from those 3 or 4
paragraphs.

But I am at a stopping point, and the cryto aspect of my work is
calling me back.

Presently, I need to know how to:

1. Add a file to MSI database

or

2. Change uncompressed binary file to anothe binary file in .MSI
database.

But in no place in the documentation do I see where it says, "This is
how you add a file", or better yet, .

"This is where the actual data of the file is stored inside the .MSI,
and this is the programmatic procedure, using C++ of the MSI API, by
which it got there."

Please, speaking as an engineer-to-engineer, how is this done?

TIA,

-Le Chaud Lapin-

Christopher Painter

unread,
Jan 29, 2008, 9:48:02 AM1/29/08
to
I would suggest you add your opinion to this blog thread:

http://blogs.msdn.com/windows_installer_team/archive/2008/01/19/growing-windows-installer-experts-through-troubleshooting.aspx

While there are some here who would disagree with me because they love
rolling their own from scratch, the MSI SDK is really only intended to
document the API well enough for tools vendors to create authoring
tools and developers to troubleshoot why an install is failing.
While some people enjoy using the tools ( ORCA, MSIVAL2,
WiRunSQL.vbs ) to create installs, they are really just sample
tools. Orca is great for sneak and peak troubleshooting but anyone
who uses it to author complex packages is either doing it for the
gratification of learning or they are just really cheap or stupid.
IMHO.

That said, do learn the SDK. It's important to understand the how's
and why's. But do also pick up a tool like WiX/WiXAware,
InstallShield, Wise, InstallAware and let it guide you on your path.
There is a reason developers of these tools have spent countless hours
automating the relationships into simple to understand designers.
There are also reasons to understand the SDK as these vendor tools are
not 100% what everyone needs. Eventually you'll need to color outside
the lines and/or troubleshoot some obsecure behavior.

So for your example questions using InstallShield:

1) Right click New Feature, Right Click New Component, Right Click
Insert File, Right Click Set Keyfile. Fill in all the various
attributse.
Knowing the MSI SDK is helpful here to make sure you don't violate
the component rules but you shouldn't have to memorize tables|columns
worth of values and author it all by hand.

2) Right Click New Release Wizard and select options for compressed or
uncomressed. Repeat for different configurations then decide which
one to build. In your build automation you use issabld.exe with
command line switches and/or msbuild integration to specifiy which one
gets built. http://www.joyofsetup.com/2008/01/28/new-wix-feature-defaultcompressionlevel/
has a good use case of why you'd do this using WiX.

For your final question, the tools compress files into cab's, record
information about it all in the Media Table and store it in streams
and/or externally in the installation media. The SDK does cover
this, if you know what you are looking for. Again, just spend some
money on a nice tool. Trust me, people balk at paying $2000 for
InstallShield but for me that's a couple days worth of labor. The ROI
is awesome. After all, one could write C# applications using
Notepad.exe, but most are smart enough to pick Visual Studio or Sharp
Develop.

Le Chaud Lapin

unread,
Jan 29, 2008, 11:55:50 AM1/29/08
to
On Jan 29, 8:48 am, Christopher Painter <chr...@yahoo.com> wrote:
> I would suggest you add your opinion to this blog thread:
>
> http://blogs.msdn.com/windows_installer_team/archive/2008/01/19/growi...

I will take a look at that.

> While there are some here who would disagree with me because they love
> rolling their own from scratch, the MSI SDK is really only intended to
> document the API well enough for tools vendors to create authoring
> tools and developers to troubleshoot why an install is failing.

Seems like it might be for developers like me who is not interested in
creating another InstallShield but has a task where programmatic
modification of .MSI database is a necessity.

> While some people enjoy using the tools ( ORCA, MSIVAL2,
> WiRunSQL.vbs ) to create installs, they are really just sample
> tools.    Orca is great for sneak and peak troubleshooting but anyone
> who uses it to author complex packages is either doing it for the
> gratification of learning or they are just really cheap or stupid.
> IMHO.

Glad we agree about not using ORCA for the super complex. So how can I
do it in C++?

> That said, do learn the SDK.  

How much of the SDK?

Consider this:
If any of the experts in .MSI database just happened to have to do
something with device drivers, perhaps find a way to auto-install
legacy, non-hardware driver using technique that Sysinternals Tools
likes to use, and they came to the Windows Driver group asking how to
do it, knowing that there would be probably people who could rattle
off in 5 seconds how it's done...

the response probably NOT be..."That said, do learn the DDK."

As I said before, many of us have a specific task that needs to be
done. We're not ignorant or stupid. We need to come in, have a meal,
and leave, not become chef of the restaurant.

> It's important to understand the how's
> and why's.   But do also pick up a tool like WiX/WiXAware,
> InstallShield, Wise, InstallAware and let it guide you on your path.
> There is a reason developers of these tools have spent countless hours
> automating the relationships into simple to understand designers.

This point would be true for people who do nothing but make
installation packages, not people who write massive software tools in C
++/assembly language. Note that I do not need "simple to understand",
which I tried to convey, in the least offenssive manner possible in my
original post, without detracting from the essence of my message. I
guess I failed. The problem here is not complexity. There is nothing I
find remotely terrifying about .MSI databases. It is a simple matter
of knowledge. You have it. I do not. If you tell me, i will have it
too. :) I can also read, so if I get past this hump, I will move on
and continue reading the MSDN Windows Installer documentation, and
there will shortly come a point where I will not bother you or anyone
else in this group anymore, because I will be on my way.

> There are also reasons to understand the SDK as these vendor tools are
> not 100% what everyone needs.  Eventually you'll need to color outside
> the lines and/or troubleshoot some obsecure behavior.

I am glad we agree that I need to understand.

> So for your example questions using InstallShield:

I have never used InstallShield in my life. I'm a C++ programmer
wanting to use the Windows Installer API... you know, <msi.h>????

> 1) Right click New Feature, Right Click New Component, Right Click
> Insert File, Right Click Set Keyfile.  Fill in all the various
> attributse.

See above.

>   Knowing the MSI SDK is helpful here to make sure you don't violate
> the component rules but you shouldn't have to memorize tables|columns
> worth of values and author it all by hand.

Yes agreed.

> 2) Right Click New Release Wizard and select options for compressed or
> uncomressed.   Repeat for different configurations then decide which
> one to build.   In your build automation you use issabld.exe with
> command line switches and/or msbuild integration to specifiy which one

> gets built.    http://www.joyofsetup.com/2008/01/28/new-wix-feature-defaultcompressi...


> has a good use case of why you'd do this using WiX.

No InstallShield in my office anywhere.

For your final question,  the tools compress files into cab's, record
> information about it all in the Media Table and store it in streams
> and/or externally in the installation media.  

Ah..a glimmer of light.

What happens if the files are not compressed? Where are they stored.

> The SDK does cover
> this, if you know what you are looking for.  Again,  just spend some
> money on a nice tool.   Trust me, people balk at paying $2000 for
> InstallShield but for me that's a couple days worth of labor.  The ROI
> is awesome.   After all, one could write C# applications using
> Notepad.exe, but most are smart enough to pick Visual Studio or Sharp
> Develop.

I happen to have Visual Studio. I do not have $2000.

You certainly proved one thing. Lamenting preemptively that my
question would go unanswered was not entirely a prejudgemental waste
of time.

I hope I am not offending you, but if you were in my position, you
would be highly, highly frustrated.

So I will ask again, so that you, or anyone else who has a inkling of
my point of view, might answer if you are so kind.

1. I am an experienced C++ developer.
2. I have Visual Studio 2008.
3. I have the full set of Windows Installer SDK headers and tools.
4. I am not squeamish toward Windows Installer software technology,
not in the least.
5. I have FOO.MSI
6. It contains a file FOO1.BIN
7. I want to replace the file with FOO2.BIN

I do realize that it is good to develop expertise in things. I happen
to understand convolution from Fourier Theory and signal processing,
which makes it extremely difficult for me to fail to configure cable
TV boxes, TV's, however I want. Four months ago, when my 81-year-old
neighbor was having problems with her cable TV setup up, she asked me
if I could help her fix it. She's not dumb, and she does know that in
the US, there is something with Channel 3 or 4 she has to do, but I
did what she wanted, because I knew that despite her understanding,
something weird must have happen, or there was something she was
missing, and at 81 years old, she really does not have time to learn
convolution theory. I did not say, "Hey, you know, there's a cable
manual that talks about this....or convolution is not for the faint-of-
heart." She already knows that. I imagine that she read the manual
before calling me and could not find what she wanted.

What perplexes me is that this group is one of only two groups in all
the technical groups I use on USENET where I seem to have this problem
with communication. By contrast, if I go to the kenel-mode group, and
ask an extremely complex question, the answer will be generated with
lightning efficiency.

Can we have a bit of that here...PLEASE?

I have already read about the hash info, file sizes, etc. all that
stuff makes sense. I understand the creation of view and execution of
SQL statements against the database. I understand the rollback
procedures, the use of smart-pointers for handles instead of raw do to
the large degree of nesting that would undoubtedly occur in real
application...

I simply need to know

(a) if it's possible and

HEY! Look here: >>>>> (b) which of the Windows Installer SDK C++
functions would be used to do that. <<<<<

I don't need a whole code sample, or an entire article, just a little
bit to get past the "hump". I can do the rest.

If anyone could be so kind to include, with all their suggestions on
what I should learn, what not, which groups I should post to,
anecdotes, how .MSI technology is not for the faint-of-heart,
etc...the answer to my question...arrggg!!!...please, I would be
grateful.

I'm starting to laugh hysterically, but I don't know why - there is
nothing funny about this.. :)

TIA,

-Le Chaud Lapin-

Christopher Painter

unread,
Jan 29, 2008, 12:37:51 PM1/29/08
to
It's difficult to answer your questions because they are generally
broad and open ended. You asked

How Much of the SDK? - The MSI SDK is part of the PSDK. You
want to read all of MSI.CHM.

You mentioned that other groups can answer your question easily.
Well, I can to, if it's a focused question. Unless you have me in
your office for 8 hours freeflowing QA it's very difficult to answer
broad questions. Your not really asking how to install a device
driver, your asking how do you write a device driver.

You also said:

>> Knowing the MSI SDK is helpful here to make sure you don't violate
>> the component rules but you shouldn't have to memorize tables|columns
>> worth of values and author it all by hand.
>Yes agreed.

Well, when you are authoring MSI's using C++ that's exactly what you
have to do.... memorize. You don't have any automation abstracting
you from the data. You have to roll all your own automation to author
the table data. Part 1 of the answer would be what API's and
Part 2 would be what to do with the API's ( table data ). Well,
there is a whole lot of API's to go through.... Opening databases,
creating views, creating records, xecuting, fetching, checking error
codes, closing handles so on and so on. Once you know how to do
all of that, then you start focusing on what do you put in those
tables? What is the relationship between the Feature, Component,
Directory, File and Media tables?

Seriously, I'm glad you know a lot about C++ ( and I wish I could
spend 8 hours in a room with you learning to write co-installers and
use the DIFx SDK ) and I'm sure you'll have fun learning all of this,
but I think you'll have more fun if you checkout a tool like Windows
Installer XML ( WiX - Free and Open Source ).... learn how it converts
xml schema into installer databases then go peaking through it's
source code to see how it all works.

Le Chaud Lapin

unread,
Jan 29, 2008, 1:08:05 PM1/29/08
to
On Jan 29, 11:37 am, Christopher Painter <chr...@yahoo.com> wrote:
> It's difficult to answer your questions because they are generally
> broad and open ended.    You asked
>
> How Much of the SDK?      -  The MSI SDK is part of the PSDK.  You
> want to read all of MSI.CHM.


> You mentioned that other groups can answer your question easily.

No, I said that if another expert in another group can answer my
question easily if I ask them a question about something that they
know about in that group.

For example, if I go to sci.physics group and ask, "Is permittivy of
glass different from permittivity of free space, and if so, what is
the permittivity of free space?"

Someone will answer,

"Yes. 8.85x10-12 Farad/m".

Then I will leave and they will leave and all will be well in the
world.

> Well, I can to, if it's a focused question.   Unless you have me in
> your office for 8 hours freeflowing QA it's very difficult to answer
> broad questions.   Your not really asking how to install a device
> driver, your asking how do you write a device driver.

No, my question was very specific. For example, if you read my
original post, you will see that I explicitly stated uncompressed
files. Your followup [which happened to be devoid of the answer I am
seeking] talked about cab files.

I asked for a specific API. Not how to write an installer package.
Note that I did not even assume that such an API existing. I asked
1st, if it existed, and 2nd, if it did, what is it.

It is either present or not. Is it or is it not? and if it is, what is
it? Or do you know?

> You also said:
>
> >>   Knowing the MSI SDK is helpful here to make sure you don't violate
> >> the component rules but you shouldn't have to memorize tables|columns
> >> worth of values and author it all by hand.
> >Yes agreed.
>
> Well, when you are authoring MSI's using C++ that's exactly what you
> have to do.... memorize.  You don't have any automation abstracting
> you from the data.  You have to roll all your own automation to author
> the table data.       Part 1 of the answer would be what API's and
> Part 2 would be what to do with the API's ( table data ).      Well,
> there is a whole lot of API's to go through....   Opening databases,
> creating views, creating records, xecuting, fetching, checking error
> codes, closing handles  so on and so on.    

I am far enough along in that that I have no worries about doing
that. Relational databases were around before .MSI. For some strange
reason, which I cannot understand, the knowledge of using SQL
statements against other databases applies to .MSI. Strange. [When it
finally dawned upon me that that was what Microsoft was using (though
the documentation does not state that upfront, they just start talking
about tables as if ever engineer reading were a Siamese twin].

> Once you know how to do
> all of that, then you start focusing on  what do you put in those
> tables?     What is the relationship between the Feature, Component,
> Directory, File and Media tables?
>
> Seriously, I'm glad you know a lot about C++ ( and I wish I could
> spend 8 hours in a room with you learning to write co-installers and
> use the DIFx SDK ) and I'm sure you'll have fun learning all of this,
> but I think you'll have more fun if you checkout a tool like Windows
> Installer XML ( WiX - Free and Open Source ).... learn how it converts
> xml schema into installer databases then go peaking through it's
> source code to see how it all works.

Ok, so are you saying you _do_ know the answer and refuse to tell me
or you _do not_ know the answer and refuse to tell me that you do not.

Just so we are clear...I have no problems doing the following, right
now, based on what I have read so far:

".... Opening databases,
> creating views, creating records, xecuting, fetching, checking error
> codes, closing handles so on and so on. "

I know how to do the above, right now, _manually_ in C++, given C:
\FOO.MSI which I just so happened to create using Visual Studio 2005.

C:\FOO.MSI contains a file called FOO1.BIN.

I understand the directory table in the .MSI, the relationship, the
convention of using GUIDs for unique identification, I get the overall
picture.

**** I AM STUCK ON A VERY PARTICULAR ISSUE ****

I want to replace FOO1.BIN, in FOO.MSI, with FOO2.MSI, using...

.... Opening databases,
> creating views, creating records, xecuting, fetching, checking error
> codes, closing handles so on and so on.

Which I *ALREADY* know how to do.

I am simply unclear which tables need to be modified and what method
is used to actually bundle FOO1.BIN (and hence FOO2.BIN) with the .MSI
bundle.

I am curious. Do you know how to do this, programmatically, in C++,
using msi.h, msiquery.h, and msi.lib ? At this point, you don't have
to tell me if you do or not. I am simply trying to determine if the
reason you want tell me is because you don't know, or because do know
and just enjoy yanking my chain over the Internet. ;)

-Le Chaud Lapin-

Phil Wilson

unread,
Jan 29, 2008, 1:23:37 PM1/29/08
to
Perhaps I'm misunderstanding what you're asking, but there's a reason you
can't find documentation on adding a file to an existing MSI, and that's
because you don't add a file to an existing MSI. The way to add files is to
use whatever tool you have for building them, add the file to the build of
the MSI file with that tool and build the MSI from scratch. It might be
loosely called a database, but it's not that kind of database. A file
typically isn't "in" the MSI. It's in a CAB file, the CAB file is in a
stream in the MSI, and there are various references to the file via its
sequence in the CAB, and other places like the File table. The same is true
of your other question. There are no tools I'm aware of that will add a file
to an existing MSI file or substitute one file for another without a
rebuild. There are varying degrees of success with which this could be
hacked, but you're in the same situation as having a code file from somebody
and there's a line of code you want to change, and you won't documentation
for that in the SDKs either.

If you want to build a tool to create MSI files from scratch, adding a file
is the least of your issues. You'd need to be familiar with the concept of
installer components and the rest of the tables. I'd start by reverse
engineering a simple MSI file built by a Visual Studio setup project.
--
Phil Wilson
[MVP Windows Installer]


"Le Chaud Lapin" <jaibu...@gmail.com> wrote in message
news:524d11fb-673d-4fea...@i3g2000hsf.googlegroups.com...

Le Chaud Lapin

unread,
Jan 29, 2008, 1:51:53 PM1/29/08
to
Hi Phil,

On Jan 29, 12:23 pm, "Phil Wilson"


<phil.wil...@wonderware.something.com> wrote:
> Perhaps I'm misunderstanding what you're asking, but there's a reason you
> can't find documentation on adding a file to an existing MSI, and that's
> because you don't add a file to an existing MSI. The way to add files is to
> use whatever tool you have for building them, add the file to the build of
> the MSI file with that  tool and build the MSI from scratch.  It might be
> loosely called a database, but it's not that kind of database. A file
> typically isn't "in" the MSI.

I read that. I read that in the MSDN documentation last night while
munching on cookies. I understand the concept of streaming, the
putting the file in CAB, why the compression is better that way versus
individual files, the 15 file limit, the sequence numbers...

I read enough of that so that I arrive at the point, if I get stuck on
_those particular things_ I can unstick myself.

I also read that there is the option of compressed or uncompressed
files. I am only interested in uncompressed. Some of my files have
only 24 bytes in them.

> It's in a CAB file, the CAB file is in a
> stream in the MSI, and there are various references to the file via its
> sequence in the CAB, and other places like the File table.  The same is true
> of your other question. There are no tools I'm aware of that will add a file
> to an existing MSI file or substitute one file for another without a
> rebuild. There are varying degrees of success with which this could be
> hacked, but you're in the same situation as having a code file from somebody
> and there's a line of code you want to change, and you won't documentation
> for that in the SDKs either.

I tried to empasize in my OP that I have no intention of using a tool
to add a file to .MSI package. I tried to emphasize that, if it is
possible, I would be doing it with C++. The reason I am thinking
this, if it is wrong is because...

1. Tool makers have to use the MSI API, you know, <msi.h>, etc. are
thoroughly familiar with to make their tools.
2. When a tool like InstallShield or Visual Studio .MSI Maker
(whatever it's called) is about to

a. stream in a cab of files into a .MSI

OR

b. add uncompressed file, outside a cab

it invokes some API defined by Microsoft and published in the MSDN
help on Windows Installer.

I am interested in (b). I want to know what API they are invoking.

> If you want to build a tool to create MSI files from scratch, adding a file
> is the least of your issues. You'd need to be familiar with the concept of
> installer components and the rest of the tables. I'd start by reverse
> engineering a simple MSI file built by a Visual Studio setup project.

A month ago, I had no clue. I did not know that tables meant tables as
in the kind we are all familiar with as engineers.

That is no longer the case. I get the gist of it. I have browse
through all 88 tables in my current .MSI many times. I know about
Schema.MSI

I cannot understand why people keep telling me...you need to
understand what you are doing...

I never said I did not.

I am saying there is an extremely specific piece of information that I
am looking for that I wish someone would tell me. Allow me copy the
help text from MSDN here:

"Uncompressed Sources

A source consisting entirely of uncompressed source files should omit
the compressed flag bit from the Word Count Summary Property. All of
the uncompressed files in the source must exist in the source tree
specified by the Directory table."

I click on the "Directory table" to learn about that. It says, among
other things:

"Directory
The Directory column contains a unique identifier for a directory or
directory path. This column can contain the name of a property that is
set to the full path of a target directory. If this column contains a
property, the target directory takes the name specified in the
DefaultDir column and takes the parent directory specified in the
Directory_Parent column.
If the Directory_Parent column is either null or equal to the value of
the Directory column, the Directory column represents a root target
directory. Only one root directory may be specified in the Directory
table."

Ok fine. No issues here.

It does not say *which API function* that a Tool Maker would use to
add files to the database during the building/construction/compilation/
synthesis [choose your favor word] of that .MSI database.

Note that, by the word "add", I do not necessarily mean add after the
fact, I mean "put".

These tables are tables of references to files that should be bundled
internally to the .MSI, assuming no external .CAB is used.

So...assuming a single .MSI, no external or internal .CABS of any
kind, and that all user files are .TXT file (for sake of
amusement)....

What API function is used to build not the reference in the tables,
which I clearly see how to do, but to put the files in the .MSI.

Obviously, if I make a .MSI file using the Windows Installer API, and
give that .MSI to a customer, and it contains a bunch of references to
a file called FOO2.BIN, and the customer goes to install the .MSI , it
will fail, because though all the references in the table are correct,
the actual FOO2.BIN file will not be in the .MSI package unless I do
"ZZZ".

What is "ZZZ" ? What API puts the file in the .MSI bundle?

-Le Chaud Lapin-


Le Chaud Lapin

unread,
Jan 29, 2008, 2:17:40 PM1/29/08
to
Hi All,

This message is being cross-posted to microsoft.public.platformsdk.msi
and microsoft.public.vstudio.general becuase am reaching a terminal
point of frustration, and it might be due to my inability to convey
what I am trying to say, so I would like to explain it to a group of
people that I normally communicate with, and hope one of them could be
so kind as to translate for me.

BACKGROUND:

I am trying to make a .MSI file, the kind that you download off the
Internet, install, etc. Let's call it FOO.MSI. I intend to synthesize
this FOO.MSI using a combination of Visual Studio 2005 and the Windows
Installer API: http://msdn2.microsoft.com/en-us/library/aa369425(VS.85).aspx

For those of you who are not familiar about what exactly is going on
when user double-clicks .MSI file, it's this essentially this:

Microsoft decided to structure the .MSI file as database, much like
the kind from RDBMS's with tables, rows, columns, keys, etc. In fact,
they have a tool Orca.exe, which one can use and actually see the
schema of the database. The probably used a database format for many
reasons, including the comfort gained from being able to reuse
concepts of commit, rollback, etc, that have been thorougly explored
in relational databases. When a company like InstallShield makes a
tool to allow some of us programmer to create .MSI packages, they
write their tool in, say, C++, but they use the Windows API, which
includes MSI.LIB, MSI.DLL, <MSI.H>, and <MSIQUERY.H> and perhaps more,
to actually build the FOO.MSI. So we set checkboxes, type in text, in
the InstallShield or Wise or whatever build API, and behind the
scenes, they create a file call FOO.MSI, using the Windows Installer C+
+ functions to open FOO.MSI of disk, and regard the opening of file as
opening of a "database", then pump **** textual SQL statements **** to
other Windows Installer API functions, passing additionally a handle
to the opened file/database, to get the structure of the .MSI exactly
the way they want it. When they are finished, FOO.MSI will typically
contain many tables, 88 in my case, filled in with all kinds of inter-
table references, for example, a GUID identifying the product code for
the entire package. Naturally, since tables are used, things like the
directory hierarchy created at target of installation will be defined
using linkage among tables.

Now if you have a file called FOO1.BIN, which is to be bundled inside
FOO.MSI when FOO.MSI is built, there are two options:

1. Put FOO1.BIN and all its friends, FOO2.BIN, FOO3,BIN, etc. in a
compressed .CAB file. the .CAB file can be stored as a "stream" inside
FOO.MSI. The CAB packing of these ancillary files achieves greater
compression than would be achieve by individual packing of each
ancillary file before affixing them to FOO.MSI.

2. Just put FOO1.BIN and all its friends in the .MSI package, not
compressing them.

And thus we have the breach of communication mentioned at beginning of
this post:

I am trying to get the .MSI experts in the
microsoft.public.platformsdk.msi to tell me which of the <msi.h>
functions is used to do #2, to put a FOO1.BIN or FOO2.bin in the .MSI
package.

Also, *if* it is possible, I am trying to get them to also tell me
which of the <msi.h> functions would be used to either:

1. Remove FOO1.BIN and put in FOO2.BIN

OR

2. Replace FOO1.BIN with FOO2.bin.

I do not care which method is used, so long as, at end of day,
FOO1.BIN has been replaced by FOO2.BIN.

Some othe the microsoft.public.platformsdk.msi experts, probably do to
my inability to communicate clearly what I want, insist that it is
better that I understand what is going on. :))

If any of you would please be so kind, if you understand my writing,
to translate for me and indicate what I want, I would be greatful,
both to the translator, and the person in
microsoft.public.platformsdk.msi who provides the answer.

Note that I do not *know* that it is possible to replace an
uncompressed FOO1.BIN with FOO2.BIN, I only *suspect* that it is
possible, again *NOT* using the streaming .CAB technique.

TIA,

-Le Chaud Lapin-

Le Chaud Lapin

unread,
Jan 29, 2008, 2:31:14 PM1/29/08
to
On Jan 29, 12:23 pm, "Phil Wilson"
<phil.wil...@wonderware.something.com> wrote:
> Perhaps I'm misunderstanding what you're asking, but there's a reason you
> can't find documentation on adding a file to an existing MSI, and that's
> because you don't add a file to an existing MSI. The way to add files is to
> use whatever tool you have for building them

[snip]

I just realized after I responded that this gives me a good
opportunity to reask my question in a hopefully non-ambiguous way:

Let us pretend for a moment that I am a janitor, working for Wise or
Installshield, who happens to have a strong interest in .MSI
technology. As I am vacuuming the floor behind one of the senior
software engineers, I look over his shoulder, and suprising, on his
screen, with Visual Studio 2008 , is the exact code that implements
the part of his tool where he takes the list of files his customer has
entered and starts packaging the .MSI file based on that list and
extraction from his customer's disk. I notice at the top of his .cpp
file that, strangely, he has included <msi.h>, <msiquery.h>, and that
he has added msi.lib to his linker command line...and I ask him...

"Sir..I noticed that you're including msi.h and msiquery.h. Why?"

And he says,

"Well janitor, it's because I am using these MSI functions. You can
see how I open the database with MsiOpenDatabase. I get handle back
from that. You can also see where I am going through list of file
paths that my customer will have specified in my GUI. And this is
where I use the XYZ function to bundle up those specified files into
the target .MSI"

And I say,

"I notice that you are not making a .CAB from the specified files, but
putting them in uncompressed. Why?"

And he will say,

"Because I tested flag as you can see above, and at this point in
code, user has explicitly stated that they do *not* want .CAB, either
streamed in or as a companion."

I say,

"Wow. Cool. You mind moving your hand out of the way so I can see how
you put the files in using uncompressed technique?"

When he moves his hand out of the way, what C++ code will I see?

-Le Chaud Lapin-

Christopher Painter

unread,
Jan 29, 2008, 3:13:38 PM1/29/08
to
On Jan 29, 1:31 pm, Le Chaud Lapin <jaibudu...@gmail.com> wrote:
> Let us pretend for a moment that I am a janitor, working for Wise or
> Installshield, who happens to have a strong interest in .MSI
> technology. As I am vacuuming the floor behind one of the senior
> software engineers, I look over his shoulder, and suprising, on his
> screen, with Visual Studio 2008 , is the exact code that implements
> the part of his tool where he takes the list of files his customer has
> entered and starts packaging the .MSI file based on that list and
> extraction from his customer's disk.

And as I said before, go checkout http://wix.sourceforge.net/ and
download the source tree. This is the most complete open source
project you'll find and the developers hang out on a list called WiX-
devs so you can actually ask them yourself. Only don't expect to see
a whole lot of C++. The majority of the toolset is written in managed
code with a p/Invoke interop layer back to the Win32. The only stuff
that is unmanaged C++ is the custom actions modules since these
actually get executed at install time where you can't assume you have
the .NET framework.

Le Chaud Lapin

unread,
Jan 29, 2008, 3:25:25 PM1/29/08
to

Ok, but before I do that, I am going to run out to the bookstore to
buy a book on .NET. I'll study that 1st, which should take me 5-5
weeks. After I do that, I will read the download you suggested, which
should take 1-2 days. Then, when one of my engineers asks me why I
don' t have the 3-line answer to the question I asked 6 weeks prior,
I'm going to tell him that it should be obvious to him that I am
working in the most efficient manner possible.

Of course, that last paragraph is somewhat facetious, but this
following question is not at all, really not, I really want to know so
please do not be offended.

Do you, or do you not, know the Windows Installer, C++, API, the
function that is responsible for the synthesis of a FOO.MSI from
FOO1.BIN, FOO2.BIN, FOO3.BIN. I am talking about a function that I
have a strong suspicion begins with Msixxxxxx since 99.9% of all the
other other functions begin with Msixxxxx.

1. If you do, just tell me. I can handle it, I promise. :)

2. If you do not, just tell me, I can handle it, I promise. :)

-Le Chaud Lapin-

Phil Wilson

unread,
Jan 29, 2008, 4:57:34 PM1/29/08
to
The problem here is that adding a file is not one API call.

Let's assume that the files are all uncompressed and separate and you want
to substitute a file. Is it recommended? No. But you'd subsitute the
uncompressed file and then do a series of SQL commands, having called
MsiOpenDatabase.

MsiDatabaseOpenView with SQL Query on the File table to update the file with
new size and version. Something like UPDATE File Set File.Version='whatever'
where File.Name = etc etc.
MsiViewExecute
MsiViewFetch

This example should be helpful:

http://msdn2.microsoft.com/en-us/library/aa367523.aspx

These as SQL examples:
http://msdn2.microsoft.com/en-us/library/aa368562.aspx

http://msdn2.microsoft.com/en-us/library/aa372879(VS.85).aspx


Adding a new file means creating a component for the file (adding a new row
to that table), adding the component to the component table, adding the
component to the featurecomponents table, adding whatever else might be
relevant (Filehash table, shortcuts, anything where the file is more than
just a file).

--
Phil Wilson
[MVP Windows Installer]

"Le Chaud Lapin" <jaibu...@gmail.com> wrote in message

news:c9ce5184-acf3-4294...@j20g2000hsi.googlegroups.com...

Stephen Connolly

unread,
Jan 29, 2008, 5:13:48 PM1/29/08
to
If I have understood what you are getting at, you can't put 'raw'
files 'in' the MSI package, unless you count the custom action
binaries, RTFs for license agreements and image files for use in the
UI which are stored in the binary table for use during the
installation. These files are available to the installation, but are
not actually installed.

Either you must put the payload files into one or more cab files, and
embed these cabs into the package in the _streams table; or you must
use an uncompressed (aka administrative) image where the files are all
stored in a folder structure *alongside* the MSI package. The folder
layout of the source folders is defined in the Directory table where
you specify the source and target directories - the source layout need
not necessarily map onto the target layout - for example you may have
sets of binaries targeted at different OSs that all need to be in
separate folders in the source layout, but on the target they will all
end up in the same folder.

If you want to make a one-file downloadable MSI package you will need
to add all your payload files into one or more cabs and stream those
cabs into the package. As part of that job you will also need to
extract any of the relevant file metadata (size, version, etc) to put
it into the file table. AFAIK there are no convenient API functions
for doing this in one go, you have to go through all the steps bit by
bit.

So, to reiterate what Phil said earlier, replacing a file in an
existing MSI is not straightforward (though not impossible) and it's
probably easier to just rebuild the whole thing, which is what the
shelfware tools do, rather than incrementally tweaking the tables and
cabs. The alternative would involve extracting the old cab from the
_Streams table replacing files in that cab, re streaming it to the
_Streams table and updating the file table appropriately, as you said.

The only other way to achieve a 'single file' download without using
cabs/streams, is to create a self-extracting zip of the uncompressed/
administrative image. Some of the shelfware tools will create files of
this type, extracting the MSI to a temp folder and installing from
there, but this isn't an ideal solution IMO as it can make repairing
the installation awkward.

Sorry to disappoint that I can't give you the solution you might
expect, that's just the way MSI works.


Le Chaud Lapin

unread,
Jan 29, 2008, 5:30:59 PM1/29/08
to
On Jan 29, 3:57 pm, "Phil Wilson"

<phil.wil...@wonderware.something.com> wrote:
> The problem here is that adding a file is not one API call.
>
> Let's assume that the files are all uncompressed and separate and you want
> to substitute a file. Is it recommended? No. But you'd subsitute the
> uncompressed file and then do a series of SQL commands, having called
> MsiOpenDatabase.

Yes, I am familiar with MsiOpenDatbase. I read about it ad nauseum
last night until 12:30.

> MsiDatabaseOpenView with SQL Query on the File table to update the file with
> new size and version. Something like UPDATE File Set File.Version='whatever'
> where File.Name = etc etc.
> MsiViewExecute
> MsiViewFetch

You might find this hard to believe, but I also know how to read the
"man pages", the MSDN docs for these functions, and there is very
little mystery in my mind about how to tweak the tables using these
functions. That's not the problem.

> This example should be helpful:
>
> http://msdn2.microsoft.com/en-us/library/aa367523.aspx

I study this link ad nauseum also, since "adding binary data" seemed
to be the closest thing to what I was looking for.

> These as SQL examples:http://msdn2.microsoft.com/en-us/library/aa368562.aspx
>
> http://msdn2.microsoft.com/en-us/library/aa372879(VS.85).aspx
>
> Adding a new file means creating a component for the file (adding a new row
> to that table), adding the component to the component table, adding the
> component to the featurecomponents table, adding whatever else might be
> relevant (Filehash table, shortcuts, anything where the file is more than
> just a file).

Ah...Phil. :)

If you look at the paragraph that you just wrote, you talked about
many things that would involve adding a "file" to the .MSI bundle.

1. You talk about the components. Check.
2. You talk about the featurecomponents. Check.
3. You talk abut updating the hash, and specifying shortcuts. Check.

Now, if I were to fire up Visual Studio 2008 right now, take a
dummy .MSI file,

I could write code to...

1. Open the database using MsiOpenDatabase...
2. Define featurecomponets...using MsiViewExecute and appropriate SQL
statements
3. Definte shortcuts using same...
4. Tweak a few other tables...yada...

And then, I would have my FOO.MSI.

When a customer goes to double-click on FOO.MSI, assuming I were able
to actually close the database and it passed internal-consistency
check,

the FOO.MSI would be corrupt.

The reason it would be corrupt, I *think* is because I'd have all
kinds of references to a file that supposed to be installed, call it
FOO1.BIN, including short cuts, little pictures, indication that it is
part of a component, etc...

but the imagine itself, the "meat" of FOO1.BIN would not be in FOO.MSI

What function puts the "meat" of FOO1.BIN into FOO1.MSI?

The "meat" of FOO1.BIN, the 48,962 bytes for example, if FOO1.BIN is a
file whose size is 48,962 bytes, does not magically jump into a .MSI
installer when a person is using say, InstallShield, to make
the .MSI. There is a function provided by Microsoft, inside of
msi.dll, that is called by the InstallShield .MSI builder that puts
the "meat" of FOO1.BIN into FOO.MSI, in addition to the ancillary
stuff you mentioned like shortcuts, etc.

What is that function or functions?

-Le Chaud Lapin-

Le Chaud Lapin

unread,
Jan 29, 2008, 5:45:52 PM1/29/08
to

Oh no. You gave me exactly what I have been asking for.

I might add that the MSDN documentation is horrible on this topic.

So now I understand.

If I have FOO.MSI, and it has as one of its file, FOO1.BIN, and if I
want that file to go along with .MSI as a unit, I *must* make a .CAB


from the FOO1.BIN, and stream it in. Microsoft writes:

"Uncompressed Sources

A source consisting entirely of uncompressed source files should omit
the compressed flag bit from the Word Count Summary Property. All of
the uncompressed files in the source must exist in the source tree
specified by the Directory table."

Ok, sure, that makes sense.

But they never said how the files got there, and now I know that they
cannot be put there by the .MSI unless they were stored in a .CAB
inside the .MSI. [Looking at the docs, I imagine there might be
trickery involving custom actions and extracting binary blogs from
the .MSI, but I have *not* intention of even thinking of doing that. I
just wanted to mention it.]
If I do not want to use .CAB FILES, I *have* to provide a companion
external file hierarchy, of which FOO1.BIN is a part, and put
references into tables inside FOO.MSI, so that during installation,
FOO1.BIN can be located, assuming of course, that FOO1.BIN managed to
get into its proper place before exection against FOO.MSI.

Sigh.

Thanks a lot, and if this perception is wrong, I am sure one of you
will tell me so. :)

-Le Chaud Lapin-

Le Chaud Lapin

unread,
Jan 29, 2008, 9:53:02 PM1/29/08
to
On Jan 29, 3:57 pm, "Phil Wilson"

<phil.wil...@wonderware.something.com> wrote:
> The problem here is that adding a file is not one API call.
>
> Let's assume that the files are all uncompressed and separate and you want
> to substitute a file. Is it recommended? No. But you'd subsitute the
> uncompressed file and then do a series of SQL commands, having called
> MsiOpenDatabase.
>
> MsiDatabaseOpenView with SQL Query on the File table to update the file with
> new size and version. Something like UPDATE File Set File.Version='whatever'
> where File.Name = etc etc.
> MsiViewExecute
> MsiViewFetch
>
> This example should be helpful:
>
> http://msdn2.microsoft.com/en-us/library/aa367523.aspx
>
> These as SQL examples:http://msdn2.microsoft.com/en-us/library/aa368562.aspx
>
> http://msdn2.microsoft.com/en-us/library/aa372879(VS.85).aspx
>
> Adding a new file means creating a component for the file (adding a new row
> to that table), adding the component to the component table, adding the
> component to the featurecomponents table, adding whatever else might be
> relevant (Filehash table, shortcuts, anything where the file is more than
> just a file).

I am curious. Stephen Connolly implied in his post that files
referenced by the .MSI database are either store in .CAB files
internal to the .MSI or stored in some directory structure that is
external and available to the installation procedure during
installation.

But, by given the 1st link above, you seem to imply that it is,
indeed, possible to swap out a file that is actually inside the .MSI
and not in a .CAB. Is this true?

I guess the matter comes down to this:

Is it or is it not true that any file that is internal to a
monolithic, singular, .MSI package necessarily stored in .CAB format?

-Le Chaud Lapin-

Dennis Bareis

unread,
Jan 30, 2008, 1:57:33 AM1/30/08
to
Hi,

On Tue, 29 Jan 2008 10:51:53 -0800 (PST), Le Chaud Lapin <jaibu...@gmail.com> wrote:

>
>It does not say *which API function* that a Tool Maker would use to
>add files to the database during the building/construction/compilation/
>synthesis [choose your favor word] of that .MSI database.
>

>What API function is used to build not the reference in the tables,
>which I clearly see how to do, but to put the files in the .MSI.
>

>What is "ZZZ" ? What API puts the file in the .MSI bundle?

There is NO API to add a file into the MSI, there are APIs to manipulate the rows/columns in the table and streams.

That is why its difficult, some tools will decide to have a "CABS" table that they will populate with compressed files
another tool may decide to have a table called "FRED". I use "MAKEMSI_CABS".

I don't like this either but they have made the process really hard and the documentation assumes you are
already an expert and just need the occassional hint. And you wouldn't want any examples in there either,
that would be too easy :-)

It took me ages to work it out and many times I'd reread a sentence orpage 20-50 times to try to work out what
they could possibly be meaning. That is why I and others point you at tools.

Now for my MAKEMSI tool, which you don't have to use :-)
I started creating a "Windows Installer Basicis" section which may help you understand some parts, its
a work in progress as origiginally I referred users to the SDK but decided, I'd put the basics in my manual:

http://makemsi-manual.dennisbareis.com/windows_installer_basics.htm


Now if you did use MAKEMSI to learn how to do things the ".dbg.txt" file will tell you what table manipulations
it did to add a file to the MSI..

Hope that helps,
Dennis
Dennis Bareis [Microsoft MVP] (dba...@KillSpam.gmail.com)
http://dennisbareis.com/
Freeware Windows Installer creation tool (+ "ORCA automation"):
http://makemsi.dennisbareis.com/

Stephen Connolly

unread,
Jan 30, 2008, 4:41:27 AM1/30/08
to
That is indeed the case. If it's a payload file embedded in the MSI
package, then it must be embedded in a .cab inside the _streams table.
This is the case even for merge modules that contain only a few files.

As for the external structure of the payload, that's down to you to
create it yourself so that the MSI can reference it.

I was also about to suggest that if your install was very small, you
could even stream the source directory structure from the binary table
and create the source image on the fly, but that probably wouldn't
work for installs from CD ROM and you'd really be pushing MSI to its
limits. In any case, I think you've seen that it wouldn't be a good
idea :)

Stephen

Le Chaud Lapin

unread,
Jan 30, 2008, 10:01:48 AM1/30/08
to
On Jan 30, 12:57 am, Dennis Bareis <dbar...@newsgroups.nospam> wrote:
> There is NO API to add a file into the MSI, there are APIs to manipulate the rows/columns in the table and streams.

Good Morning Dennis. :)

> That is why its difficult, some tools will decide to have a "CABS" table that they will populate with compressed files
> another tool may decide to have a table called "FRED".  I use "MAKEMSI_CABS".
>
> I don't like this either but they have made the process really hard and the documentation assumes you are
> already an expert and just need the occassional hint.  And you wouldn't want any examples in there either,
> that would be too easy :-)
>
> It took me ages to work it out and many times I'd reread a sentence orpage 20-50 times to try to work out what
> they could possibly be meaning.  That is why I and others point you at tools.

I read a bit of the blog that Chris Painter gave in the 2nd message in
this thread, and there seem to be a lot of people who think that the
writing is "wordy". Microsoft, if you are reading this, your
documentation in this area is even worse that the 1995 documentation
on the Windows shell. The biggest problem with this documentation,
IMO, is that the person who is writing is is does not seem to have a
clue that s/he is writing to another engineer. It's as almost as if
the writer is talking to himself, off in his own world.

For the record, Microsoft, a lot of us will immediately *get* the idea
of using tables and inter-table references. One thing that _any_
completely newbie will want to know immediately is what happens during
the packing process, meaning, how does the meat of FOO1.BIN get into
FOO.MSI. As of today, after reading through all your documentation, I
still do not know.

It's like giving a presentation on a new type of nuclear weapon, and
as the audience waits hours and hours to know what is ithe material
used for the explosive...but the presenter talks about everything
else, like radiation fall-out, electronics, safety procedures...it's
enough to drive someone mad!

So! That settles it. In a nutshell:

The files (not binary blobs) of an .MSI package are necessarily packed
into .CABs. If they need to be "free", they would have to be stored in
a directory structure, that will ultimately exist alongside the .MSI,
whereby references to the files in the directory will exist in the
tables of the .MSI. So monolithic means .CAB is a necessity, in which
cases, references still exist from the tables into the .CABs. And
there are limitations on naming and count in the .CAB (that part was
clear in the docs).

And...drum roll please.... the function that would have saved me 28
hours of lamenting about this, would have been the above paragraph
(with essentially Stephen Connolly wrote), and the function...

FCIAddFile!!!

> Now for my MAKEMSI tool, which you don't have to use :-)
> I started creating a "Windows Installer Basicis" section which may help you understand some parts, its
> a work in progress as origiginally I referred users to the SDK but decided, I'd put the basics in my manual:
>
>      http://makemsi-manual.dennisbareis.com/windows_installer_basics.htm
>
> Now if you did use MAKEMSI to learn how to do things the ".dbg.txt" file will tell you what table manipulations
> it did to add a file to the MSI..

I will take a look. Since I think I can manage on my own now.

I cannot express how important it is, Microsoft, to explain to an
"outsider" better the nature of the packing process, and by this, not
information about references that need to be made, but how 1 file gets
bound into the .MSI. The documentation that implies that .CAB must be
used for monolithic .MSI if no external files are to be allowed is
simply horrible.

Note: this fact/concept/whatever is one of the 1st things that an
outsider will want to know.

You also might want to put a one-sentence explanation at the beginning
of the documentation that by "tables", you mean relational database
tables. Yes, yes, it becomes obvious when you spend 3 days reading
the documenation and finally get to a function that has embedded SQL
statements in it and wonder why .MSI technology has SQL statements in
it, but the whole experience is so much more pleasurable if you do not
assume that the newbie knows what's in your head.

Much thanks all,

-Le Chaud Lapin-

Phil Wilson

unread,
Jan 30, 2008, 3:53:04 PM1/30/08
to
But you previously said that were interested only in uncompressed files, so
why do you now trumpet about FCIAddfile, a call that adds a file into a CAB
file, which is not uncompressed files at all???

In any event that API is not an MSI API - it's what anyone uses if they
want to create CAB files. MSI juat happens to use cab files (as do other
things) when building a compressed image or an image where the files are
external but in a cab. Uncompressed is when there are no cab files at all.


--
Phil Wilson
[MVP Windows Installer]

"Le Chaud Lapin" <jaibu...@gmail.com> wrote in message
news:ad939d41-a705-4517...@d4g2000prg.googlegroups.com...

Le Chaud Lapin

unread,
Jan 30, 2008, 6:06:17 PM1/30/08
to phli...@yahoo.com
On Jan 30, 2:53 pm, "Phil Wilson"

<phil.wil...@wonderware.something.com> wrote:
> But you previously said that were interested only in uncompressed files, so
> why do you now trumpet about FCIAddfile, a call that adds a file into a CAB
> file, which is not uncompressed files at all???

Because now I had context, whereas before, I did not.

That is the essence of my OP. I kept trying to basically say...

1. I am not dumb.
2. I am not inexperienced in software engineering.
3. You, the experts in this group I mean, are not dumb.
4. You, the experts in this group I mean, are not inexperienced in
software engineering.
5. You, the experts in this group know the Windows Installer thought-
space.

Therefore, it would seem that, even if I do not use the right
terminology, or ask for the right thing, the *essence* of what I am
asking for should have been clear, based on the number of message
published in this thread. I count the message I am typing right now
to be message #21.

Said another way, if a person comes to me, say, another electrical
engineer, who happens to be ignorant on a particular aspect of
electrical engineering and is stuck, there is no way it would take the
amount of communication we currently have present for me to:

1. figure out what it is he wants
2. communicate that to him quite efficiently

What I would *NOT* do is say...

1. "Oh....digital signal processing is not for the faint of heart..."
2. "You do realize there is a 900-page manual on techniques of
digitall signal processing..."
3. "Yes, yes, I know you want to make a circuit, but there are already
some made. Might cost $2000 for the schematics, but it is well worth
it. You should stop doing what you are trying to do and get that
instead and study it."

I especially would not say anything if the person has already read
say, 100 pages of that 900 page manual, and is stuck on a very
particular issue, which should be apparent to another expert reading
his (perhaps incorrect) communication.

> In any event that API  is not an MSI API - it's what anyone uses if they
> want to create CAB files.  MSI juat happens to use cab files (as do other
> things) when building a compressed image or an image where the files are
> external but in a cab. Uncompressed is when there are no cab files at all.

Oh trust me, I KNOOOOOOWWWW that know. More importantly, if another
neophye like myself, with similar experience in software development
on Microsoft Windows, even dares come into this group asking question
like, "How do FOOx.BIN's get packaged together to form the ultimate
FOO.MSI", I am confident that I can project into that person's mind
that:

1. If you want a monolithic, no side-kick .MSI package, you _have_ to
stream in a CAB containing the FOOx.BIN's.
2. If you choose to have not the .CAB method, the the files will have
to automagically exist alongside the .MSI at installation time,
conforming to a hiearchical structure that is implicit in the
distribution of references inside the .MSI.

I am confident that I can project this knowledge in 2 or 3 paragraphs
and be done with it.

What is also remarkable about this thread is that my OP explicitly
implied that I was not interested in being told something like,
"Windows Installer technology is not for the faint of heart."

I know you experts do not mean to insult us, but to be frank, it is a
bit insulting when reserve information that is more or less factual in
nature while telling us "it's not for the faint of heart". It's
alsmost as if you are presuming that we do not know what we are
getting ourselves into.


Here is a link of a thread that has the same title that I was going to
use for my OP, but decided not to use the word "Add" because I wanted
to preempt anyone telling me, "You don't 'Add' a file after it has
been put in". It is written by someone named Philip in 2003, with whom
I have no association.

http://tinyurl.com/2sxrzx

Notice the remarkable similarity between the answers he gets and the
answers I got:

>Dennis Bareis wrote:
>> The gist of it is adding a file to an MSI is not a simple thing. I
>> suggested MAKEMSI as a much easier alternative to adding the file via
>> "the API".

Look at his original post. His thought pattern is almost identical to
mine. He's basically saying he's not interested in all the rift raft,
that he understands MsiOpenDatabase, etc...but the documentation is
weird, and people keep sending him to the Internet to study entire
packages, which he is not interested in, at least not yet:

>I have Googled relentlessly for this question, and have either found
>short examples that don't show how to do it, or very long examples
t>hat show how to build a complete MSI, in confusing detail.

>Given an MSI file and a binary file (to become the installed
>application's private data), how do I insert the binary into the MSI?

>This may have something to do with MSI.DLL methods such as
>OpenDatabase, OpenView, SetStream, Execute, CreateRecord, etc., right?

>Thanks for any help finding the >simplest< complete example code
>showing this one action!

Notice this last sentence. He's basically saying, "Please, please,
cut to the chase. I'm not an idiot, just ignorant on very particular
part."

Here is the part where he is trying in vain to make a request so
simple that the answer *HAS* to be the one he wants. Not!:

>"Given MyApp.msi, and file.txt, what would the command line look like to push it in? "

This is where he, like I, start to become midly hysterical, because he
knows he is not dumb, and he knows what he is trying to say, but there
is a communication breakdown somewhere, and it frustrates him that the
person who is helping him will not take control and make things right:

> Dennis, you have noticed by now I am retarded.
> The page you linked does not say how to add a file; it says how to change a
> property.
> What is the command, with MAKEMSI, or ORCA, or WiImport.vbs, to add a file?

Here is the part where he has learned to basically educate himself:

> So, part of recovering from this dismay was abandoning my attempt to
> programmatically add product files to MSI files. Apologies for thinking they
> could have been architected like sentient ZIP files.

Note: this last paragraph, this is his work, his thinking, not that of
the person helping him. He had to learn the hard way.

And finally, there is the part where you realize that he is not
stupid, not entirely mistracked on what it is he wants. He obviously
knows how to write lexical analyzers:

>So, here's my narrow technical solution to this situation: I wrote a parser
>(using lean & robust Test Driven Development, natch) that converts VDPROJs
>into in-memory data structures in C++. Now I manipulate those structures,
>write back correct VDPROJ format, and feed this into devenv.exe.

>So, essentially as a by-product of this effort, I can add files on the fly;
>just before the MSI assembly process. This solution is sustainable for
>uncomplicated MSIs; it meshes with my colleagues' abilities and development
>environments, and I can run sanity checks on the MSIs before they go out the
>door.

Just took a look at link on his site. He has knowledge of ray-tracing,
vector graphics, fractals and complex numbers, and CPP, and probably
other things. So this person is not dumb, and his diction is not that
bad either.

I normally would not put so much effort into a post, but I did this
time because this pattern seems to be endemic to this group. This is
not the only post where I see people, some with deep experience in
Windows area, asking what would be a trivial question to a colleauge,
being lead by the nose in circles.

I realize that no one here is doing this purposely, but it is
*perceived* that way.

The next time an experienced engineer asks, "How do I add FOO.TXT to
FOO.MSI", you should be able to set them straight in one or two
paragraphs. For that matter, if a person does not even know
that .MSI's are based on relationasl databases, you should be able to
set them straight in 4 simple paragraphs, which would take, what 3
minutes, versus days for the MSDN docs?

Please do not make any references to .MSI installer being complex or
not being for the faint of heart or anything like that. Just pretend
that the person asking is someone of Philip's background, understand
what it is they want, and then tell them. They just might get it.

[Off my soapbox now.]

-Le Chaud Lapin-

Daniel Levin

unread,
Jan 31, 2008, 2:44:21 AM1/31/08
to
In article <5792aa59-7631-4e80-b085-
c5b3a2...@j78g2000hsd.googlegroups.com>, jaibu...@gmail.com says...

> On Jan 30, 2:53 pm, "Phil Wilson"
> <phil.wil...@wonderware.something.com> wrote:
> > But you previously said that were interested only in uncompressed files, so
> > why do you now trumpet about FCIAddfile, a call that adds a file into a CAB
> > file, which is not uncompressed files at all???
>
> Because now I had context, whereas before, I did not.
>
> That is the essence of my OP. I kept trying to basically say...
>
> 1. I am not dumb.
> 2. I am not inexperienced in software engineering.

Well, one thing you cannot say is "I am not a whiner"

Exhibit A:

(Your posts in this thread)

Exhibit B:

http://groups.google.com/group/microsoft.public.virtualpc/browse_thread/
thread/c272190f504ab038/29bf0fcf07b7aec6?#29bf0fcf07b7aec6


> 5. You, the experts in this group know the Windows Installer thought-
> space.
>
> Therefore, it would seem that, even if I do not use the right
> terminology, or ask for the right thing, the *essence* of what I am
> asking for should have been clear, based on the number of message
> published in this thread. I count the message I am typing right now
> to be message #21.

In defense of Christopher, Phil, and Dennis, I think their responses to
you were perfectly reasonable, given the knowledge and terminology gap
between you and them, and your silly "preemptive whining."

In the end, you learned something valuable, and you crossed that
knowledge gap. Congratulations on your monumental achievement. I am
happy for you.

I must protest, however, that you now appear to be whining that "the
experts in this group" should have been able to figure out what a newbie
like yourself was asking. You are in essence, arguing that the
"experts" should be able to come down to the level of, and understand
"newbiespeak."

However, in the above link, you complained on microsoft.public.virtualpc
that you, a self-proclaimed "network expert" could not figure out which
Virtual PC networking option would connect your VMs to the Internet,
even though it was *clearly defined*. Someone responded incredulously,
asking you:

> How vague can it be when it correctly spells out exactly what will
> happen when you select any of the available optionsin the network
> dialogue?

You replied that Microsoft's VPC documentation was "meaningless to an
expert" (specifically: you). It was written for ordinary IT monkeys who
would be installing VPC. So in that situation, you were an "expert" who
was unable to come down to the level of, and understand "newbiespeak."
Their documentation was clearly understandable by newbies.

You should have a greater appreciation of the communications gap between
expert and newbie, now that you have had a taste on both sides.

Le Chaud Lapin

unread,
Jan 31, 2008, 3:32:34 AM1/31/08
to
On Jan 31, 1:44 am, Daniel Levin <dlev...@sbcglobal.net> wrote:
> In defense of Christopher, Phil, and Dennis, I think their responses to
> you were perfectly reasonable, given the knowledge and terminology gap
> between you and them, and your silly "preemptive whining."

You mean "lamenting" which I wrote. In any case, it was accurate. I
did take roughly 15 messages to get what I was after, when Stephen
Connolly made his replay.

> In the end, you learned something valuable, and you crossed that
> knowledge gap. Congratulations on your monumental achievement. I am
> happy for you.

No, I learned nothing "valuable". I don't know if it is valuable yet
(FCIAddFile, I mean). I have not tried it because I had to wait 28
hours to get to where I needed to be.

> I must protest, however, that you now appear to be whining that "the
> experts in this group" should have been able to figure out what a newbie
> like yourself was asking. You are in essence, arguing that the
> "experts" should be able to come down to the level of, and understand
> "newbiespeak."

Well, yes. Anytime a person gives instruction of any kind, s/he could
consider audiences. Having been an instructor myself, both formally,
and informally, I usually consider audience. I certainly would not
have had trouble figuring out what was being asked for if someone else
had written what I wrote and I had been the one with the insight. In
fact, someone else effectively did, 5 years ago in 2003, as I
mentioned. While the wording between our posts are different, the
frustration is the same. And looking at the guy's web site, he's no
dummy, so there is a breach in communication somewhere.


> However, in the above link, you complained on microsoft.public.virtualpc
> that you, a self-proclaimed "network expert" could not figure out which
> Virtual PC networking option would connect your VMs to the Internet,
> even though it was *clearly defined*. Someone responded incredulously,
> asking you:

> > How vague can it be when it correctly spells out exactly what will
> > happen when you select any of the available optionsin the network
> > dialogue?

That problem turned out to be a bug in VPC.

> You replied that Microsoft's VPC documentation was "meaningless to an
> expert" (specifically: you). It was written for ordinary IT monkeys who
> would be installing VPC. So in that situation, you were an "expert" who
> was unable to come down to the level of, and understand "newbiespeak."
> Their documentation was clearly understandable by newbies.
>
> You should have a greater appreciation of the communications gap between
> expert and newbie, now that you have had a taste on both sides.

Don't know what you mean by this. In both cases, I was the one asking
the question.

As far as me giving newbie's advice on things I understand, I
generally consider my audience before responding. My response to
questions about electrodynamics, for example, would differ
significantly depending on whether I am explaining to a 10-year-old or
to my professor, who had multiple Ph.D's. In the former case, I would
tread lightly, perhaps using analogies. In the latter case, I could
speak as fast as human possible using jargon in full-glory and never
come remotely close to overloading his mind. It is the role of the
responder to consider where the recipient of the response lies in this
spectrum. That generally only takes a few seconds, and when you have a
situation where the person receiving the information has deep
knowledge of that which surrounds that which ins being asked about (C+
+, DLL's, databases, the registry), it is even more important to
consider what it is that person wants.

One thing I would never do is to is begin by telling someone who is
competent as a software engineer who approaches as a newbie and ask
something specific about XYZ technology, "XYZ is not for the faint of
heart", especially after that person has preemptively asked that I not
respond in that manner.

-Le Chaud Lapin-

Phil Wilson

unread,
Jan 31, 2008, 4:47:02 PM1/31/08
to
As it's a slow day, I did a bit of counting. My estimation is that the first
few posts contain around 1750 words of lament, and 284 words that could
possibly be classified as actual technical content, much of which was
repetitive "I want to replace this with that in an MSI file". It would
have really helped if more information could have been supplied instead of
lamentation.

--
Phil Wilson
[MVP Windows Installer]


"Daniel Levin" <dle...@sbcglobal.net> wrote in message
news:MPG.220b37fc1...@news-server.austin.rr.com...

Le Chaud Lapin

unread,
Jan 31, 2008, 5:07:44 PM1/31/08
to
On Jan 31, 3:47 pm, "Phil Wilson"

<phil.wil...@wonderware.something.com> wrote:
> As it's a slow day, I did a bit of counting. My estimation is that the first
> few posts contain around 1750 words of lament, and 284 words that could
> possibly be classified as actual technical content, much of which was
> repetitive "I want to replace this with that in an MSI file".    It would
> have really helped if more information could have been supplied instead of
> lamentation.

The lamentation would have probably been absent if I had not read
similar posts in this group over the last 10 years of relatively
competent engineers asking specific questions and being essentially
told "Windows Installer Technology is not for the faint of heart...try
my tool..go study this open source whatever..."

-Le Chaud Lapin-

Reply all
Reply to author
Forward
0 new messages