MSBuild任务中的Hashtable / Dictionary参数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MSBuild任务中的Hashtable / Dictionary参数相关的知识,希望对你有一定的参考价值。
我想在Dictionary
tas之间发送/分享Hashtable
或MSBuild
。
我有以下两个自定义任务,生成Hashtable的Get
和应该使用它的Set
。
Get.cs
public class Get : Task
{
[Output]
public Hashtable Output { get; set; }
public override bool Execute()
{
Output = new Hashtable();
return true;
}
}
Set.cs
public class Set : Task
{
[Required]
public Hashtable Output { get; set; }
public override bool Execute()
{
var items = Output.Cast<DictionaryEntry>().ToDictionary(d => d.Key.ToString(), d => d.Value.ToString());
foreach(var item in items)
{
//Do Something
}
return true;
}
}
以上课程可以很好地融入Assembly.dll
然后,我在以下构建目标脚本中使用该Assembly.dll
来调用Get和Set自定义任务:
MyTarget.targets
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="Get" AssemblyFile=".Assembly.dll"/>
<UsingTask TaskName="Set" AssemblyFile=".Assembly.dll"/>
<Target Name="Get">
<Get>
<Output TaskParameter="Output" ItemName="Output" />
</Get>
<Set Output=@(Output) />
</Target>
</Project>
当我使用上述目标MSBuild构建项目时显示以下错误:
MSBuild不支持“Get”任务的“Output”参数的“System.Collections.Hashtable”类型
如何在属性中使用Hashtable或Dictionary来执行自定义MSBuild任务?
可以进出任务的参数仅限于ITaskItem
或ITaskItem
的数组。
所以你的属性应该改变
public Hashtable Output { get; set; }
至
public ITaskItem[] Output { get; set; }
符合该要求。
接下来,您需要一个实现ITaskItem
的实现类。这允许您处理您的哈希集或字典。我为你添加了那个添加但是最小的KeyValue类看起来像这样:
public class KeyValue: ITaskItem
{
string _spec = String.Empty;
public KeyValue(string key, string value)
{
_spec = key;
metadata.Add("value", value);
}
Dictionary<string,string> metadata = new Dictionary<string,string>();
public string ItemSpec
{
get {return _spec;}
set {}
}
public ICollection MetadataNames
{
get {return metadata.Keys;}
}
public int MetadataCount
{
get {return metadata.Keys.Count;}
}
public string GetMetadata(string metadataName)
{
return metadata[metadataName];
}
public void SetMetadata(string metadataName, string metadataValue)
{
metadata[metadataName] = metadataValue;
}
public void RemoveMetadata(string metadataName)
{
}
public void CopyMetadataTo(ITaskItem destinationItem)
{
}
public IDictionary CloneCustomMetadata()
{
return metadata;
}
}
如果它是在平面MSBuild脚本中完成的,那么这个类将生成和看起来如此的Item:
<Item Include="key">
<value>some value</value>
</Item>
接下来,您可以调整Set和Get Task来使用这个新类KeyValue:
public class Set : Task
{
TaskLoggingHelper log;
public Set() {
log = new TaskLoggingHelper(this);
}
[Required]
public ITaskItem[] Output { get; set; }
public override bool Execute()
{
log.LogMessage("start set");
foreach(var item in Output)
{
log.LogMessage(String.Format("Set sees key {0} with value {1}.",item.ItemSpec, item.GetMetadata("value")));
}
log.LogMessage("end set");
return true;
}
}
public class Get : Task
{
// notice this property no longer is called Output
// as that gave me errors as the property is reserved
[Output]
public ITaskItem[] Result { get; set; }
public override bool Execute()
{
// convert a Dictionary or Hashset to an array of ITaskItems
// by creating instances of the class KeyValue.
// I use a simple list here, I leave it as an exercise to do the other colletions
Result = new List<ITaskItem> { new KeyValue("bar", "bar-val"), new KeyValue("foo","foo val") }.ToArray();
return true;
}
}
我用来测试上面代码的构建文件:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="Get" AssemblyFile=".cb.dll"/>
<UsingTask TaskName="Set" AssemblyFile=".cb.dll"/>
<Target Name="Get">
<Get>
<Output TaskParameter="Result" ItemName="GetResult" />
</Get>
<!-- lets see what we've got -->
<Message Importance="high" Text="key: @(GetResult) :: value: %(value)" />
<Set Output="@(GetResult)">
</Set>
</Target>
</Project>
运行时结果将是:
Build started 24-12-2017 21:26:17.
Project "C:Prjld est.build" on node 1 (default targets).
Get:
key: bar :: value: bar-val
key: foo :: value: foo val
start set
Set sees key bar with value bar-val.
Set sees key foo with value foo val.
end set
Done Building Project "C:Prjld est.build" (default targets).
Build succeeded.
0 Warning(s)
0 Error(s)
以上是关于MSBuild任务中的Hashtable / Dictionary参数的主要内容,如果未能解决你的问题,请参考以下文章
在Visual Studio中的MSBuild社区任务BeforeBuild步骤期间找不到路径中的xsd.exe
TransformXml 任务通过使用单声道的 Linux 上的 msbuild 失败