Firebird and MSVC8 run-time. Again
Vlad Horsun wrote on Firebird-Devel list
After reading MSDN articles about assemblies, side-by-side installation,
context activation API, etc, i think i have an idea how we can avoid (in most
cases) requirement to install MSVC8 runtime via Windows Installer and just
deploy it with our binaries.
I don’t know about all side-by-side assemblies, but MSVC8 run-time have
initialization code where it is checks its location against few rules.
Interesting (for us) rules is :
a) if correct activation context already exists then it is OK to load library
b) if dll’s folder have no correct manifest file then library will not load
In the past we tried to workaround rule (b) :
The original idea was that it is enough to put 2 dll’s and manifest file into \bin
folder of installed server. Unfortunately it was not enough because we have dll’s
in other folders (\intl and \udf) and they also need MSVC8 runtime to work. There
was 2 solutions for this issue. First, make copy of runtime dll’s in every place
where it is needed. And second, to make patched copy of manifest (pointing to \bin)
in this secondary places. First “solution” obvious bad as nobody want to deploy 3
copy of the same runtime. Second solution not worked at least on Windows 2003 Server
as loader complains about bad manifest structure.
Now, i hope, we can exploit rule (a).
When application loads some assembly it (application or loader – i don’t know)
creates in memory so-called activation context. This structure contains information
about assembly. There may be many contexts present in memory. They arranges as stack.
When MSVC8 runtime loaded it checks for existing context. My guess is that when runtime
is loaded second time by some dll (for example by fbintl.dll or udf.dll) then loader
detects embedded in library manifest and creates from it activation context (pointed
to dll’s folder). So, when second copy of runtime library checks for activation context
it found this new context which pointer not to the application’s folder (\bin) but to
the our dll’s folder (\intl or \udf). This folder have no manifest file and runtime
So, i offer to *not* embed manifest into our dll’s which loaded by server
process. In this case secondary copies of MSVC8 runtime (loaded by our dll’s)
will found activation context created by application and will load successfully.
I.e. we can deploy MSVC8 runtime dll’s and manifest file only in \bin folder.
I tried this on clean Windows 2003 Server installation and all was OK.
If my understanding correct, lets look at our binaries and decide which of them
still needs embedded manifest and which – not needs.
a) All .exe files – obvious they are need embedded manifest. They will load runtime
assembly from its own folder (\bin).
b) .dll files which loaded by Firebird : fbudf.dll, ib_udf.dll, ib_util.dll, fbintl.dll
This group needs no embedded manifest. They will “use” runtime assembly already
loaded by Firebird
c) fbclient.dll – we have no knowledge if host application will load MSVC8 runtime.
For example, Delphi application not used MSVC8 runtime. Therefore we must embed
manifest in fbclient.dll. I recommend (as one of possible options) to deploy fbclient
+ runtime files in the same folder as application or in separate folder (application
must be able to load fbclient.dll from that location)
d) fbembed.dll – the same as fbclient.dll
Of course, this also will work with correctly installed at SxS MSVC8 runtime.
In this case there is no needs in additional libraries in \bin (or application) folder.