I am trying to setup a WiX installer that install a windows service and handles upgrades and updates.
The installer works like a charm, the user installs the service
This is a classic source of truth problem. MSI wants to be the source of truth and doesn't have anything in it's code to account for this scenario. It thinks the service should be LocalSystem and so it wants to fix it. ( This isn't just upgrades ... a repair will do the same thing. )
So, what to do?
Option A:
Bring username /password configuration into the MSI. UI work, credential validation and encryption of the creds persisting it on the machine somewhere so that subsequent transactions can decrypt and reuse the credentials.
Note: Risk. The creds can be reverse engineered.. I got news though... so can windows LSA secrets and Application Pool Identities and such.
Option B:
Use custom actions to create the service. This way you can do logic to not touch the service during subsequent transactions.
Option C:
Put conditional expressions on CreateServices standard action to only apply during first time installation and not major upgrades.
Risk: If you ever change anything else about the service it won't get deployed by an upgrade because it's been bypassed. Also this is for all services in your MSI not just this one.
Option D:
Embrace running as a built in service account and use active directory permissions to grant that computer object rights to whatever it connects to.
Option E:
If the user applies creds after install, then they can simply do it again after upgrade. They can deal with it.