【问题标题】:Installer Projects - Launching a custom action with elevated privileges安装程序项目 - 使用提升的权限启动自定义操作
【发布时间】:2019-05-08 14:23:14
【问题描述】:

我有一个带有安装程序项目安装程序的 Visual Studio 2017 c# 应用程序。我们使用“自定义操作”来启动在 MSI 完成时运行的可执行文件,并且自定义操作位于自定义操作选项卡中的“提交”下。

应用程序运行时,其 Windows 用户主体为 NT AUTHORITY\SYSTEM。

当我自己运行应用程序时,它的用户就是我,MYDOMAIN\MYUSER

所以我试图让它提升这些权限,到目前为止,我主要在谷歌上搜索旧的 stackoverflow 问题,但我发现了三个可能的解决方案,但没有一个对我有用,在所有情况下,exe 仍在 NT AUTHORITY\ 下运行系统

  1. 添加包含
  2. 的应用清单
<requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
  1. 在记事本中编辑 vdproj 文件,使 RequiresElevation “true”
    "MsiBootstrapper"
    {
        "LangId" = "3:1033"
        "RequiresElevation" = "11:TRUE"
    }
  1. 尝试添加 AdminUser 作为启动条件,按照:How do I avoid UAC when my EXE file name contains the word "update"?

以上方法已经单独尝试过,但它始终是 SYSTEM 用户。

关于如何让自定义操作作为登录用户的权限而不是作为 SYSTEM 运行的任何想法?谢谢

【问题讨论】:

  • 应用程序在做什么?如果它不需要管理员权限,您可以将它所做的事情移至主 application.exe 及其启动顺序。更易于实施、调试和维护。对 QA 人员也更好(他们可以清理注册表并重新启动您的应用程序并快速再次运行)。
  • MSI 正在安装服务,作为自定义操作运行的应用程序会提示用户提供必要的信息以登录服务并将其连接到与之通信的网站。所以该应用没有 UI,因此我们必须在安装时与用户交互。
  • 不太清楚为什么需要提升当前用户。为什么 SYSTEM 还不够?
  • 在某些域(而不是其他域)上,安装程序自定义操作会失败,因为它没有足够的权限,而当用户在安装完成后启动相同的自定义操作 exe 时它会起作用。还有一个易用性问题,我们可以为服务凭证默认用户名和域名。但是是的,主要问题是在 MSI 安装程序的上下文中存在某种权限问题。抱歉,我不知道确切的问题,但无论是什么解决方案都是提升权限。
  • 在已编译的 MSI 中,查看 CustomAction table(使用 Orca or similar tools 打开)。尝试根据您在上述链接中找到的选项调整 Type 值。我现在没有适合你的样品。

标签: c# visual-studio-2017 windows-installer custom-action


【解决方案1】:

EASY 答案被证明是该线程中接受的答案:

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

[引用]

简短的回答是,您不能在作为 InstallAllUsers 设置的 Visual Studio 设置中执行此操作,因为所有 VS 安装程序生成的自定义操作都作为系统帐户运行。因此,您需要使用 Orca 等编辑工具更改 MSI 文件中的自定义操作设置。您会在 MSI 文件的 CustomAction 表中找到自定义操作,查看 Type 值(可能是 3074 类型),然后关闭 msidbCustomActionTypeNoImpersonate 位,使其模拟为安装用户运行。

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

请注意,以安装用户身份运行有其自身的一系列问题,因为它与以交互式用户身份运行不同。用户配置文件未加载,因此与用户关联的对象(例如 HKCU、用户配置文件文件夹)非常不可靠。

许多人在第一次启动应用程序时使用单独的程序填充数据库,以便它可以作为交互式用户正常运行,并且可以作为独立程序进行开发和调试。如果在安装过程中填充失败,您要么放弃安装并回滚,要么继续安装并最终得到一个空数据库,您可能需要一个程序来填充它。 [/quote]

不是那么简单的答案但很好的解决方案如下:

编辑 MSI 文件以从自定义操作记录中删除类型 msidbCustomActionTypeNoImpersonate。

我在 VB.NET 程序中以编程方式执行此操作,如下所示:

    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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多