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
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
"MsiBootstrapper"
{
"LangId" = "3:1033"
"RequiresElevation" = "11:TRUE"
}
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
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