Directory.EnumerateFiles和File.Exists忽略本机DLL文件(Directory.EnumerateFiles and File.Exists are ignoring native DLL files)

环境:C#,.NET 4.0和混合模式。

我有一个复杂的应用程序与几个第三方依赖项。 当我们收到一些关于应用程序崩溃的报告时,我们添加了一些健全性检查,以确保通过遍历程序集依赖关系来存在所有依赖项。 不幸的是,这不会检查我们的应用程序使用的本机DLL文件是否存在。 我们的预期解决方案是遍历所有DLL名称,并确保至少有一个具有该名称的文件作为完整性检查。

问题

Directory.EnumerateFiles()和File.Exists()都无法看到这些本机DLL。 重现此问题的代码就像教科书“如何列出文件”一样简单:

foreach(string file in Directory.EnumerateFiles(Environment.CurrentDirectory, "*.dll")) { string entry = Path.GetFileName(file); if (! RequiredFiles.Contains(entry)) { /* Do error handling */ } }

盯着我列出文件的目录,我可以看到我想要检测的文件。 它们不会以任何方式标记为系统文件。 然而,无论我是否有过滤文本,都只列出了.NET DLL文件。 我想更直接地重写代码部分并且令人沮丧地得到了相同的结果:

foreach(string dependency in RequiredFiles) { string fileName = Environment.CurrentDirectory + '\\' + dependency; if(! File.Exists(fileName)) { /* do error handling */ } }

我得到了完全相同的结果。 所有本机DLL文件似乎都是.NET不可见的。

是什么导致这个? 更重要的是,如果我甚至无法在文件系统中看到它们,如何检测本机DLL文件?

Environment: C#, .NET 4.0, and mixed mode.

I have a complex application with several third-party dependencies. When we received some reports of the application crashing we added some sanity checks to ensure that all the dependencies exist by traversing the Assembly dependencies. Unfortunately, this does not check for the existence of the native DLL files our application uses. Our intended solution is to iterate through all the DLL names and make sure there is at least a file with that name as a sanity check.

The Problem

Both Directory.EnumerateFiles() and File.Exists() cannot see these native DLLs either. Code to reproduce this problem is as simple as the textbook "how to list files":

foreach(string file in Directory.EnumerateFiles(Environment.CurrentDirectory, "*.dll")) { string entry = Path.GetFileName(file); if (! RequiredFiles.Contains(entry)) { /* Do error handling */ } }

Staring in the directory I was listing the files on, I could see the files I wanted to detect. They are not flagged as system files in any way. Yet, whether I had the filter text or not, only .NET DLL files were listed. I thought to rewrite the section of code more directly and frustratingly got the same results:

foreach(string dependency in RequiredFiles) { string fileName = Environment.CurrentDirectory + '\\' + dependency; if(! File.Exists(fileName)) { /* do error handling */ } }

I got the same exact results. All the native DLL files seemed to be invisible to .NET.

Question

What causes this? And more importantly, how can I detect the native DLL files exist if I can't even see them in the file system?

最满意答案

为您自己的DLL组成一个名称,例如MySuperNiftyLibrary.dll。 它可以只是一个重命名的文本文件。 把它放在你正在看的文件夹中。 再次运行代码。 查看是否列出了该名称。 如果这不能说服您,请创建一个具有独特名称的小型.NET类库项目,并将其放在目录中。

Directory.EnumerateFiles没有理由过滤.NET DLL而不是其他类型的DLL,因此您无法查看正确的目录。

但如果您是,请考虑您要查找的DLL是在顶级目录还是子目录中。 默认情况下, EnumerateFiles仅列出顶级目录中的文件 。 要列出所有子目录中的所有文件,您需要使用EnumerateFiles这个重载:

Directory.EnumerateFiles(directory, "*.dll", SearchOption.AllDirectories)

Make up a name for your own DLL, e.g. MySuperNiftyLibrary.dll. It can be just a renamed text file. Put it in the folder you're looking at. Run the code again. See if that name is listed. If that doesn't convince you, create a small .NET class library project with a distinctive name, and put that in the directory as well.

There's no reason Directory.EnumerateFiles would filter on .NET DLLs as opposed to other types of DLLs, so you can't possibly be looking at the right directory.

But if you are, then consider whether the DLLs you're looking for are in the top-level directory or a subdirectory. By default, EnumerateFiles only lists files in the top-level directory. To list all files in all subdirectories, you need to use this overload of EnumerateFiles:

Directory.EnumerateFiles(directory, "*.dll", SearchOption.AllDirectories)

更多推荐