<p>Short of using a profiler, is there any way inside a running program to detect first chance exceptions?  Ideally, I would like to record more detailed state information that is not available once the catch block has taken over the final exception.</p>

I think the only way you can get that information in .NET is using a Debugger.
Otherwise, you'll have to develop a solution yourself for saving the state of a stackframe and having a special way to log exceptions. You'd basically be doing the same things that a memory profiler does, keep track of the instances that are created.  This would be a huge performance hit though unless you limit the amount of information you are logging.
A better solution would be to use the Trace and Assert capabilities in the System.Diagnostics namespace to selectively trace the program state, or to use a logging facility (log4net, EnterpriseLibrary, NLog, roll your own simple one) to dump thread / stack / variable information as you go.
In any case, adding all this extra information is a big overhead.
EDIT: I got news of this project in my feed:
NTrace
.  It looks like it will fit a little more of what you're trying to do.