【问题标题】:VersionNT MSI property on Windows 10Windows 10 上的 VersionNT MSI 属性
【发布时间】:2015-11-03 03:21:42
【问题描述】:

我发现当我更新引导程序的清单以支持 Windows 10 兼容性时,MSI 的 InstallUISequence 将正确设置 VersionNT=1000,但 InstallExecuteSequence 将设置 VersionNT=603。

如何让 InstallExecuteSequence 也设置 VersionNT=1000?

【问题讨论】:

标签: wix windows-installer installshield


【解决方案1】:

微软官方回答:

在 Windows 10 或 Windows Server 2016 上安装 .msi 安装包时,VersionNT 值为 603。

Source

【讨论】:

  • 微软这么说,但实际上在 Windows 10 上并非如此。
【解决方案2】:

我发现检测 Windows 10 的一种非常简单且可靠的方法是调用内置 WMIC 命令并解析其输出:

wmic os get Name,Version,BuildNumber /VALUE

它会准确返回您需要确定您使用的操作系统的信息:

BuildNumber=14393

版本=10.0.14393

http://helpnet.flexerasoftware.com/installshield22helplib/helplibrary/whats_newIS2015.htm

在装有 Windows 10 的系统上,Windows Installer 属性 VersionNT 和 VersionNT64 表示 603,最初是作为 Windows 8.1 的版本号。因此,无法创建 .msi 包中专门针对 Windows 10 的条件。

从 Windows Installer 5.0 和 Windows 7 开始,.msi 中的 DLL 自定义操作 包被填充以阻止获取操作系统版本; API GetVersion、GetVersionEx 和 RtlGetVersion 返回 Windows 6.0.6000 的版本,原来是 6.0.6000 的版本号 Windows Vista。因此,也无法获得实际的 来自 DLL 自定义操作或来自 InstallScript 自定义操作(作为 DLL 实现)。

由于 Windows 安装程序中的上述行为,它不是 很容易检测到 .msi 所在的 Windows 版本 包正在运行

【讨论】:

    【解决方案3】:

    这是我的两分钱......

    我没有发现 VersionNT 属性非常有用。 VersionNT64 是: VersionNT64 .... 不是 VersionNT64 来确定位数。

    这有点小题大做(他们这样做,我们这样做......)但危急时刻需要采取危急措施......

    在 MSFT 正在玩的所有兼容性游戏中,它们似乎只是掩盖了主要和次要,但构建和修订。我还发现在 Win8 上将其掩码为 6.2,在 Win 10 上将其掩码为 6.3。所以我觉得这样做很舒服:

    <Property Id="WIN10FOUND">
      <DirectorySearch Id="searchSystem" Path="[SystemFolder]" Depth="0">
        <FileSearch Id="searchFile" Name="advapi32.dll" MinVersion="6.3.10000.0"/>
      </DirectorySearch>
    </Property>
    

    我倾向于问自己“为什么”我需要 Windows (FOO)?然后,我会查找一些注册表项或 DLL,以指示存在特定功能、组件、API 并将其用于我的测试。

    Microsoft 采用了一种常青的方法,即“您无需知道它是什么版本,您将始终拥有最新版本,并且它始终被称为 Windows 10”,对我来说,这强化了我更喜欢的方法拿。我知道有一天他们会出错,我确实需要知道否则我会安装,我的应用程序会失败,我的用户会抱怨并且不知道他们有什么版本。 (叹气……)

    【讨论】:

    • 我认为这是有道理的(或者至少是我们必须采用的最好方法)。我们的安装程序当前关闭 VersionNT 属性以在客户端机器中填充数据库表,以便服务器机器可以读取数据并向用户显示他们的每个客户端是什么(在列表中)。我们必须找到一些有意义的东西来开启前进的道路……
    • @jbudreau 当那些在 Windows 7 或更高版本上安装您的程序的人在没有全新安装的情况下升级 Windows 时,似乎只在安装中执行此操作会给您留下不准确的数据。如果将其移至应用程序,则可以同时解决这两个问题。
    • 同意。实际上,我刚刚进行了几次 Win 8.1 到 10 的升级,而且进展顺利。
    • 我对这个答案不满意,它不应该被信任。 SYSWOW64 中不存在用于 32 位安装的 Kernel32,并且其他 dll(例如 advapi32.dll)的版本号被屏蔽,从而干扰了 AppSearch。还有更多我似乎还不知道的内容。
    • 我仍然对答案底部的意见感到满意。
    【解决方案4】:

    对于没有引导程序的安装程序,我发现创建一个立即自定义操作调用GetVersionEx() 并设置一个属性供安装程序的其余部分使用也是一个不错的选择。 我已将我的自定义操作排序在 AppSearch 之后发生,使用它来调节组件就足够了。

    【讨论】:

    • 我不确定我想走这条路。在 MSDN 页面上,第一句话是“[GetVersionEx 可能已更改或在 Windows 8.1 之后的版本中不可用。相反,请使用 Version Helper API]”-msdn.microsoft.com/en-us/library/windows/desktop/…
    • @jbudreau - 你是对的。如果您的自定义操作是用 C++ 编写的,那么一定要使用 Version Helper API。但是,P/Invoke 无法从 .NET 自定义操作中使用它们。无论如何,无论自定义操作的实现是什么,关键是自定义操作不是在兼容模式下运行的,因此可以帮助确定操作系统的版本。
    • 此自定义操作如何成功?自定义操作在调用进程的上下文中运行,即 msiexec.exe,它没有 Win10 的清单,因此 GetVersion(Ex) API 返回相同的 6.3 结果。
    • @MikeKaganski,自定义操作由 rundll32.exe 运行。有清单吗?
    • 不,自定义操作由 m​​siexec.exe 运行,因此它们可以访问安装程序上下文,包括安装程序属性(可用于此类操作 - 例如延迟)等。
    【解决方案5】:

    由于 msiexec.exe 在其清单中没有 Windows 10 兼容性,并且 VersionNTprivate property,因此我知道没有干净的方法可以使执行序列参见 VersionNT=1000。我会推荐以下方法之一:

    • 在 UI 序列期间将VersionNT 复制到另一个属性(一些public propertyREALVERSIONNT;请务必将其列在SecureCustomProperties 中,就像您要传递给执行序列的任何其他属性一样),
    • 从您的引导程序(同上)传递实际值,或者
    • 如果您在维护或卸载期间需要相同的信息,可以在引导程序中设置一个注册表项,然后通过系统搜索将其值提取到安装中。

    (我对注册表项选项感到痛苦,因为如果将来升级操作系统,它可能会过时。请注意,所有这些选项可能只与引导程序中的清单一样正确Windows 的理论未来版本。)

    【讨论】:

    • 感谢您的建议。不幸的是,#1 不适用于静默安装,#2 和 #3 不适用于直接运行 MSI...
    • 既然你需要支持所有这些使用模式,嗯,祝你好运!我认为目前的答案是不可能的。可能还有其他工件需要寻找,但 Microsoft 已明确决定他们不希望人们在 Windows Installer 程序包中检测 Windows 10。 (我只是希望他们相应地更新 VersionNT 上的文档。)
    • 下面提供了我的两分钱。
    • 他们也应该更新 AppSearch。我用 minversion 10.0.0.0 搜索了一个 advapi32.dll,但没有检测到它。将 minvision 放到 6.0.0.0 并检测到它。 Explorer 说它的版本是 10.0.10240.16384。
    • WindowsBuild 和 MsiWin32AssemblySupport 属性也是谎言!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-14
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多