I am using pinvoke from a .NET (C#) dll to call into a native dll. Now I would like to compile my .NET dll as "AnyCPU" but when "pinvoking", I must know, whether I have to call into the 32 or 64 bit dll. I install both versions of the native dlls into the subfolder bin32 and bin64. Now when my DLL gets loaded, I would like to check, whether we are in 32 or 64 bit mode and call SetDllDirectory with the appropriate path. There seems to be no problem with this approach, except for a good "entrypoint" from where to call SetDllDirectory. In native DLLs there is a DllMain entry, which gets called, when the DLL is attached to a process. Is there some similar entrypoint in a .NET DLL? Do you think, dynamically calling SetDllDirectory is a good idea?
.NET does have the equivalent of a DllMain() function, it is called a module initializer. It is however out of reach from C# and VB.NET code, you can only create one in IL or in C++/CLI. C++/CLI itself has a bitness dependency so that only leaves IL. You'll find sample code for one in this answer. Getting it linked into your assembly is pretty awkward, the build system doesn't directly support running the assembly linker.
Next best thing is a "type initializer" as mentioned in the same article, called a static constructor in C#. You do need some semblance of organization in your code to make these pay off, a class that's guaranteed to get used before one of your 'thousands of methods' get called. That ought to be difficult with that many methods.
That doesn't leave much beyond an initialization method that has to be called by the app in its Main() method. And of course the standard solution, two installers, one for 32-bit machines, another for 64-bit machines. Which also ensures your app ends up in the 'right' directory, c:\program files vs c:\program files (x86).
UPDATE: .NET 5 now supports module initializers in C# v9 with the [ModuleInitializer] attribute