Which DLL is [DllImport] loading?

2019-04-28 20:04发布

I'm using the [DllImport] attribute to import a native DLL into my application but the DLL it's loading isn't in the local bin folder. It's being loaded from elsewhere on the system, but I can't work out where.

It works on my dev machine but not on a clean one.

I've enabled Fusion logging and that only shows me managed assemblies.

I've dumped the process using Sysinternals Process Explorer and that's telling me it's in C:\Windows\System32 but I can't see the file there in Windows Explorer.

It might be worth noting that I'm running 64 bit Windows 7 but the DLL only supports x86 so I've had to force my app do be x86. Is there some sort of redirect that changes where x86 files are loaded from?

The DllImport is a custom Silicon Labs USB driver. [DllImport("SiUSBXp.dll")]

I've also used the command prompt to do a dir si* in the System32 folder and the file isn't there.

4条回答
闹够了就滚
2楼-- · 2019-04-28 20:41

The actual source code behind DllImport is here:

https://github.com/gbarnett/shared-source-cli-2.0/blob/master/clr/src/vm/dllimport.cpp

As you can see, it first tries to find de unmanaged library in .Net's internal cache.

If that fails, but an absolute path is specified, it loads the library with that path.

If no absolute path is specified it looks in these locations:

1) The folder containing the manifest file of the assembly that contains the DllImport.

2) The folder specified in Assembly.CodeBase.

3) All the places where LoadLibraryExW looks.

If all that fails, it tries to interpret it as "filename, assemblyname".

Then it adds the library to its internal cache.

查看更多
再贱就再见
3楼-- · 2019-04-28 20:44

You want to read this - LoadLibrary function and, from that, you also want to read this Dynamic Link Library Search Order.

Note - these relate to a native Win32 API, but it is the one that's used by the [DllImport] attribute.

The file is possibly not showing in Explorer because you need to have Show All Files switched on - many common [DllImport] directives (e.g. kernel32) are targeting Win32 DLLs, which are classed as operating system files and are therefore hidden by default.

查看更多
男人必须洒脱
4楼-- · 2019-04-28 20:45

The File System Redirector will be kicking in:

The %windir%\System32 directory is reserved for 64-bit applications. Most DLL file names were not changed when 64-bit versions of the DLLs were created, so 32-bit versions of the DLLs are stored in a different directory. WOW64 hides this difference by using a file system redirector.

In most cases, whenever a 32-bit application attempts to access %windir%\System32, the access is redirected to %windir%\SysWOW64.

So even though the process thinks it loaded the DLL from System32, it probably loaded from SysWOW64 And yes, the numbers are the wrong way around from what you'd expect.

查看更多
一纸荒年 Trace。
5楼-- · 2019-04-28 20:53

DLLImport searches through the following paths:

  1. Currently loaded DLLs (if it's already loaded, there is no need to search the file)
  2. The directory of the executable module for the current process
  3. The current directory.
  4. "System" directory. (i.e. c:\Windows\System32)
  5. The "Windows" directory. (i.e. c:\Windows)
  6. The directories listed in the PATH environment variable.
查看更多
登录 后发表回答