The way exceptions are handled in .NET is materially different than the way they are handled in, say, Java. Exceptions in Java demand more from the programmer than .NET does, and so the argument could be made that you reserve exception handling in Java for the truly exceptional cases.
In .NET, an exceptional condition is one that you cannot reasonably recover from without user intervention. If the user passes the name of a file to a method which expects the file to exist, but the file doesn't exist, that's an exceptional condition.
As a programmer, you still have the option of checking for the existence of the file first, before calling the method that requires it.
In any case, the guidance that Microsoft offers seems relatively straightforward:
If the event is truly exceptional and is an error (such as an
unexpected end-of-file), using exception handling is better because
less code is executed in the normal case. If the event happens
routinely, using the programmatic method to check for errors is