On 2018/11/01 9:51 AM, Graham Hardman wrote:
I am pleased about this, although still puzzled by the fact that the
windows LoadLibrary call returned a non null pointer and windows help
file implies that it is ok for multiple copies of same name libraries
to be loaded together.
This is an old Windows problem, one which I think they (M$) have
self-regretted so many times. What I deduced long ago after resolving a
similar problem (and I could be wrong, I don't have insider info on it)
is that Windows' idea of DLLs was to have it so the DLLs live in a
common area in the Windows system path (typically
c:\program files\common files\system) from where it can be shared to all
the lovely apps everywhere needing to use it. AND, how wonderful would
it be if, when a DLL is updated, everyone benefits from the new version.
Right?
So what they did is the DLL loader seems to have a rule of loading the
DLL FIRST from the windows common DLL area, and only if not available
there (because that's where the updatedest DLL would be, right?) then
see if local DLL exists next to the app and loads it.
Most applications play nice and do not install their greasy little DLLs
to the Widows DLL common area, but just hug them locally (in the app
folder). But some, thinking probably they were doing the right thing, do
install DLLs to the common area, and sometimes this includes a DLL like
sqlite3.dll which starts causing problems for everyone else using it,
because they don't actually distribute/install newest versions, so
everything else loading the same library gets the last installed version
of the last app to successfully install to the common area.
Even this wouldn't be such a catastrophe if the common area DLLs weren't
usually "in use" by the services it supports, so it can't be updated by
anyone else, unless you KNOW which service(s) is/are using it and stop
all of them.
This leaves a new application install with very few options, if you
can't get Windows to use your local DLL, nor can you update the "in-use"
one in the common area... How then do you cause the system to use your
newest DLL? There are a few hacky ways:
1 - The easiest is to just use a different name (and to do your part by
not installing it for all).
2 - Use a side-by-side isolation assembly.
See:
https://docs.microsoft.com/en-us/windows/desktop/SbsCs/isolated-applications-and-side-by-side-assemblies-portal
This option is fine if you develop new software to be isolated from
any DLL conflicts from the start, but it's a LOT of effort to just fix
one conflict.
3 - This is my favourite - Use DLL redirection, which involves simply
adding a .local file to your app path (so myapp.exe must be accompanied
by myapp.local).
This does require and extra file to maintain, but it's relatively
easy and means you don't need to be concerned with sorting out DLL
naming or isolation.
I believe the file's presence matters, but its content is
irrelevant (I usually add a line like "** Force local DLLs **" as the
content), which makes Widows look locally first when loading DLLs.
See:
https://docs.microsoft.com/en-us/windows/desktop/dlls/dynamic-link-library-redirection
NB! - The .local file will force local redirection for ALL DLLs you use,
some of which may not be intended, like if you supply xxx.dll as a
back-up, but would prefer Windows to use it's internal (and possibly
newer) xxx.dll if present.
NB2! - As is the standard for M$, every fix must have a fallback... so
known common DLLs cannot be redirected like this (there is a list
maintained in the Windows registry in
HKLM/SYSTEM/CurrentControlSet/Control/Session Manager/KnownDLLs/ of what
Windows regards as "common" DLLs. Make sure your DLL is not in there,
for if it is, options 1 & 2 above are your only remaining venues).
HTH - Cheers!
Ryan
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users