Do you know the feature of decompile switch?
Michael wrote:
I saw you at the Microsoft Seminar earlier this month in Perth,
which was very useful thanks. If you have time I do have a
question.
You probably won't remember but I asked you in the break about
copying and pasting reports and forms in Access 97 causing Access
to perform an illegal operation and 'hang' next time you opened
it. Your reply was to use the "/decompile" switch in the command
line. Not only has this worked extremely well but it reduced the
file size from 8Mb (a lot of code in this database) to 4Mb.
However, I can find no information at all anywhere about decompile
either in the Access Help, Knowledge Bases or anywhere on the
Microsoft web site. Maybe its there, but I can't find
it.
My concern is that the message you get after decompiling is
something like "Access has upgraded your code to the version of
Visual Basic on your system", and I'm worried that if I distribute
my database to end users (either 'as is' or as a setup with
runtime Access) that if they don't have MS Office SR1 and SR2 or
the Jet SR pack or whatever else I might knowingly or
inadvertently have on my computer, will that cause a
problem? In other words, what does "the version of Visual Basic on
your system" really mean and is there any danger to using this
apparently undocumented decompile feature, particularly regarding
distribution of the end result?
If you have a minute to answer or point to a resource
(Access 97 Developers Handbook, Litwin/Getz/Gilbert doesn't
appear to mention it either) I would be very grateful.
Thank you.
Michael.
Adam Answered:
This is an undocumented feature. Here is real deal on the
/Decompile switch (Originally posted 5/22/99 by Michael Kaplan)
This post is to give a little historical background and info on
this undocumented command line switch in msaccess.exe.
To use it, you simply run:
msaccess /decompile <your database name>
and that's all there is to it. But what exactly does it do?????
VBA AND THE 11 STATES OF COMPILATION
That's right, internally there are 11 different compilation levels
between decompiled and fully compiled like you would find in an
MDE. As you make objects dirty, you will decompile the project,
but dirtying Module1 does not remove all the "compiled" info about
Module2 or Form1, for example. The exact levels are impossible to
even detect unless you have source and debugging symbols for VBA,
and insanely difficult even then.... so lets just leave it as read
that the yes/no question of "is it compiled?" has many
subcategories under the NO answer that essentially mean its not
compiled but some parts of it are kind of.
P-CODE VERSUS CANONICAL TEXT
Your code is stored in two forms, each one of which is a Stream
object in the project's storage(s). One form is the canonical text
that you look at and edit and such, the other is the compiled
version of the code that runs.
VBA must always compile before it runs, so in an app that runs you
will always find p-code. And unless you are running in an MDE
(where the canonical code is stripped out) you will always have
the canonical text too. Any time VBA thinks that the
compiled code is invalid (such as when you make a change or the
binary format changes, which is so far only during beta cycles),
it will "decompile" the module and then compile it again from the
canonical text.
ACCESS BETAS: BINARY FORMATS, ETC.
People who were on the betas for Access 95, 97, and/or 2000 will
remember the binary format issues. From build to build, changes
would be made in VBA or in the Access OM which would make old
compiled code invalid. Usually a crash is the best you could
expect. To help fix this, some work was done to have a global way
to decompile *ALL* code that is present in a project so that you
do not risk having any invalid code that might crash.
**********
This is the reason the flag is there and the only reason. The
command line switch is undocumented because there is never a
binary format change except during betas and in internal
builds.... so there is no reason to document something never
intended to be used.
**********
NOW there are some positive benefits that are side effects that
people have made use of:
1) SIDE EFFECT: CORRUPTED PROJECTS
Now, as a side effect, you have a way to deal with corrupt
projects! You see, the canonical text is never what is corrupted,
it is always some compiled portion of a project, like a module or
most commonly the typeinfo of a form or report. By globally
telling Access that the compiled portion should be thrown away,
you get rid of whatever the bogus piece of code is.
Now this kind of fix is what would have taken care of the old
Access93 vba232 page faults and other problems where Access was
walking off the end of a vtable and crashing, as well as a zillion
other such little problems. This is what made PSS first expose
this flag for.... if a project is corrupted, this is the best way
to uncorrupt it.
2) SIDE EFFECT: PROJECT SIZE
It was found that there are times where an object would be
decompiled and while the Stream object from the storage would be
properly invalidated, it would be orphaned and left in the
Storage, and then would not be cleaned up later.
There are many applications that use structured storage that have
such a problem in their garbage collection... VBA/Access is just
one of them, that's all. Over time, these orphaned streams will
contribute some bloat to the project. People noticed that a fully
compiled app would take up more space than the same app fully
compiled with all objects imported to a new database..... and that
is the very issue being discussed here. As you may have guessed,
the /decompile switch, which invalidates *all* streams that
contain compiled code, does an effective job of garbage collection
and removes these orphaned streams. Thus, a /decompile /compact
will make for the smallest possible size of as database.
RISKS TO DECOMPILE: WHY YOU SHOULD NOT USE IT CONSTANTLY
If you think about the mechanism, you are relying on the canonical
text always being completely valid, and you are relying on the
ability to globally invalidate a compiled state. If there is ever
a problem in either area, /decompile will take a project that was
working fine and turn it into cottage cheese. And while such bugs
should not happen.... it is impossible to make a /decompile bug
happen without using /decompile. They simply did not extensively
test a command line switch that was never meant to be used.... nor
should they have to, really.
SO, PLEASE REMEMBER that this is a very powerful technique that
was added for reasons having nothing to do with any of the reasons
that you may want to use it now. It may help you save an otherwise
hopelessly corrupted project. But use it sparingly as you may end
up in a worse situation than you started by just globally using
the switch on projects that do not need it.
IF IT AIN'T BROKE, DON'T FIX IT.
Adam Cogan
Sydney, Australia
SSW
adamcogan@s*w.com.au