Here's some ways to do a rewrite well:
Set up the rewrite as an alternate, competing product and let the two compete in the marketplace. This requires having the resources to support developing two such products at the same time using separate teams for each, which is not something many companies can afford. The advantage to doing it this way is that it gives the rewrite time to mature before it's fully replaced the old system. What most people tend to not realize is that mature software with fundamental flaws can often be superior to immature software on a better foundation. Real-world use is orders of magnitude more effective as a QA process than any sort of in-house testing, and always well be, products that have been tried by fire and made the cut should always be respected no matter how horrible their underlying code is.
If you look at a lot of the major switchovers in software you'll see this sort of trend fairly often. For example, consumer Windows took several generations and almost an entire decade to fully switch over to the NT core.
Another good way is to rewrite piece-wise, in place (refactoring). There are lots of different ways to do this regardless of architecture, ultimately you're essentially creating a bubble of new code that grows and grows until it completely replaces all the old code. The advantage of this is that it takes much less effort than a full rewrite and you can do it incrementally and slowly. Often it's easier to mature each new component in isolation than to try to mature an entire new product.
And, of course, there's the hybrid approach. Work component-wise in an "add + deprecate" fashion. Create the new component, have it work in parallel along with the old component, and then deprecate the old component and work toward moving client code to the new component.