0

I have a Visual Studio 2017 c# application with an installer projects installer attached to it. We use a "custom action" to launch an executable which runs as the MSI is finishing, and the custom action is under "commit" in the custom actions tab.

When the application runs, its windows user principal is NT AUTHORITY\SYSTEM.

When I run the application myself, its user is me, MYDOMAIN\MYUSER

So I am trying to get it to elevate those permissions, and so far from googling mainly on old stackoverflow questions I found three possible resolutions but none of them worked for me, in all cases the exe was still running under NT AUTHORITY\SYSTEM

  1. Add an app manifest that contains
<requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
  1. Edit the vdproj file in notepad to make RequiresElevation "true"
    "MsiBootstrapper"
    {
        "LangId" = "3:1033"
        "RequiresElevation" = "11:TRUE"
    }
  1. Tried adding AdminUser as a launchcondition, as per:How do I avoid UAC when my EXE file name contains the word "update"?

The above have been tried all together and separately but its always still the SYSTEM user.

Any ideas on how I can get the custom action to run as the logged-in user's privileges and not as SYSTEM ? thanks

user2728841
  • 1,063
  • 13
  • 27
  • What is the application doing? If it does not require admin rights, you can move the things it does to the main `application.exe` and its launch sequence. Easier to implement, debug and maintain. Better for the QA guys as well (they can clean the registry and re-launch your application and get running again quickly). – Stein Åsmul May 05 '19 at 15:08
  • The MSI is installing a service, and the application that is run as a customaction prompts the user for the necessary information to log the service on and connect it to the website it communicates with. So the app has no UI, therefore we have to interact with the user at install time. – user2728841 May 05 '19 at 16:00
  • Not quite sure why you need to elevate the current user. Why SYSTEM is not enough? – montonero May 06 '19 at 09:09
  • On some domains (and not others), the installer custom action fails because it doesn't have enough permissions, whereas it works when the user launches the same custom action exe after the install has finished. There's also an ease of use issue that we can default the username and domain name for the service credentials. But yes the main issue is some kind of permissions issue when its under the context of the MSI installer. Sorry I don't know the exact issue but whatever it is the solution will be to elevate permissions. – user2728841 May 06 '19 at 16:08
  • In the compiled MSI, look in the [`CustomAction table`](https://docs.microsoft.com/en-us/windows/desktop/msi/summary-list-of-all-custom-action-types) (open using [Orca or similar tools](https://stackoverflow.com/q/48482545/129130)). Try to adjust the **`Type`** value based on the options you find in the above link. I don't have a good sample for you right now. – Stein Åsmul May 07 '19 at 02:34
  • Strangely, my custom action didn't appear in that table. I could see "/installtype=notransaction" on each action, but no evidence of my custom action exe whatsoever. I am briefly chasing another idea and will come back to this – user2728841 May 07 '19 at 08:48
  • @SteinÅsmul your comment guided me to the "not so easy answer" below :) – user2728841 May 08 '19 at 06:21

1 Answers1

0

The EASY answer turned out to be the accepted answer in this thread:

Windows installer using the NT AUTHORITY\SYSTEM instead of login user

[quote]

The short answer is that you can't do this in a Visual Studio setup that is an InstallAllUsers setup because the all VS installer generated custom actions run as the system account. Therefore you'd need to change the custom action settings in the MSI file with an editing tool such as Orca. You'd find the custom action in the CustomAction table in the MSI file, look at the Type values (it's probably a type 3074) and then turn off the msidbCustomActionTypeNoImpersonate bit so that it runs impersonated as the installing user.

https://msdn.microsoft.com/en-us/library/windows/desktop/aa368069(v=vs.85).aspx

Note that running impersonated as the installing user has its own set of issues because it is NOT the same as running as the interactive user. The user profile is not loaded, so objects associated with the user (such as HKCU, user profile folders) are very unreliable.

Many people populate the databases with a separate programs the first time the application is launched so that it runs properly as the interactive user and can be developed and debugged as a standalone program. If the populate fails during the install you either give up the install and roll back, or you continue the install and end up with an empty database, for which you might need a program to populate it anyway. [/quote]

The NOT SO EASY ANSWER but excellent solution was as follows:

Edit the MSI file to remove the type msidbCustomActionTypeNoImpersonate from the custom action record.

I did this programmatically in a VB.NET program as follows:

    Dim o As WindowsInstaller.Installer = CType(CreateObject("WindowsInstaller.Installer"), WindowsInstaller.Installer)

    Dim db As WindowsInstaller.Database
    db = o.OpenDatabase(fil.FullName, WindowsInstaller.MsiOpenDatabaseMode.msiOpenDatabaseModeDirect)

    Dim record As WindowsInstaller.Record = Nothing
    view = db.OpenView("select File.File, FileName From File")
    view.Execute(record)
    record = view.Fetch
    Dim bFound As Boolean = False
    While record IsNot Nothing
        Dim sFileName As String = record.StringData(2)
        If sFileName.EndsWith("MYCUSTOMACTIONEXE.exe", StringComparison.CurrentCultureIgnoreCase) = True Then
            bFound = True
            Exit While
        End If
        record = view.Fetch
    End While

    If bFound = True Then
        Dim sGUID As String = record.StringData(1)

        '   At time of writing this was changing a 3602 into a 1554, so removing msidbCustomActionTypeNoImpersonate 
        '   The record key was _65BF5279_D2EA_42C1_AC66_90A684817EE5 which is the custom action for MYCUSTOMACTIONEXE.exe


        view = db.OpenView("select Action, Type From CustomAction Where Source = '" & sGUID & "'")
        view.Execute(record)
        record = view.Fetch
        If record IsNot Nothing Then
            Dim sActionGUID As String = record.StringData(1)
            Dim sType As String = record.StringData(2)
            If sActionGUID IsNot Nothing AndAlso sActionGUID <> "" Then
                '   Take off Hex 800 which means noimpersonation
                Dim lType As Integer = CInt(sType)
                If lType And 2048 = 2048 Then
                    Dim sNewType As String = CStr(lType - 2048)
                    Dim v As WindowsInstaller.View = db.OpenView(
                        "update CustomAction set Type=" & sNewType & " Where CustomAction.Action = '" & sActionGUID & "'")
                    v.Execute()
                End If
            End If

        End If
    End If
user2728841
  • 1,063
  • 13
  • 27