Wixsharp: Running msiexec from a windows service as LocalSystem account

Created on 29 Jun 2020  路  8Comments  路  Source: oleg-shilo/wixsharp

Hello,

I am working on a service that updates software developed by me.
The service downloads the latest versions of the application and starts the installer as the LocalSystem user.
For the first time, the application must be installed by the administrator for the service to see what it can update.

The problem occurs when the updater installs the update.

For example, let's call the application "test".

The administrator installs the "test" application version 1.0.0. The updater, after some time, sees that version 1.0.1 has been released.
The updater downloads and installs the update but not in major upgrade mode. The new version does not appear in the control panel, there are two entries in the registry in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall.

From solutions on StackOverflow:
https://stackoverflow.com/questions/2603969/running-msiexec-from-a-service-local-system-account
the only ones that work are a change of the user running the service but I can't use it.

I have already set InstallScope to perMachine in script. GUID is the same for all versions of "test" application.

Installer form updater is launched by

```c#
string command = $"/i {installerPath} /l \"{installerDirectory}\log.txt\" /passive REINSTALL=All REINSTALLMODE=vomus";

ProcessStartInfo installProcessStartInfo = new ProcessStartInfo
{
FileName = "msiexec",
UseShellExecute = false,
RedirectStandardError = false,
Arguments = command
};

Process msiexec = Process.Start(installProcessStartInfo);
```

When I remove "test" application, files from later version still exists in folder and registry key created by system local exists too. There is one way to delete this entries, you need to manually install the same version as the updater already did and then you can uninstall it from the control panel.

question

All 8 comments

Sorry, my answer will not be the one that you are hoping for. :)

I do not know what exactly happening in your case but that "installs the update but not in major upgrade mode. " makes me question why you don't use major upgrade. It would solve your problem in the most direct way.

======================

The scenario you are implementing is a typical use case that have been solved I would also so many times by many products that you already know and use. Notepad++, VSCode, Paint.NET, FIleZilla....

None of them resorted to installing the updater service. The all follow a very simple approach:

  • At startup check for updates
  • If the update is available, ask user if he/she wanst to install a new version (right away or after exit).
  • If user agrees start the downloader/updater and exit the current instance of the app.

And there is even a complete deployment build around this use case: ClickOnce

One of my applications is running as a service all time and there is no way to show message about update.
The reason why I want to make updater run as the localUser is that users which use my applications could not have permissions to run installation, what is required.

I think I have misspelled. I use major update. "The updater downloads and installs the update but not in major upgrade mode." is how application behaves in this specific situation (when I first install application as administrator, then updater runs installer as LocalSystem user). Next updates performed by updater works almost properly except it does not remove old version installed by other user.

...users which use my applications could not have permissions to run installation, what is required.

I see. Then indeed the requirement above makes the difference.

I can only suggest to see if the upgrade removes the old install when executed from the user session, not the service.
Normally _MajorUpgrade_ msi removes the old version without any problems.

You also try to use the _MajorUpgrade_ sample from the distro. It works on its own so you can use it as a benchmark in your scenario.

no way to show message about update.

Yes, for years it was possible for services to interact with the user (by enabling "allow interact with desktop"). It's no longer the case. If you still need to interact with the user then you can use the OS task scheduler to execute an immediate task with the desired privileges and the ability to interact with the user.

I can only suggest to see if the upgrade removes the old install when executed from the user session, not the service.

Upgrade successfully removes old install when it's run from user session.
If I change user that runs service from localSystem to other user with admin privileges, installation runs properly as well (which is not good solution because I will have to change user every time updater gets updated).

you can use the OS task scheduler to execute an immediate task with the desired privileges and the ability to interact with the user.

Thank you for the hint :D

Then, I am puzzled. I cannot see any logical reason for MSI to be have differently for localSystem and an elevated user.
If indeed your findings are accurate then it might indicate the bug in the MSI implementation. Doesn't give you much hope :(

Sorry for wasting your time... there is something strange with my os... I tried this on virtual machine and it works properly... on my friend's computer and works too... It's time to do fresh os installation 馃槩

It is in fact the preferred outcome :)

@konrad-szerwinski There are multiple things problematic with your approach.

First, I'm not joking when I say, "Don't use ClickOnce." I would suggest Squirrel in the past (even Microsoft Teams was using it), but it has become semi-abandoned. A new framework, snapx, has emerged.

Second, LocalSystem uses a unique AppData folder, so it's easy to create a Rube Goldberg machine with your current approach. If it "works on my machine" but not others, this could be why.

Third, ClickOnce's check for updates mechanism leaks request counts, which eventually causes ClickOnce applications to stop checking for updates. See my description and workaround here: https://github.com/jzabroski/Home/blob/8c2896377658a2f5b51674924a15549c9f9e5c72/CSharp/ClickOnce/README.md

Was this page helpful?
0 / 5 - 0 ratings

Related issues

CADbloke picture CADbloke  路  4Comments

meytes picture meytes  路  5Comments

Chrissyoung1223 picture Chrissyoung1223  路  5Comments

meytes picture meytes  路  3Comments

marcobeninca71 picture marcobeninca71  路  4Comments