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