32位进程不能加载64位Dll,64位进程也不可以加载32位Dll。Windows的系统目录包含了所有安装的应用程序和它们的Dll文件,根据我们所述的规则,它应该被分为给64位应用程序的目录和给32位应用程序的目录。如果不这样,我们就无法区分32位和64位的Dll文件。对于64位应用程序,其文件通常被放在%windir%\system32和%programfiles%(比如:c:\program files)。对于32位应用程序,其文件通常在%windir%\syswow64和C:\program files (x86)下面。
如果我们用32位程序去访问%windir%\system32,不管我们用硬编码还是其它的方式,系统都会自动地给我们转向到%windir%\syswow64下面。这种转向对于每个32位应用程序默认都是打开的。但是这种转向对于我们来说并不总是需要的。那么我们可以在C#里面调用相关的API来关闭和打开这种转向。
常用的函数有3个,Wow64DisableWow64FsRedirection(关闭系统转向),Wow64RevertWow64FsRedirection(打开系统转向),Wow64EnableWow64FsRedirection(打开系统转向)。但是Wow64EnableWow64FsRedirection在嵌套使用的时候不可靠,所以通常用上面的Wow64RevertWow64FsRedirection来打开文件系统转向功能。在C#中,我们可以利用DllImport直接调用这两个函数。
但是要注意到的是,在32位的Kernel.dll中是没有这两个函数的。那么在C++中应该使用LoadLibrary来动态加载这两个函数。否则会因为找不到这两个函数而无法通过编译。而且在目前的使用中,发现这两个函数有一个小小的问题。如果我们在调用了Wow64DisableWow64FsRedirection后去调用Comdlg32.dll的GetOpenFileName函数,是无法调用成功的。但是也得不到Error的值。