none
File not found for existing file in system32 directory RRS feed

  • Question

  • I keep getting file not found when using File.Exists("c:\winows\system32\plasrv.exe") even though the file appears in the directory listing. This is a Windows 10 PC. I am using .Net 4.5, Visual Studio Pro 2013.

    I checked the permissions on the file. Everyone and all applications have Read and Read & Execute permissions.

    I checked the permissions on the directory path .Everyone and all applications have Read, List folder contents, and Read Execute permissions.

    I don't have a problem using the same call on other existing files in this directory.

    Is there another function I could use that would reliably determine if the file exists. This file might be an active service and thus require me to use another function?

    Friday, November 13, 2015 4:36 PM

Answers

  • Since Visual Studio 2012, C# application projects default to “Any CPU 32-bit preferred”. If you run such an executable on a 64-bit Windows operating system, then it will start as a 32-bit process and be affected by WOW64 file system redirection.

    When a 32-bit process on 64-bit Windows tries to access "C:\Windows\System32", WOW64 redirects it to "C:\Windows\SysWOW64". There are several ways to access the real "C:\Windows\System32" directory:

    • Use "C:\Windows\SysNative", which WOW64 redirects to "C:\Windows\System32" even though it does not appear in directory listings. This is an easy way and unlikely to cause problems.
    • Use Wow64DisableWow64FsRedirection and Wow64RevertWow64FsRedirection.
    • Use a 64-bit process.
    Friday, November 13, 2015 7:23 PM

All replies

  • >>Is there another function I could use that would reliably determine if the file exists.

    No, but you could for example use the File.OpenRead method and catch any exception to see what is actually happening when you try to read the file as suggested by Jon Skeet here: http://stackoverflow.com/questions/18266637/why-system-io-file-existsstring-path-returns-false

    The Exists method will return false if any error occurs while trying to determine if the specified file exists, for example due to permissions problems.

    Also make sure that you don't misspell the folder name. You are for example missing a "d" in the code you posted:

    File.Exists("c:\windows\system32\plasrv.exe") 

     

    Hope that helps.

    Please remember to close your threads by marking helpful posts as answer and then start a new thread if you have a new question. Please don't ask several questions in the same thread.

    Friday, November 13, 2015 4:45 PM
  • My laptop "D" keys takes more pressure than the other keys. The example I posted was missing the 'D' but the code wasn't.

    Tried the

    File.OpenRead("C:\\WINDOWS\\SYSTEM32\\PLASRV.EXE")

    and got :

    {"Could not find file 'C:\\WINDOWS\\SYSTEM32\\PLASRV.EXE'.":"C:\\WINDOWS\\SYSTEM32\\PLASRV.EXE"}

    Used cmd.exe and got:

    C:\dir c:\WINDOWS\SYSTEM32\PLASRV.EXE
     Volume in drive C is Windows7_OS
     Volume Serial Number is 7DA2-C800
     Directory of c:\WINDOWS\SYSTEM32

    07/10/2015  03:59 AM            10,240 plasrv.exe
                   1 File(s)         10,240 bytes
                   0 Dir(s)  347,532,959,744 bytes free

    Also tried GetFileAttributes and got the same results as File.OpenRead().


    Appears the problem is with EXEs in the system32 directory. DLLs are found.

    • Edited by OnTheBeach2 Friday, November 13, 2015 5:52 PM
    Friday, November 13, 2015 5:17 PM
  • Are you using a 64 bit OS? By default .NET apps run as 32 bit and they won't see the files in C:\Windows\System32, they'll see the files in C:\Windows\SysWOW64.

    Friday, November 13, 2015 5:26 PM
    Moderator
  • It appears the issue is with EXEs in the SYSTEM32 Directory. I can find if a DLL exists just not an EXE.

    Am using the anycpu option on the project configuration. Don't know if this affects this.

    Friday, November 13, 2015 5:54 PM
  • I am running a 64bit OS. The PLASRV.EXE file only exists in system32. Doing a DIR from the cmd line find the file.

    Friday, November 13, 2015 6:09 PM
  • Outside using CreateFile on the backend to determine if a file exists, which is what both of the methods done so far do, the other way is to use FindFirstFile/NtQueryDirectoryFile which is what I believe cmd does.  What happens if you enumerate the directory with the filename as a filter like below:

    bool found = Directory.GetFiles("C:\\Windows\\System32", "plasrv.exe", SearchOption.TopDirectoryOnly).Length > 0;


    WinSDK Support Team Blog: http://blogs.msdn.com/b/winsdk/


    Friday, November 13, 2015 7:01 PM
  • Since Visual Studio 2012, C# application projects default to “Any CPU 32-bit preferred”. If you run such an executable on a 64-bit Windows operating system, then it will start as a 32-bit process and be affected by WOW64 file system redirection.

    When a 32-bit process on 64-bit Windows tries to access "C:\Windows\System32", WOW64 redirects it to "C:\Windows\SysWOW64". There are several ways to access the real "C:\Windows\System32" directory:

    • Use "C:\Windows\SysNative", which WOW64 redirects to "C:\Windows\System32" even though it does not appear in directory listings. This is an easy way and unlikely to cause problems.
    • Use Wow64DisableWow64FsRedirection and Wow64RevertWow64FsRedirection.
    • Use a 64-bit process.
    Friday, November 13, 2015 7:23 PM
  • I tried the Directory.GetFiles above and it returned false

    Friday, November 13, 2015 7:34 PM
  • I'd recommend just running ProcMon at this point then and see what's going on.

    WinSDK Support Team Blog: http://blogs.msdn.com/b/winsdk/

    Friday, November 13, 2015 7:37 PM
  • Are you using a 64 bit OS? By default .NET apps run as 32 bit and they won't see the files in C:\Windows\System32, they'll see the files in C:\Windows\SysWOW64.

    Good point there. You should get the directory via the SpecialFoldersEnumeration. Hardcoding it is very likely to fail.

    Also note that File.Exists() is not reliable at all. Between you checking for the file and trying to use it, somebody else might have done something to it:
    Vexing exceptions - Fabulous Adventures In Coding - Site Home - MSDN Blogs (under exogenous exceptions)

    You should just try to open or execute the file (Process.Start) and communicate exogenous exceptions (like file not found) properly to the user. You can't prevent running into them anyway, no mater how many precautions you take.

    Friday, November 13, 2015 9:20 PM
  • One last comment. Thank you all for your replies. You provide some interesting insights into this problem.

    I have concluded that the problem I am having has to do more with permissions. A problem that is not shred by the cmdline dir command.

    I decided to try a wildcard search for all EXE files:

     int cnt = Directory.GetFiles("C:\\Windows\\System32", "*.exe", SearchOption.TopDirectoryOnly).Length;
    

    I received a count  of 320. However using the comandline prompt of "dir *.exe" returned 567 files.

    Dong the same thing with DLLs, I got 2330 in my program and 3127 using the command line.

    Saturday, November 14, 2015 2:16 PM
  • I have concluded that the problem I am having has to do more with permissions. A problem that is not shred by the cmdline dir command.

    And maybe, the O/S is not going to allow you to scan System32 and the Windows directories programmically on Vista and up and Win 2k8 server and up, since they are closed by default O/S(s) and those directories are protected cutting down the attack vector on those O/S(s).

    Saturday, November 14, 2015 5:23 PM
  • "I have concluded that the problem I am having has to do more with permissions."

    It has nothing to do with permissions. It has to do with the way 32 bit applications run on 64 bit systems. See Ranta's post above for more details.

    Sunday, November 15, 2015 6:26 PM
    Moderator
  • Hi OnTheBeach2,

    I agree with ranta. I wrote below code to confirm it.

    File.Exists("c:\windows\system32\plasrv.exe") //return false
    File.Exists(@"C:\Windows\SysNative\plasrv.exe") //return true
    Best Regards,
    Jerry

    Monday, November 16, 2015 5:37 AM
  • I absolutely agree and have moved on.

    Thanks

    Monday, November 16, 2015 5:12 PM