30

Using VS 15, C# with .Net 4.5.2
The computer is on an AD network, with the ad name "AD".
This problem happens with AD normal-user rights, AD admin rights, and local admin rights. It doesn't matter what rights the program gets, the same problem occurs.

Our test file is "C:/windows/system32/conhost.exe".
The file above exists, it is very much existing. I can see it with explorer.

This is the file in explorer:
enter image description here

This is the file properties:
enter image description here

You can see that it is there, right?
The following cmd command checks if the file exists:

IF EXIST "C:\windows\system32\conhost.exe" (echo does exist) ELSE (echo doesnt exist)

It returns "does exist" as promised.

The following C# code checks if the file exists:

FileInfo file = new FileInfo("C:/windows/system32/conhost.exe");
MessageBox.Show(file.Exists + "");

This returns "False".

This code also returns "False":

MessageBox.Show(File.Exists("C:/windows/system32/conhost.exe") + "");

This code also doesn't find it:

foreach (string file in Directory.GetFiles("C:/windows/system32/"))
{
    //conhost is NEVER mentioned, like it doesn't exist
}

This code also doesn't find it:

foreach (string file in Directory.EnumerateFiles("C:/windows/system32/"))
{
    //conhost is NEVER mentioned, like it doesn't exist
}

False, False, False:

MessageBox.Show(File.Exists("C:/windows/system32/conhost.exe") + "");
MessageBox.Show(File.Exists("C:\\windows\\system32\\conhost.exe") + "");
MessageBox.Show(File.Exists(@"C:\windows\system32\conhost.exe") + "");

What am I doing wrong?
Extra note: I copied conhost to C:\conhost.exe, and my program can find that without problem. My program also finds other files in system32, just not conhost and a few others. For example, it finds "connect.dll" which is in system32, so it's not the directory's read permission.
More extra notes: conhost.exe and connect.dll has the same security attributes (Security tab in the file properties).

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
HoverCatz
  • 65
  • 1
  • 5
  • 19
  • Have you tried changing / to \ maybe? – Tamás Szabó Mar 23 '17 at 13:22
  • Try `File.Exists(@"C:\windows\system32\conhost.exe")` – phuzi Mar 23 '17 at 13:22
  • Yep, same result in every test in both directions :( – HoverCatz Mar 23 '17 at 13:23
  • 6
    64 bits app and redirection perhaps... – xanatos Mar 23 '17 at 13:25
  • @xanatos You might be right, I haven't tested this as 64bit yet. – HoverCatz Mar 23 '17 at 13:26
  • can you show "icacls c:\windows\system32\conhost.exe" and "whoami /groups" of the same user that is running your program? – DarkSquirrel42 Mar 23 '17 at 13:28
  • I had similar problem with Directory.exists, msdn:"If the caller does not have sufficient permissions to read the specified file, no exception is thrown and the method returns false regardless of the existence of path.", hacked it with net use command http://stackoverflow.com/a/15832359/891715 – Arie Mar 23 '17 at 13:29
  • Found the answer, thanks to xanatos and Uladzimir Palekh, I will update my question with the answer. It had nothing to do with permissions :) – HoverCatz Mar 23 '17 at 13:30
  • 1
    Questions are where you ask your question, not where you post your answer. If you want to post your own answer, in addition to the answers provided by others, then post it *as an answer*. If the existing answers adequately answer the question, then of course there is no need to do so. – Servy Mar 23 '17 at 13:43
  • @Servy I strongly dislike that you removed the solution, even tho it is in one of the answers. – HoverCatz Mar 23 '17 at 13:47
  • @Servy I didnt know the answer when posting this question. Are you telling me to post a NEW QUESTIOn with the "answer" in that "as an answer"? – HoverCatz Mar 23 '17 at 13:50
  • @Servy Alright, I have seen lots of questions before where the OP updated his question with the answer, and noone (after years) didn't remove it. I guess you irritated me about it, and i'm sorry about that, you're right :) I just wanted to make it easier for future "googlers" to find a quick solution. – HoverCatz Mar 23 '17 at 13:54
  • why doesn't the accepted answer contain the question? i think it should or how do we know what the answer is for? – Weyland Yutani Mar 23 '17 at 16:57
  • 2
    unrelated, but wth is up with all the `+ ""` stuff? Get rid of that useless junk. If you mean to do `.ToString()`, then to `.ToString()`. Or use string interpolation.. whatever. `+ ""` just doesn't look right. – Mathieu Guindon Mar 23 '17 at 18:01
  • unrelated, its shorter. – HoverCatz Mar 24 '17 at 09:18

3 Answers3

43

If you are using x64 system, you will have different content of the c:\Windows\System32 directory for x86 and x64 applications. Please be sure that you are using same architecture running batch file and your C# app.

Uladzimir Palekh
  • 1,846
  • 13
  • 16
  • This is the only thing I haven't tried yet. Ill do it right now and update my question, maybe setting this as solved. – HoverCatz Mar 23 '17 at 13:27
  • 1
    There may be something to this, but it may be something else, as I tried this both in 32-bit and 64-bit mode, non-administrator, and it found the file both times, but then again my "32-bit" mode is also "anyCPU" so that may be my issue. I'll re-test it more explicitly. Edit: Yes, forcing the .NET project to 32-bit does replicate the issue. The default is AnyCPU, so I wonder what the OP was doing that it wasn't that. – Kevin Anderson Mar 23 '17 at 13:40
  • Might be worth mentioning why this is the case. I believe it's to do with the [File System Redirector](https://msdn.microsoft.com/en-us/library/windows/desktop/aa384187(v=vs.85).aspx) – Lukazoid Mar 23 '17 at 23:49
  • Thanks, @UladzimirPalekh! This also explained, for me, why I couldn't do `Process.Start("arp");` after setting the `WorkingDirectory` to `%SYSTEMROOT%\system32`, which I had to do because I was doing impersonation. Under my account, it ran fine. I found it was because `arp` is only a 32-bit app, and so it had the right context - because of my having to direct it due to impersonation, it did not. :( – vapcguy Oct 17 '17 at 20:04
  • I have a file in a specific directory. `File.Exists(@"absolute/path/to/the/file")` returns `false`. I published the project with _Target Framework : netcoreapp2.2_ and _Target Runtime : win-x86_. Even than `File.Exists(@"absolute/path/to/the/file")` returns `false`. I would like the C# code to be able to read the file and execute it. – phougatv Jul 16 '19 at 12:15
  • @Vedant what OS are you using? My answer is related to the 64 bit Windows. – Uladzimir Palekh Jul 19 '19 at 21:08
  • OS: Windows 64 bit. The exe I'm trying to access is 32 bit. As it lies in Program Files (x86). – phougatv Jul 20 '19 at 00:29
  • Many thanks! Had that issue on my 64-bit machine due to defaults "platform target: Any CPU" and "Prefer 32-bit" ticked in my console app. Unticked "Prefer 32-bit" to resolve. – Markus Mar 15 '22 at 13:38
10

In the MSDN documentation for System.IO.File.Exists(path), it states:

If the caller does not have sufficient permissions to read the specified file, no exception is thrown and the method returns false regardless of the existence of path.

For this reason, we can safely assume that your application does not have read access to that specific file. Check the security settings and grant read access if not already done so.

Build your application (in release mode) and run as administrator.

Nathangrad
  • 1,426
  • 10
  • 25
  • 1
    I specified that I tried 2 types of admin rights in my question. – HoverCatz Mar 23 '17 at 13:27
  • 6
    The example file is a built-in system file, within the Windows folder. Every user has at least read acces into them, otherwise Windows itself would have problems. For other files, permissions are something to consider. – Alejandro Mar 23 '17 at 15:45
  • My kingdom for seperate `.exists()` and `.canRead()` in C#. The method should be called `existsAndCanRead()`. – Steve Smith May 26 '17 at 11:56
1

This is the problem that come over 64-bit operating system... here is a work around,

go to the project's properties > click on build tab > untick Prefer 32-bit

after that, it should work correctly over 64-bit os.

hsCode
  • 469
  • 4
  • 11