Directory.EnumerateFiles and File.Exists ignore DLL files

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 dependencies exist by crossing the assembly dependencies. Unfortunately, this does not check for the existence of native DLL files that our application uses. Our intentional solution is to iterate over all the DLL names and make sure that there is at least a file with that name as a health check.

Problem

Both Directory.EnumerateFiles () and File.Exists () also cannot see these native DLLs. The code for reproducing this problem is as simple as the How to List Files tutorial:

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

Being in the directory in which I listed the files, I could see the files that I wanted to detect. They are not marked as system files. However, whether I had filter text or not, only .NET DLL files were listed. I thought to rewrite the code section more directly and disappointingly received the same results:

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

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

Question

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

+4
source share
3 answers
  • Make a name for your own DLL, for example. MySuperNiftyLibrary.dll. It could just be a renamed text file. Put it in the folder you are looking at. Run the code again. See if this name is indicated. If this does not convince you, create a small .NET class library project with a distinguished name and place it in a directory.

    There is no reason why Directory.EnumerateFiles will filter on the .NET DLL and not on other types of DLLs, so you cannot look in the right directory.

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

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

+2
source

Are you sure your working directory is correct? Otherwise, Environment.CurrentDirectory will not indicate what you expect. If the DLLs are in the same directory as your executable code, then you can:

 Assembly.GetExecutingAssembly().Location 
+2
source

Then use a shell, something like this should work:

  Shell32.Shell shl = null; Shell32.Folder folder = null; try { shl = new Shell32.Shell(); folder = shl.NameSpace(Environment.CurrentDirectory); foreach (Shell32.FolderItem file in folder.Items()) { if (!RequiredFiles.Contains(file.path)) {/* do error handling */} } } catch { } finally { if (folder != null) { System.Runtime.InteropServices.Marshal.FinalReleaseComObject(folder); folder = null; } if (shl != null) { System.Runtime.InteropServices.Marshal.FinalReleaseComObject(shl); shl = null; } } 

UPDATE: if you intend to use this both in XP and in new OSs, you need to access Shell32.dll (Microsoft Shell management and automation tools) on XP and compile it once so that such a DLL is copied to your project. Because the dll from Vista or 7 will not work on XP, but vice versa. This is a simpler shell scripting approach. Otherwise, you can interact directly with the Shell API, but it's more complicated ...

0
source

Source: https://habr.com/ru/post/1395661/


All Articles