Maintaining state for uninstall is a big one which comes to mind.
Reference counting (which could sort of be rolled into the above item), to make sure you're not removing something someone else is using, if you install stuff to a shared location.
Silent installation. Yes, this is an afterthought for a lot of devs, but a lot of techs expect it for rolling out software.
Extensibility / Customization at install time. Also ties into the previous one (how to configure the install with no UI running).
Resume-after-reboot functionality, to update files which may have been locked.
Publishing accurate information into Add/Remove Programs (or "Programs and Features" as they call it these days).
Handling elevation in cases where the user isn't Admin (or post Vista - the installer is launched under the non-admin token).
"Repair" functionality, which requires maintaining the currently installed state and configuration.
Support for packing up and deploying redistributables (maybe even download support).
You start adding all that stuff up, and you realize - you can't bang that out in a weekend. It's a LOT of work actually.