每次登录时,程序都会尝试在 HKEY_LOCAL_MACHINE 注册表中配置安装参数

At each login the program tries to configure installation parameters in the HKEY_LOCAL_MACHINE registry

admin用户安装程序后,没有admin权限的不同用户登录同一台电脑会出现以下问题。

在管理员用户安装程序时,SQL 数据库的通用连接信息被写入 HKEY_LOCAL_MACHINE 注册表中的一个键一次(例如 (local)\sqlexpress) .然后注册表中的这个信息被admin手动修改为相关的数据库连接信息(eg. Remote_location\sqlexpress)。所以此信息是特定于机器的,而不是特定于用户的,因此程序可以运行并为每个用户从数据库中获取数据。

安装后,几个用户(非管理员)登录计算机以运行程序:

  1. 用户 1 登录,程序运行正常,它访问数据库。然后注销重新登录,下次程序运行正常。

  2. 然后用户2登录并启动程序。弹出一个消息框,上面写着“请稍候,Windows 配置程序”,并且无法连接到数据库,因为重新配置已经用注册表中的通用数据库连接数据覆盖了数据库连接,所以该程序找不到数据库。

  3. 所以我们将数据库设置导入注册表并重新启动程序,它可以很好地连接到数据库。用户注销并重新登录,程序运行。

  4. 然后用户 1 重新登录并且该程序无法使用相同的消息“请等待 Windows 配置程序”,即使它已经在工作并且 运行之前和用户 1 在一起。

该程序似乎只适用于一个用户!我们如何解决这个问题?为什么每次不同的用户尝试登录时 Windows 都尝试重新安装程序,尽管程序连接到数据库的信息位于注册表的公共计算机位置?

I have added some tags to the question, most notably for sql-server-express.

Chances are users familiar with this tool will know outright what the problem really is.


快速方法(首选,试试这个):

尝试在用户桌面上手动创建快捷方式以启动有问题的应用程序。对两个用户都这样做 - 不要启动应用程序的预先存在的快捷方式(它会触发我们试图避免的修复操作)。

这有可能以可接受的方式解决整个问题。但是,有一个问题:关于 SQL 连接字符串是否有任何特定于用户的内容? 它是否包含应因用户而异的用户名?我们可以看到实际的连接字符串吗?

您看到的很可能是 Windows 安装程序自我修复问题。他们可以参与可靠地修复。几乎可以肯定,部署包中有一个相当严重的错误会触发此问题。


分步方法(用于 MSI 包调试):

自行修复比较复杂,我觉得一步一步的调试方法可能比全面的解释更有效:

  1. 按照此处所述找到自我修复的触发器:Windows Installer launches unexpectedly, for no obvious reason.

  2. 记下事件日志中的 GUID:“检测到产品”,如上文所述。示例 GUID:{A54DCC30-E1EA-4912-A7F9-6C5A3AF1FB3A}(对于 IIS 10.0 Express - 只是一个示例,您的 GUID 将明显不同)。

  3. 现在运行以下PowerShell命令来确定您在事件日志中找到的产品代码的产品名称,并找到[=127的本地缓存MSI包=] 原始安装。 将下面的 GUID 替换为您的 GUID(启动 PowerShell:按住 Windows 键,点击 R,松开 Windows 键,键入在 "powershell" 中,然后按 OK 或按回车 )。 IdentifyingNumber 是 WMI 引用产品代码的方式,因此请将您自己的产品 G​​UID 放在该位置。

gwmi -Query "SELECT Name,LocalPackage FROM Win32_Product WHERE
IdentifyingNumber='{A54DCC30-E1EA-4912-A7F9-6C5A3AF1FB3A}'" | Format-Table Name,
LocalPackage

  1. 首选方案:复制"LocalPackage"指定的文件并将其上传到我们可以访问的地方并告知我们。包中有错误需要整理(可能并不容易)。不要碰 %SystemDrive%\Windows\Installer\*.* 里面的任何东西 - 这是一个根本不能乱动的 "super hidden" 文件夹。那里只有只读操作。非常重要。

  2. 或者:获取查看 MSI 文件的工具并自己进行检查。它需要一些 MSI 知识。

    • 一些 MSI 工具及其不同优点的完整描述:What installation product to use? InstallShield, WiX, Wise, Advanced Installer, etc(矫枉过正恕我直言)。
    • 如果您安装了 Visual Studio,您最快的选择可能是安装 Orca(MS SDK 工具)。只需搜索 Orca-x86_en-us.msi 并安装它 - 这是 Microsoft 自己的官方 MSI 查看器和编辑器。安装后你可以在开始菜单找到Orca。
    • 如果您没有安装 Visual Studio,您最快的选择可能是尝试 Super Orca(它使用起来很简单,但我没有进行广泛测试)。这是一个免费的(我上次检查过的)第三方 Orca 替代品。

Windows 安装人员自行修复

很可能您看到的是 Windows 安装程序自我修复。当系统以某种方式检测到安装不完整时,就会发生这种情况。在许多情况下,如果您让安装程序完成其 "repair",问题就会消失,但在某些情况下,安装程序包本身存在错误,导致出现与您所描述的类似的问题。

这是一个复杂的话题,我已经多次描述了如何调试自修复问题,最近一次在这里: .

为了将来参考,我添加了一些关于 Windows 安装程序自我修复或 "resiliency":

主题的链接
  • 自修复的综合解释,冗长综合How can I determine what causes repeated Windows Installer self-repair?
  • 以解决方案为中心的自我修复描述,试图找到现实世界的解决方案
  • 开发者自行修复问题,第一时间避免问题(或许也试试这个,应该是快速阅读专为开发人员编写的)。

基本上您不能安装将被用户更改的 KeyPath 注册表项,原因很简单 Windows 安装程序会认为它已损坏并修复它。

最简单的解决方法是为该组件(在您的 WiX 中)提供一个空组件 ID。正如她所说的文档,在 ComponentId 下:

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

ID 为空的组件未注册且无法修复。

您还应该通过查看 Windows 事件日志、应用程序并查找将引用损坏或丢失组件的 MsiInstaller 条目来验证实际丢失的组件是什么。可能真的有另一个组件似乎已损坏,例如另一个文件或注册表项。如果是这种情况,那么修复 HKLM 注册表项可能会产生下游影响,因为修复组件时 Windows 将修复并重新安装整个功能,并且可能包括 HKLM 条目。无论哪种方式,拥有可以更改的 HKLM 条目(在 MSI 中注册)都是不安全的,因为还有其他情况(例如从程序和功能修复或右键单击 MSI 文件)可以重写注册表条目。但是,要点是修复将替换该注册表项。