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

Reply via email to