This is certainly a problematic area with no easy solutions, especially because every solution has a number of drawbacks leaving no clear winner.
One option is to replace only .dll files. This prevents signing of the assemblies (since you're not updating the executable file itself) and requires the application to be structured in a way so that almost all of the application logic resides in dlls. The benefit is that you can have the exe itself check for updates and download them when available, but this is only feasible if the dlls are stored as data elsewhere (e.g. an application plugin folder in appdata).
Another option is to use a Windows service that runs with local administrative rights to download and install the updates. This can happen without user intervention, even for another Windows service afaik. The trick here is to not leave the update service running, but start it from one of the actual applications (either on startup or when it is closed) and then have the service stop itself after installing any updates, in order to avoid bogging down users systems with yet another update service.
Last, you should seriously consider dropping the "completely unattended" part. Users might find intermittent startup delays to be an issue and communicating what you are doing does not cause any harm. I particularly like the solution that displays a dialog on startup saying "new version found - install (now) (on exit) (later)", giving me complete control over whether I want the delay or not. Some applications (like every poker client I know of) need to be in sync with server-side software and do not give you this option, but still show the "update in progress" dialog so that I know what is going on. As long as the installation is automatic I wouldn't worry about the prompt.