【问题标题】:Ant to start service if is not already startedAnt 启动服务(如果尚未启动)
【发布时间】:2016-05-13 16:40:58
【问题描述】:

我的要求是从 Ant 启动窗口服务。 这是我的代码:

<target name="copy">
    <exec executable="net">
        <arg value="START"/>
        <arg value="SomeService"/>          
    </exec>
</target>

如果服务还没有启动,它工作得很好。但是如果服务已经启动,它会返回异常 [exec] Result: 2

【问题讨论】:

  • 我相信,你应该先看看服务是否在运行,否则启动。查找here如何检查相同
  • ANT 是一个 java 构建工具。使用像 chef 这样的配置管理工具来管理服务器上的服务不是更合适吗?
  • 我不同意。 ANT 不仅仅用于构建 Java 应用程序。它通常适用于“引导任何类型的可以根据目标和任务来描述的过程”。因此,检查服务是否正在运行完全在 ANT 目标的范围内。

标签: ant windows-services


【解决方案1】:

(1) 使用 BAT 文件: 正如 Rao 的评论中所指出的,您可以编写一个批处理文件来检查服务是否正在运行,如果没有则启动它,如下所述:@987654321 @。这可以在ant 目标中使用&lt;exec&gt; 命令调用。


(2) 仅使用 ANT 目标: 或者,如果您不想要额外的批处理文件,您可以通过带有 &lt;exec&gt;ant 目标调用适当的单行命令通过cmd /C 发表声明。在我的示例中,服务名称是“JBossEAP7”,这将是需要替换您的服务名称的字符串。

<target name="run-jboss-service-if-not-already-running">
    <exec dir="bin/" executable="cmd" spawn="false" failonerror="true">
        <arg value="/c"/>
        <arg value="&quot;for /f &quot;tokens=3 delims=: &quot; %H in ('&quot;sc query JBossEAP7 | findstr &quot;STATE&quot;&quot;') do if not &quot;%H&quot;==&quot;RUNNING&quot; net START JBossEAP7 &quot;" />
    </exec>
</target>

此目标执行cmd,它调用sc query 来检查服务的状态(如此处所述https://*.com/a/3325123/14015737),如果状态不是RUNNING,则调用net START


(3) 使用一系列ANT目标:如果你不一定要启动服务,但要根据服务是否运行,或者是否有其他目标来做其他事情需要有条件地执行,你可以使用一系列依赖的ant目标来实现这个(在我的例子中,我仍然只是启动服务,但你可以做其他事情)。

<target name="check-jboss-service-running">
    <exec executable="cmd" spawn="false" failonerror="false" resultproperty="service.result">
        <arg value="/c"/>
        <arg value="&quot;for /f &quot;tokens=3 delims=: &quot; %H in ('&quot;sc query JBossEAP7 | findstr &quot;STATE&quot;&quot;') do if not &quot;%H&quot;==&quot;RUNNING&quot; exit /B 1&quot;" />
    </exec>
    <condition property="jboss-service.running">
        <equals arg1="0" arg2="${service.result}"/>
    </condition>
</target>

<target name="start-jboss-service" depends="check-jboss-service-running" unless="jboss-service.running">
    <exec executable="net" spawn="false" failonerror="true" resultproperty="net.result">
        <arg value="START"/>
        <arg value="JBossEAP7"/>
    </exec>
    <condition property="jboss-service.running">
        <equals arg1="0" arg2="${net.result}"/>
    </condition>
</target>

<target name="whatever-comes-next" depends="start-jboss-service" if="jboss-service.running">
    <echo>
        JBoss service is running
    </echo>
</target>

更多细节:

  • 第一个目标 (check-jboss-service-running) 再次运行 &lt;exec&gt; 语句,该语句执行 cmd 调用 sc query 来检查服务的状态。如果不是RUNNING,则退出cmd,返回1。接下来,根据返回码,jboss-service.running 属性在 &lt;condition&gt; 语句中是否设置。

  • 第二个目标 (start-jboss-service) 仅在属性 jboss-service.running 尚未设置时执行。它启动服务,如果成功,则在&lt;condition&gt; 语句中设置属性jboss-service.running

  • 一旦服务运行,第三个目标可以是您接下来想做的任何事情。仅当属性jboss-service.running 已设置时才会执行,这应该由第一个或第二个目标完成。


两句话:

(1) 当然还有“RUNNING”和“STOPPED”以外的状态。所以你的服务例如当前正在启动或关闭时,将执行 net 命令,即使您可能不希望这样做。

(2) 根据您正在检查或启动的服务,您可能需要引入延迟以确保该服务所做的一切实际上都已启动并正在运行。例如。在我的示例中,JBoss 可能正在运行,但在部署的 Web 应用程序响应之前需要额外的时间。

【讨论】: