I've written a custom automatic updater and basically, the way it works is this:
The whole application is essentially 3 parts:
- A launcher .exe that's essentially like a bootstrapper
- The launcher .exe has an embedded .exe resource that is used if the launcher .exe itself needs to be updated
- The application dll's
When you start the application, the launcher app starts and checks via webservices if the dll's are up to date. If they are not, it downloads them to a temporary directory and then makes sure the checksums are all correct and overwrites the existing app libraries with the new ones. It's then loading the application's core assembly and calls a "Run" method via reflection.
Now, in our app we sometimes have the need to update the launcher itself and the way we achieved this is by embedding an .exe in the launcher .exe resources. If the launcher detects that there is a new launcher .exe available, it downloads it to a temp directory, then extracts the .exe and launches it. This extracted .exe simply shuts down the launcher process, copies the new launcher .exe over the old one and then starts the launcher process again.