The real question is not so much why it's evil, but why do you want to use it in the first place? The two most common answers I've seen are system("cls") and system("pause"). The latter is a subject that's already been discussed to death a thousand times over. The former is a perfect example of something that could be significantly improved if replaced with system calls.
As for system() vs. system functions such as CreateProcess() ("ProcessExec"? MSDN returns nothing), there's a world of difference. Among other things, nothing passes through the shell (at least not that I remember. I may be wrong though), it's possible to use Unicode strings, it's possible to inherit handles (try pulling this one off using system():
http://www.cplusplus.com/forum/lounge/17371/ ), it's possible to give the new process specific security parameters (run with lower privileges), and it's non-blocking.
Of course, with great power comes great complexity. You have to actually
read the documentation to find out about any of this.
As a final note, for the past four years I've never, not
once, had to use system() for something that couldn't be done better some other way. I've written a grand total of three calls to CreateProcess(), one of them being that link.
If the number of people who ask about system() is any indication, it would seem one out of two programming projects is a shell.