[英]Comparing DateTime stamps in Msbuild
I am trying to compare two date times stamps in msbuild. 我想在msbuild中比较两个日期时间戳。 I have done the following:
我做了以下事情:
<CreateItem Include="@(Compile)->'@(Compile).cache'"
Condition="('%(Compile.ExcludeFromStyleCop)' != 'true') and ('%(Compile.ExcludeFromSourceAnalysis)' != 'true') and (@(Compile.ModifiedTime) > @(Compile.cache.ModifiedTime))">
<Output TaskParameter="Include" ItemName="StyleCopFiles"/>
</CreateItem>
However, it throws the following: 但是,它会引发以下情况:
error MSB4086: A numeric comparison was attempted on "@(Compile.ModifiedTime)" that evaluates to "@(Compile.ModifiedTime)" instead of a number, in condition "('%(Compile.ExcludeFromStyleCop)' != 'true') and ('%(Compile.ExcludeFromSourceAnalysis)' != 'true') and (@(Compile.ModifiedTime) > @(Compile.cache.ModifiedTime))".
错误MSB4086:尝试对“@(Compile.ModifiedTime)”进行数值比较,评估为“@(Compile.ModifiedTime)”而不是数字,条件为“('%(Compile.ExcludeFromStyleCop)'!='true' )和('%(Compile.ExcludeFromSourceAnalysis)'!='true')和(@(Compile.ModifiedTime)> @(Compile.cache.ModifiedTime))“。 [c:\\dev\\apt\\DotNetMvc\\src\\Apt.Lib.Data.Elmah\\Apt.Lib.Data.Elmah.csproj]
[C:\\ dev的\\易于\\ DotNetMvc \\ SRC \\ Apt.Lib.Data.Elmah \\ Apt.Lib.Data.Elmah.csproj]
How does one compare two date time stamps in msbuild? 如何比较msbuild中的两个日期时间戳?
Try to use inline task: (msbuild v4+ is required, I guess) (I didn't tested it) 尝试使用内联任务:(我想是msbuild v4 +)(我没有测试过)
<UsingTask
TaskName="CompareDates"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
<ParameterGroup>
<FirstDate ParameterType="System.DateTime" Required="true" />
<SecondDate ParameterType="System.DateTime" Required="true" />
<Result ParameterType=" "System.Int32" Output="true" />
</ParameterGroup>
<Task>
<Using Namespace="System"/>
<Code Type="Fragment" Language="cs">
<![CDATA[
Log.LogMessage("First Date: " + FirstDate, MessageImportance.High);
Log.LogMessage("Second Date: " + SecondDate, MessageImportance.High);
Result = DateTime.Compare(FirstDate, SecondDate);
]]>
</Code>
</Task>
</UsingTask>
Usage in MsBuild script: 在MsBuild脚本中的用法:
<CompareDates FirstDate="$(FirstDate)" SecondDate="$(SecondDate)">
<Output TaskParameter="Result" PropertyName="DateCompareResult"/>
</CompareDates>
<Copy Condition="$(DateCompareResult)=='0'" .../>
A much simpler solution here is to convert the DateTime object into an integer using a property function to access the Ticks property. 这里更简单的解决方案是使用属性函数将DateTime对象转换为整数以访问Ticks属性。
For a named file: 对于命名文件:
$([System.IO.File]::GetLastWriteTime('SomeFile.bin').Ticks)
Or from item metadata: 或者从项目元数据:
$([System.DateTime]::Parse('%(ItemGroup.ModifiedTime)').Ticks)
You can then compare items using conditional expressions like the following: 然后,您可以使用条件表达式比较项目,如下所示:
Condition="($([System.DateTime]::Parse('%(ItemGroup.ModifiedTime)').Ticks) > $([System.IO.File]::GetLastWriteTime('SomeFile').Ticks)))"
In the case of the question here, I believe this should work: 对于这里的问题,我认为这应该有效:
Condition="($([System.DateTime]::Parse('%(Compile.ModifiedTime)').Ticks) > ($([System.DateTime]::Parse('%(Compile.cache.ModifiedTime)').Ticks)"
Here is what we went with: 以下是我们的用途:
<UsingTask
TaskName="CompareDates"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
<ParameterGroup>
<FileList ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
<CacheFile ParameterType="System.String" Required="true" />
<Result ParameterType="Microsoft.Build.Framework.ITaskItem[]" Output="true" />
</ParameterGroup>
<Task>
<Using Namespace="System"/>
<Code Type="Fragment" Language="cs">
<![CDATA[
var modifiedFiles = new List<ITaskItem>();
//If the cache file exists, only return files that have been edited more recently than it
if(File.Exists(CacheFile))
{
DateTime cacheTimeStamp = File.GetLastWriteTime(CacheFile);
foreach(var file in FileList)
{
if(DateTime.Compare(DateTime.Parse(file.GetMetadata("ModifiedTime")), cacheTimeStamp) > 0)
{
modifiedFiles.Add(file);
}
}
Result = modifiedFiles.ToArray();
}
//Otherwise, return all files
else
{
Result = FileList;
}
]]>
</Code>
</Task>
</UsingTask>
We used it as follows: 我们用它如下:
<CompareDates FileList="@(Compile)" CacheFile="My.StyleCop.Cache">
<Output TaskParameter="Result" ItemName="ChangedFiles"/>
</CompareDates>
And updated the cache (after the stylecop task is executed): 并更新缓存(执行stylecop任务后):
<Touch
Files="My.StyleCop.cache"
AlwaysCreate="true"
Condition="'$(StyleCopViolationCount)' == '0'"/>
<CreateItem Include="Apt.StyleCop.cache">`enter code here`
<Output TaskParameter="Include" ItemName="FileWrites"/>
</CreateItem>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.