You can't get a mixed-mode callstack from inprocess.

You can't get a full-mixed (both managed+ native) stack of a thread within your own process.
You can get a native-only stack from function like DbgHelp!StackWalk64 (which is what this article on Codeproject  does) to get the native callstack of a native thread. However, the native stackwalker gets lost once it hits managed code because it doesn't know how to decode managed code.  I allude to this problem here.
You can also get a managed-only stack from the managed StackTrace class, but that won't have any native frames.
Unfortunately, you can't really stitch these two results together because there's not enough information.

Consider this example. Suppose the callstack is:
    (M1) calls (U1) calls (M2) calls (U2).
Where M1 and M2 are managed code; and U1 and U2 are unmanaged code. The thread is currently stopped in U2.

A full mixed mode callstack would yield all frames {M1, U1, M2, U2 }. A managed-only stack trace from the StackTrace class would yield {M1, M2} and ignore the unmanaged frames. A native-only stack trace would likely just yield {U2}. This is because stack traces start at the leaf most end of the stack (where the thread is currently active), unwind through U2, then get lost inside of M2 and not even be able to determine that it's in M2. Once a stacktrace gets lost, it will likely just stop trying to make any further progress and thus you get a truncated stack trace.  (It is possible the native stack trace might get "lucky" enough to find U1, depending on the codegen for M2 and the type of transitions between managed and native code).
So the managed-only trace is  {M1, M2}, and the native-only trace is {U2}. There's no way to recover the original full trace {M1, U1, M2, U2} because:
1.) U1 is completely lost.
2.) there's not enough information to be 100% sure about how to order the two traces. Is it {M1, M2, U2} or {M1, U2, M2} or {U2, M1, M2}? 

Obviously, the fact that VS can show fill mixed-mode stacks with MC++ testifies that ICorDebug provides enough information through the Interop-debugging interfaces to allow full mixed-stacks. But that stackwalk is being done from a separate process (the debugger) than the target. You can't use the ICorDebug interfaces for interop-debugging on your own process because as soon as you hit any native debug event, the entire process is frozen. Unlike the native-only debugging API, ICorDebug's interop-debugging API doesn't have non-invasive functionality.