> Why is this so hard?
Two reasons, from my experience:
1. we have large corporate clients (think multinational). They use our services exactly once every year. Over 1,000,000 people in total. Imagine the logistics involved to get a desktop/native application deployed - for that one time use? What if we need to tweak something halfway. How do we re-deploy?
2. That application is "distributed". Everyone does a little bit that is then accumulated. Sure, we could write a client-server app. Then we'd need to figure out threading issues on the server side, work out the communication protocols, work out locking issues. Or we could let, say, Apache handle the threading (we're good but i'd rather trust software that has undergone years and years of usage - there are other web servers that do this better, i know.) Let HTTP be the communication protocol. Let the backend database handle data locking issues (at least using standard SQL concepts allows everyone to be able to wrap their heads around the issues involved). You could argue that we could use a native app that then uses HTTP. For that, see #1.
Native apps were great. Far richer experience in terms of UI. But far, far, poorer in terms of distributed-ness and ease of deployment. Or, looking at it another way, the current state of things are due to the evolution of one native app - the browser. It's just that it comes with an established integrated communication protocol and a UI that's flexible/extendable and the guarantee that the shell/runtime is multi-vendor - but largely compatible and available on most computers shielding you from deployment hassles. So it IS a native app that comes with the pieces you need (comm protocol, extension language, widespread availability).