It depends on the exception. I've found that in some cases, exceptions
that originate with some sort of lower-level system call do include an
error code. You have to look at the internals of the exception type to
see if it's possible. For example, the SocketException class includes an
ErrorCode property that corresponds to the underlying socket error.
In many cases, the best you can do is look at the type of the exception
itself. For example, if you catch an IOException, then at least you know
that the exception wasn't caused (for example) by a null reference or out
of memory problem. But you're right, it may be hard to narrow it down
farther than that. Note that even in the IOException case, there are
derived exceptions that are more specific. So if you catch the more
specific type, that can sometimes offer more detail (though in the
examples you gave, it doesn't look like that would be the case).
I also note that in IOException (and other System exceptions), there is an
HResult member that corresponds to the system error code. However, it's
protected and unless you derive a new exception from the class, I don't
know how you'd get at that in any useful way (and if you're not throwing
the exception yourself, how would you derive from it? :) ). You can look
at it in the debugger though. :)
Pete