WIX安装程序:防止在Windows Server 2012 R2上安装

3
我有一个WIX项目,必须只安装在Windows Server 2016(或更高版本)上。
根据微软文档,Windows Server 2016的VersionNT为603,Windows Server 2012的VersionNT为602。
Windows Server 2012R2的VersionNT从未被提及过。
当我使用以下代码行时: <Condition Message="!(loc.RequireServer2016)"><![CDATA[INSTALLED OR (VersionNT >= 603)]]></Condition> 它仍然允许我在Windows Server 2012R2上安装。
如何限制我的软件仅在Server 2016上安装,并防止其在Server 2012R2上安装?

为什么不使用Server 2012 R2?您支持2008 R2吗?只支持2016及以上版本吗?我喜欢因操作系统缺少某个功能而阻塞,而不是因为操作系统的名称/版本。 - Christopher Painter
2个回答

2
"INSTALLED" 应该翻译为 "已安装"。属性区分大小写,您必须在条件中修复它 - 否则条件的那部分将永远不会成立 - 即使产品已经安装。
其余条件实际上看起来不错。以下是一些确定问题的想法:
  1. WiX Source Element: 您确定您已将此条件包含在 WiX 源的正确位置吗?

  2. Versionlessness: 在 Windows 10 中,操作系统版本的检测方式发生了巨大变化。我不知道这是否也会影响到 Windows Server 2012R2。

    • 似乎总体思路是 Windows 现在是“无版本”(这个术语怎么样) - 这意味着 VersionNT 不一定会报告操作系统的正确版本!
    • 请阅读这个答案,而不是让我在这里重复: Windows 10 not detecting on installshield
为了确定在您的安装程序中VersionNT的真实值,我会使用其中两种方法之一来在运行时检查属性。后一种选项(日志记录)通常更快,更容易,而第一种选项允许您在安装程序运行时也评估复杂条件并使用Session.EvaluateCondition方法显示它们是否为真或为假(当条件复杂且令人困惑时,我会使用此方法调用,以便获得一些运行时证据表明这些条件的行为与我预期相符)。
  1. 属性调试器VBScript:我有一个属性调试器VBScript,我用它在运行时显示MSI文件的许多属性值,并评估条件以显示它们是否为真-如上所述。如果我是你,我会使用这样的脚本在运行时显示 VersionNT (和您想要检查的任何其他属性或条件)。

    • 建议不要在生产设置中使用VBScript-仅限调试RobWiX创作者 - 我同意他所有反脚本论点,但个人仍然得出结论,VBScript对于调试很有用-快速,简便,嵌入式源代码,无需编译。设置整个编译后的自定义操作以检索几个属性进行测试太耗时了(尽管使用“真正的代码”(例如C ++)进行调试会更好并更容易)。
    • 在公司环境中,由于嵌入式源代码,VBScript被广泛使用-您始终可以在MSI中找到真实的自定义操作源-而编译的自定义操作则可能无法使用您从中编译的源代码(由于技术事物的固有混乱性 - 在现实世界中)-这是非常糟糕的。
    • 另一个好处是VBScript的简单性以及企业应用程序打包人员如何更好地掌握复杂性,而不是C ++ / C#。但总体而言,脚本自定义操作总是会引起Rob提到的问题(反病毒阻止,调试差劲,缺乏适当的错误处理的编码不力等)。
    • 关键是在公司部署方案中,您将拥有安全软件/防病毒的控制权。您可以以逻辑方式处理问题,并进行微调,直到软件包可靠部署。
    • 最后,企业桌面是SOE-标准平台,变化性比普通PC少得多(可以处于更大的状态多样性,因此会看到更多的部署问题)。
    • 实际问题基本上是自定义操作全部,它们非常容易出错:为什么限制WiX / MSI设置中自定义操作的使用是个好主意?我想要的信息比您需要的要多得多。 故事的道德对我来说是:使用任何最快完成工作的方法,但不要认为脚本足以进行世界范围的生产代码分发
    • 对于企业部署,应该消除特别自定义操作脚本,改为经过充分测试的C ++自定义操作,并由自定义MSI表驱动,其产生完整声明,在安装期间应执行什么操作。
  2. 日志记录:只需为设置创建日志文件并在其中检查 VersionNT 的值即可。我喜欢为所有设置启用日志记录,如此处所述:{{link3:installsite.org on how to do logging}}-请参阅“全局适用于机器上的所有设置”部分)。尽管会影响性能,但我总是有一个日志文件准备好在 TEMP文件夹中进行调试。


    “属性调试器演示”: 这超出了您的要求,但我认为您可能会在服务器部署中遇到类似问题,并且我想向您快速演示如何在VBScript中评估MSI条件来调试此问题。
    您上面的条件通常太简单,不值得费这个劲,但这是处理非常复杂的条件的一般方法 - 例如,当您只想在修复或主要升级启动的卸载时运行自定义操作时 - 无论您多么努力地考虑事情,证明总是在测试中得出的。
    使用VBScript在运行时评估您的条件:
    MsgBox "Condition: " & CBool( Session.EvaluateCondition("Installed OR (VersionNT >= 603)"))
    

    这样的VBScript自定义操作可以按照您的愿望插入不同的顺序和位置。属性值可能会因为您的顺序 (!) 和安装模式(install, uninstall, repair, modify, self-repair, major upgrade (涉及一个MSI的安装和卸载), minor upgrade, minor upgrade patch, major upgrade patch等...)而有所不同,以及您是否在deferredimmediate 上下文中运行,或者是以静默交互方式运行,还有我可能忘记的任何变量 - MSI有很多移动部件。例如,如果您在UI序列的开头插入自定义操作,那么AppSearch尚未运行,某些属性尚未设置。如果需要,您还可以在administrative-advertisement-installation序列中插入属性调试结构。
    另外,可能还有一些测试条件:
    • "未安装且未检测到WIX升级"
    • "未安装且不包含REMOVE~="ALL""

    还有一些比较复杂的需要测试(这些条件不是我写的,来自于此处):

    • 已安装且(REMOVE!="ALL"或UPGRADINGPRODUCTCODE)
    • 未安装或已安装且(REMOVE!="ALL"或UPGRADINGPRODUCTCODE)

    希望这个概念清晰了。我有一个用于调试此类属性的VBScript,但它太大而且混乱,无法放在这里。


1

针对这篇关于Windows 10和Server 2016的VersionNT值价值的文章:

https://support.microsoft.com/en-us/help/3202260/versionnt-value-for-windows-10-and-windows-server-2016

我会从以下条件开始:
VersionNT=603且MsiNTProductType > 1
其中后者表示服务器系统:

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

除此之外,查看WindowsBuild属性,以查看它是否对Server 2016有用的值(或者您可以用来排除Server 2012的值)。您还可以查看调用GetSystemMetrics的自定义操作:

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

查看2012年是否设置了SM_SERVERR2。

您不需要包括Installed属性的条件。当您首次安装时,Installed值未设置。如果您尝试再次安装相同的MSI,则无法进入启动条件,因为Windows将看到此特定ProductCode已安装,并进入维护模式(修复、卸载、功能更改类型的内容)。因此,不清楚您为什么认为需要它。如果您需要确保启动条件仅在初始安装时应用,则在UI和执行序列中将条件“未安装”添加到LaunchConditions操作中。


使用“VersionNT=603 and MsiNTProductType > 1”仍然允许用户安装Windows Server 2012R2。这是我现在正在使用的确切代码。我想防止在Server 2012 R2上安装。 - Josh
嗨 Phil。我认为包含OR'd Installed属性是为了强制条件在原始安装后始终为真,这样在修改、修复或卸载时启动条件就永远不会为假(如果是无法卸载的包,则会陷入一个进退两难的境地- 也许可以看看这个答案)。比如,如果条件检查已经自安装以来已经卸载的运行时,则产品将拒绝卸载,因为启动条件为假。我认为这个“Installed tweak”是 Mensching / Arnson 所特有的 :-)。到蝙蝠车上去! - Stein Åsmul
Stein:我通常会在UI和执行序列的LaunchConditions操作中使用“未安装”条件来解决这个问题,以避免混淆实际条件的复杂值。 - PhilDW
有道理 - 应该是标准的吧?在修改、修复、打补丁或卸载模式下运行启动条件有意义吗?我猜如果(托管)自定义操作缺少运行时,它们无论如何都会崩溃?我发现启动条件很棘手。 - Stein Åsmul

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接