我的TFS2012自定义构建工作流有许多自定义参数,这些参数在我的构建定义中定义。我想将它们全部传递给在构建期间运行的 exe(我知道自定义活动的选项,但我不能使用它,因为我不想每次都更改控制器的二进制文件)。
我设法拿buildDetail.ProcessParameters
并buildDetail.buildDefinition.ProcessParameters
,将它们写入文件并将它们传递给我的exe,它将解析它们(可能使用WorkflowHelpers.DeserializeProcessParameters
.但是,这意味着 exe 将需要合并两个ProcessParameters
,我想避免这种情况。
有没有办法从工作流程中获取生成的过程参数?我可以调用 WorkflowHelpers.GetProcessParameters(Activity),但是如何获取工作流的根活动?
我设法通过保持WorkflowInstanceProxy
来做到这一点,如此处建议:
public class WriteProcessParameters : CodeActivity
{
protected override void Execute(CodeActivityContext context)
{
WorkflowInstanceProxy proxy = context.GetExtension<WorkflowInstanceInfo>().GetProxy();
Activity root = proxy.WorkflowDefinition;
Dictionary<string, ProcessParameter> processParams = WorkflowHelpers.GetProcessParameters(root);
// Serialize processParams somehow...
}
protected override void CacheMetadata(CodeActivityMetadata metadata)
{
base.CacheMetadata(metadata);
metadata.AddDefaultExtensionProvider<WorkflowInstanceInfo>(() => new WorkflowInstanceInfo());
}
private class WorkflowInstanceInfo : IWorkflowInstanceExtension
{
private WorkflowInstanceProxy m_proxy;
public IEnumerable<object> GetAdditionalExtensions() { yield break; }
public void SetInstance(WorkflowInstanceProxy instance) { this.m_proxy = instance; }
public WorkflowInstanceProxy GetProxy() { return m_proxy; }
}
}
这在我的玩具测试中有效,但在实际的工作流程中无效(不知道为什么)。所以我最终阅读了属性,如下所示:
public InArgument<string> Filename { get; set; }
protected override void Execute(CodeActivityContext context)
{
var propDescriptors = context.DataContext.GetProperties().Cast<PropertyDescriptor>();
var props = new Dictionary<string, object>();
foreach (var propDesc in propDescriptors.OrderBy(p => p.Name))
{
object value = propDesc.GetValue(context.DataContext);
if (value == null)
{
var converter = TypeDescriptor.GetConverter(propDesc.PropertyType);
if (converter.CanConvertTo(propDesc.PropertyType))
{
value = converter.ConvertTo(value, propDesc.PropertyType); // Known case: null string
}
else
{
continue; // Known case: RunTestParameters
}
}
else
{
if (!value.GetType().IsVisible || !value.GetType().IsSerializable)
{
continue;
}
}
props.Add(propDesc.Name, value);
}
File.WriteAllText(Filename.Get(context), WorkflowHelpers.SerializeProcessParameters(props));
}