如何在ANT中检测Windows操作系统

6

我正在使用ant编译一个Java应用程序。问题是有些开发人员使用win7,而其他人使用XP和Vista。编译的一部分是使用WIX构建msi,在win7上这是一个目录,在XP和Vista上是另一个目录。

ant任务由Maven控制。我想知道如何在ant中使用条件标签区分Windows操作系统,以设置WIX目录。有什么想法吗?

我知道它的格式将是:

<if>
   <condition property="isWin7">
    Check for windows 7
   </condition>
   <then>
    set wix path to win 7 installation
   </then>
   <else>
    set to vista/xp wix installation
   </else>
 </if>

任何帮助都将是极好的。

可能是重复的问题:使用Ant检测操作系统并设置属性 - oers
我已经检查过了,但我想要做的是检查它是XP、Vista还是Win7,另一个选项只能让你知道它是否为Windows。 - Nathan
@Nathan - 你使用我的答案有没有什么进展?请标记为已接受,或给我留言,让我可以提供更多帮助。虽然这种技术在我们的生产构建系统中使用,但它可能无法解决你的问题。 - Richard Le Mesurier
1个回答

16

看起来ANT的<condition>可以测试操作系统的名称、家族和版本:

根据该链接,我们可以查询与操作系统相关的一些属性。其中一个是常用代码中使用的普通family属性:

<!-- CHECK FOR WINDOWS FAMILY OS -->
<condition property="is_windows">
    <os family="windows"/>
</condition>

我的ANT版本没有打印出${os.family}的解析值。

还有:

  • os.name <--- 这是你需要检查的
  • os.arch
  • os.version

这是我制作的一个演示脚本,用于展示这些属性的使用方法:
<?xml version="1.0" encoding="UTF-8"?>
<project name="Test" default="build" >

    <!-- CHECK FOR WINDOWS FAMILY OS -->
    <condition property="is_windows">
        <os family="windows"/>
    </condition>

    <condition property="is_windows_7">
        <os name="Windows 7"/>
    </condition>

    <!-- DISPLAYS WINDOWS OS -->
    <target name="display_windows" if="is_windows" >
        <echo message="OS Family is:       Windows" />
    </target>


    <target name="build" >

        <antcall target="display_windows" />

        <echo message="OS Name is:         ${os.name}" />
        <echo message="OS Architecture is: ${os.arch}" />
        <echo message="OS Version is:      ${os.version}" />

    </target>

</project>

自回答此问题以来,上述代码已被提升为我们的生产构建系统,在其中为Windows和Mac提供共享功能。

@thekbb提出了一个好建议,可以删除<antcall target="display_windows" />,并根据以下代码更新目标定义以依赖于display_windows

    <target name="build" depends="display_windows">

        <echo message="OS Name is:         ${os.name}" />
        <echo message="OS Architecture is: ${os.arch}" />
        <echo message="OS Version is:      ${os.version}" />

    </target>

这是因为 antcall 会在新的 JVM 中启动一个新的 ant 实例。一些用户可能会觉得这种优化更易于理解;而另一些用户可能出于性能原因而想要这样做。

1
如果您复制/粘贴此内容,请确保删除<antcall />并将构建目标更改为依赖于显示窗口目标。 antcall会在新的jvm中启动一个新的ant实例,以回显它是Windows。 - thekbb
@thekbb 谢谢你的提示。为什么在这个例子中分离出一个新副本是不好的呢?在ant中伪造方法调用的更好方法是什么? - Richard Le Mesurier
1
这在很大程度上是一种风格 - 我编辑了你的答案以显示我推荐的内容。如果你不同意,请编辑回去。当构建文件变得较大且存在散布的antcalls时,很难了解控制流如何在目标之间流动。在现代硬件上,启动新版本的ant的成本可以忽略不计。我在我的Mac上运行了每种方法,差异约为0.5秒。 - thekbb
更新问题以包括两个版本,包括您在评论中的解释。再次感谢。 - Richard Le Mesurier
这是一篇很好的文章,详细介绍了您可以根据操作系统触发逻辑的各种不同方式。http://boulderapps.co/running-different-ant-tasks-depending-on-the-operating-system - N D

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