【问题标题】:Installshield custom action with elevated rights not running properly具有提升权限的 Installshield 自定义操作无法正常运行
【发布时间】:2019-03-20 14:58:45
【问题描述】:

我正在使用 InstallShield 2018。我正在尝试让安装程序在安装结束时执行一个程序(带有一些命令行参数)。当安装到应该运行程序的位置时,我收到消息:“此 Windows 安装程序包有问题。无法运行完成此安装所需的程序。” (还有更多细节——见下文)

我尝试执行的程序是我们自己使用 C# 开发的,需要管理员权限才能运行。它有一个(集成的)清单文件来强制执行此操作。我目前正在使用合并模块安装它,因为该程序应该可以在不同的软件版本之间重复使用。

为了实现这一点,我在“InstallFinalize”之前添加了一个“系统上下文中的延迟执行”自定义操作(类型 3682),条件为“NOT REMOVE”。我在目录表中创建了一个指向可执行文件安装文件夹的条目,自定义操作的源指向该条目,目标是可执行文件的名称和命令行参数,即:VersionManager .exe /Register "[ProductName]" /loglevel info

返回处理设置为“同步[检查退出代码]”。我尝试将其设置为忽略退出代码 - 这可以在安装似乎没有问题的情况下完成,但是当我检查日志文件时,它无法运行程序并且我看到如下内容:

MSI (s) (F0:0C) [10:09:49:724]: Executing op: CustomActionSchedule(Action=RegisterAfterInstall,ActionType=1122,Source=C:\Companyname\VersionManager\,Target=VersionManager.exe /Register "Fully parsed product name" /loglevel info,)
MSI (s) (F0:0C) [10:09:49:740]: Note: 1: 1721 2: RegisterAfterInstall 3: C:\Companyname\VersionManager\ 4: VersionManager.exe /Register "Fully parsed product name" /loglevel info 
Info 1721.There is a problem with this Windows Installer package. A program required for this install to complete could not be run. Contact your support personnel or package vendor. Action: RegisterAfterInstall, location: C:\ Companyname\VersionManager\, command:VersionManager.exe /Register "Fully parsed product name" /loglevel info

当我在指定位置(具有管理员权限)运行给定命令时,安装似乎可以顺利完成。我唯一能想到的是,不知何故,程序没有以管理员权限执行。

当我在消息弹出的那一刻检查驱动器时(检查退出代码时),文件实际上存在于系统上(我之前遇到过问题,它产生了不同的错误消息)。

我在某处发现了一篇帖子,建议将操作类型更改为“在系统上下文中提交执行”(因为该程序依赖于在 GAC 中注册的 .NET 内容,并且在 installfinalize 完成之前显然无法访问)但这没有帮助.

我无权分享我的源代码(或至少不是全部),但如果上述信息不充分,我可以建立一个演示相同问题的小型示例项目。

编辑:

虽然我仍然很好奇为什么上述方法不起作用,但我设法找到了解决方法。如果我直接包含程序的文件(而不是通过合并模块)并定义类型为 3602 的自定义操作(即“与产品一起安装”),它工作正常。我之前没有尝试过,因为我想让它与合并模块一起工作。 (我知道可以在合并模块中定义自定义操作,但是我无法微调命令行参数)

不过,我仍然不完全明白为什么。

【问题讨论】:

  • 这个EXE在做什么?由于conflicting commit models of Fusion (GAC) and MSI,对 GAC 的依赖是托管代码的一个传奇问题。您根本不应该对自定义操作有这种依赖关系(这就是为什么我更喜欢静态链接的 C++ dll 自定义操作 - minimal dependencies)。 WiX 允许您将所有依赖项捆绑在同一个本机 CA dll as described here
  • 抱歉回复晚了;我并没有真正设法在这方面取得进展,并且被其他问题所淹没。 EXE基本上是管理安装在同一台机器上的不同版本的软件;它的主要目的是管理注册表项。这一切都必须向后兼容,并且涉及 20 年的历史、不良做法等,因此我们开发了一个自定义程序来管理所有注册表项,而不是让安装程序尝试处理它。

标签: windows-installer installshield custom-action elevated-privileges


【解决方案1】:

没有足够的信息来调试它,因为它基本上是你的程序失败了。一些问题往往是:

  1. 该代码使用本地系统帐户运行,这意味着无法访问某些常用用户项。尝试使用 HKCU 和任何用户文件夹(例如用户的应用程序数据文件夹)或映射的网络驱动器将无法预测并导致崩溃。

  2. 程序未从 Windows 资源管理器运行,因此不会设置当前工作目录。需要明确指定文件的路径(这可能是“从安装位置运行”有效的原因)。

您通常不需要在安装时进行注册。信息几乎总是静态的,可以在构建时提取到(例如)MSI 文件的注册表表中。 InstallShield 可能为此提供了一些东西,某种注册设置。

【讨论】:

  • 听起来像GAC dependency issue?还是一般的依赖问题?想知道用WiX MakeSfxCA.exe 包裹是否可以解决问题?无论哪种情况,正如我在上面评论的那样,这些托管代码自定义操作都是松散的大炮,我认为所有人都可以看到。运行时问题、依赖问题、版本干扰等......上帝帮助我们,Powershell 现在正在混合使用。我想知道 - 就像你一样 - 该可执行文件实际上在做什么。
  • 您是否尝试过将 GAC 依赖项包装在 MakeSfxCA.exe 生成的 CA dll 中?这是否可行,或者您是否会冒险从 GAC 加载旧版本 - 如果存在?如果版本不同应该可以吗?我不擅长托管代码。总是不确定,我讨厌它,以至于不测试它。那么为什么不选择菲尔的大脑呢? :-)
  • 为了分析问题,我在程序的最开始添加了一些跟踪日志记录——它不执行(除非是日志记录本身失败);在这一点上,还没有尝试对 HKCU、用户文件夹或工作目录做任何事情。我正在查看 WiX MakeSfxGA,但我不完全理解它的作用 - 这基本上是一种将所有依赖项包装在可执行文件本身中的方法吗?
【解决方案2】:

在我看来,您正在运行的文件没有必要的依赖项。例如,如果您运行一个 dll 并将其放在二进制表中,则该 dll 必须没有依赖关系。如果您指向随产品安装的 dll,则任何必要的依赖项都应存在于同一文件夹中。
这当然有解决方法,但与产品一起安装的一个限制是您可以将其按顺序放置,因为您必须等待您的东西安装好才能运行自定义操作。

【讨论】:

  • 该文件确实有许多依赖项 - 但据我所知,它们都已正确安装并在调用时存在。我不是从二进制表中执行的(除非我对操作类型有严重误解)——该限制是否适用于运行可执行文件的任何其他类型?
猜你喜欢
  • 1970-01-01
  • 2017-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多