MSBuild - wait for x seconds

橙三吉。 提交于 2021-01-26 23:13:12

问题


I have a MSBuild script that deploys a web app. It stops the current web app by copying a 'app_offline.htm' file to the server. After this it deletes other files then copies new ones to the server.

I need to add a delay between the copying of 'app_offline.htm' and the delete.

My current script throws errors as the files are still locked when the script tries to delete them.

What is the best way to do this in MSBuild?

My Stop task looks like this...

  <Target Name="Stop">
    <WriteLinesToFile File="$(DeployDirectory)\app_offline.htm" Lines="Offline for maintenance" Overwrite="true" Encoding="Unicode"/>
  </Target>

My Delete task looks like this...

  <Target Name="Clean">
    <ItemGroup>
      <Files Include="$(DeployDirectory)\**\*" Exclude="$(DeployDirectory)\app_offline.htm" />
      <Files Include="$(LogDirectory)\*" />
    </ItemGroup>
    <Delete Files="@(Files)" />
  </Target>

回答1:


There are multiple options available:

  1. MSBuild Community Tasks has built-in Sleep task. You can use it like this:

    <Import Project="$(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.Targets" />
    <Sleep Milliseconds="300" />
    
  2. MSBuild Extension Pack also contains built-in Thread task which offers Sleep functionality. Example of usage is here.

  3. Of course any kind of cmd-compatible wait can work as well via Exec command:

    • Already mentioned <Exec Command="ping -n 6 127.0.0.1 > nul" />
    • I also had <Exec Command="sleep 5" /> worked for me nicely.
  4. You can define MSBuild inline C# task for that purpose:

    <UsingTask TaskName="Sleep" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
      <ParameterGroup>
        <!-- Delay in milliseconds -->
        <Delay ParameterType="System.Int32" Required="true" />
      </ParameterGroup>
      <Task>
        <Code Type="Fragment" Language="cs">
          <![CDATA[
    System.Threading.Thread.Sleep(this.Delay);
    ]]>
        </Code>
      </Task>
    </UsingTask>
    
    ...
    
    <Sleep Delay="5000"/>
    



回答2:


You could use the Exec task to invoke one of the solutions from How to sleep for 5 seconds in Windows's Command Prompt? (or DOS), e.g. the ping is noniteractive so should work. Something like

<Exec Command="ping -n 6 127.0.0.1 > nul"/>
<Delete Files="@(Files)" />

Also see https://github.com/Microsoft/msbuild/issues/199: in the future the Delete task might get similar parameters as the Copy task has now. So another option is to use Copy with a retry count set to try to overwrite one of the files in use, and when that succeeds you know it's not in use anymore and can go on with the Delete:

<Copy SourceFiles="someFile" DestinationFile="$(DeployDirectory)\someFileInUse" 
      RetryDelayMilliseconds="1000" Retries="5"/>
<Delete Files="@(Files)" />

Of course both solutions fail if the timeout expires and the file is still in use but there's not which can be done about that without risking infinite waits.



来源:https://stackoverflow.com/questions/41188618/msbuild-wait-for-x-seconds

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!