Service Manager 会自动执行各种信息技术 (IT) 流程。 例如,对于事件管理过程,Service Manager 包括各种自动化步骤,例如在创建或解决事件时向用户自动通知,以及基于分类自动将事件路由到各种队列。 这种自动操作的实施方式是使用为各种解决方案定义的工作流,并且它会使用 Windows Workflow Foundation (WF) 功能来描述、执行和跟踪自动操作。
客户和合作伙伴可通过定义新工作流并将其添加到过程中来扩展包括的自动操作。 工作流可以设置为按照固定的时间表发生或按照在数据库中指定的条件发生,例如,创建事件时或者事件被更改为诸如“活动” 或“已解决” 等指定状态时。
Service Manager 创作工具提供了一种易于使用的方法,用于创建新工作流。 它提供一个包含诸如创建事件或更新事件等各种不同工作流活动的库,以及一个可用于将这些工作流活动安排到一个工作流序列中的拖放图形设计器。 然后,创作工具将新工作流编译为一组定义、代码和管理包内容。 当此信息导入 Service Manager 时,它将新工作流集成到指定的解决方案中。
了解创作工具的幕后所发生的情况可让更高级的用户受益。 首先,客户和合作伙伴可以使用此信息将 Service Manager 中的工作流活动库扩展到应用于其特定进程的工作流活动。 其次,开发人员可以使用此信息来生成与 Service Manager 兼容的自定义或高级工作流,方法是使用所选的开发工具(例如Microsoft Visual Studio 开发系统)。
工作流活动和 WorkflowActivityBase 类
Service Manager 工作流使用 WF 活动。 若要顺利使用创作工具,这些活动派生自基类 WorkflowActivityBase,它属于 Microsoft.EnterpriseManagement.Workflow.Common 命名空间。 WorkflowActivityBase 基类引入了在 WF 活动的泛型活动基类中不可用的属性和方法。 有关如何使用泛型活动基类定义 WF 活动的详细信息,请参阅活动类。
使用 WorkflowActivityBase 类的好处
用户可以从 Visual Studio 活动库导入 WF 活动,并且可以在“创作工具 创作 ”窗格中处理这些活动。 不过,这些活动的行为方式与它们在 Visual Studio 设计环境中的行为方式相同。 它们没有集成在 Service Manager 活动库中的定制功能。
注意
并非所有 Visual Studio WF 活动都经过测试,以便与创作工具兼容,并且某些 Visual Studio WF 活动可能无法在创作工具中正确运行。
下表列出了基于 WorkflowActivityBase 基类的 WF 活动与基于泛型 活动 基类的 WF 活动之间的行为差异。
应用场景 | 创作工具 WF 活动(WorkflowActivityBase 基类) | Visual Studio WF 活动(活动 基类) |
---|---|---|
用户将活动属性绑定到服务管理器对象属性或其他活动的属性。 | 调用为 Service Manager 用户自定义的“属性绑定目标”对话框。 | 调用面向开发人员的“属性绑定目标”对话框。 |
用户将活动添加到“For-Each 循环” 活动中。 | 添加执行特定于循环的操作所需的属性 Propertytobind (循环索引)和 CurrentItem(CurrentItem 是一个内部属性)。 | 对循环的每个迭代的行为方式相同,并且不会与为循环编制索引的属性进行交互。 |
重要
由于创作工具工作流设计器所需的自定义项,基于 WorkFlowActivityBase 类的活动在 Visual Studio 工作流设计环境中无法按预期运行。
用户可以在 Visual Studio 中生成自定义 WF 活动,以便在创作工具中使用。 但是,若要利用创作工具的自定义设计时行为,自定义活动必须基于 WorkflowActivityBase 类而不是 Activity 类。
工作流活动和 Service Manager 自动化活动
WF 活动可与不同类型的活动、Service Manager 工作项所用的 Service Manager 活动进行交互。 工作项 是 Service Manager 使用的主要对象类型之一。 工作项跟踪诸如“事件” 、“服务请求” 、“更改请求” 等工作单位以及其他工作单位。 大多数工作项由一个或多个 Service Manager 的活动组成。 例如,“更改请求” 通常至少包括两项活动:“审阅” 活动和“更改执行” 活动。 工作项通常都是按顺序执行这些活动。
创建工作项时,第一个 Service Manager 活动将变为活动状态,并在 Service Manager(或用户)执行活动表示的任何工作时保持活动状态。 该工作完成后,Service Manager 会将第一个活动 标记为“已完成 ”,并激活序列中的下一个活动。 当序列中的最终活动标记为 “已完成”时,Service Manager 会将整个工作项标记为 “已完成”。
可以手动执行某些 Service Manager 活动,例如更改请求的“审阅”活动。 可以自动执行其他 Service Manager 活动,例如向用户发送电子邮件的活动。 可以自动执行“更改请求” 的“更改执行” 活动。 Service Manager 使用 WF 工作流自动执行 Service Manager 活动。
示例:将活动状态设置为“已完成”活动
Service Manager 中的 WF 工作流活动的此示例使用“将活动状态设置为‘已完成’”WF 活动。 此 WF 活动通常表示实现自动化 Service Manager 活动的工作流中的最后一个步骤,并将该活动的状态设置为 “已完成”。 设置此状态会触发系统进入到工作项中的下一项活动,此过程将重复进行,直到完成该工作项中的最后一项活动为止。
“ 将活动状态设置为已完成 ”活动采用一个输入, 即活动 ID,用于标识要对其执行操作的 Service Manager 活动。然后,WF 活动连接到 Service Manager 管理服务器,从数据库中检索指定的 Service Manager 活动,将其状态设置为 “已完成”,然后将其保存回数据库。 本例中包括的大多数代码示例均来自 SetActivityStatusToCompleted.cs 文件,这是一个用于描述“将活动状态设置为‘已完成’” 活动的基本文件。
初始化示例 WF 活动
SetActivityStatusToCompleted.cs 文件的第一部分包含声明和初始化语句。 此活动基于 WorkflowActivityBase 类,它使用验证程序类 SetActivityStatusToCompletedValidator 和设计器类 WorkflowActivityBaseDesigner。
WorkflowActivityBaseDesigner 类包含上一节“使用 WorkflowActivityBase 类的好处”中所述的自定义项。 可以进一步扩展和自定义此类。
此示例活动对应的活动定义的第一部分包括下列代码:
namespace Microsoft.ServiceManager.WorkflowAuthoring.ActivityLibrary
{
// ---------------------------------------------------------------------
/// <summary>
/// Activity to set an activity's status to complete
/// </summary>
// ---------------------------------------------------------------------
[ToolboxItem(typeof(ActivityToolboxItem))]
[ActivityValidator(typeof(Validators.SetActivityStatusToCompletedValidator))]
[Designer(typeof(WorkflowActivityBaseDesigner))]
public sealed partial class SetActivityStatusToCompleted : WorkflowActivityBase
{
示例 WF 活动的输入属性
该代码声明了一个属性 ActivityId作为依赖关系属性。 这意味着此属性可绑定到在工作流级别定义的参数。 在这种情况下,Service Manager 活动的 ID 作为工作流参数传入工作流,并作为输入流入此活动。
// --------------------------------------------------------------------------------
/// <summary>
/// Dependency Property for ActivityId property
/// </summary>
// --------------------------------------------------------------------------------
public static DependencyProperty ActivityIdProperty =
DependencyProperty.Register("ActivityId", typeof(String), typeof(SetActivityStatusToCompleted));
// --------------------------------------------------------------------------------
/// <summary>
/// Activity ID
/// </summary>
// --------------------------------------------------------------------------------
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public string ActivityId
{
get
{
return (string)this.GetValue(ActivityIdProperty);
}
set
{
this.SetValue(ActivityIdProperty, value);
}
}
示例 WF 活动中的执行行为
Execute 方法执行此 WF 活动的实际工作。 在 Execute 方法的范围内,WF 活动将执行下列操作:
检测它是否在 For-Each 循环 活动中运行,如果是,则设置相应的 WF 活动属性。
连接到指定的 Service Manager 管理服务器并创建 EnterpriseManagementGroup 对象。
使用ActivityId属性从数据库中获取已识别的 Service Manager 活动。
查找 Service Manager 活动的类定义,获取 检索到的 Service Manager 活动的 Status 属性,并将该属性设置为 “已完成 ”枚举列表值。
提交 Service Manager 活动更改。
使用 TrackData 方法(WF 基础结构的一部分)记录关于 WF 活动的执行和状态的跟踪信息。
// --------------------------------------------------------------------------------
/// <summary>
/// The execute method will have the implementation to set the activity status to complete.
/// </summary>
// --------------------------------------------------------------------------------
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
{
try
{
// Initialize the current item if the activity contained within the For-Each loop
base.Execute(executionContext);
// Validate Parameters
if (String.IsNullOrEmpty(ActivityId))
{
throw new ArgumentNullException("ActivityId");
}
string SMServer = "localhost";
Guid TaskGuid = new Guid(ActivityId);
EnterpriseManagementGroup _mg = new EnterpriseManagementGroup(SMServer);
EnterpriseManagementObject Activity = _mg.EntityObjects.GetObject
<EnterpriseManagementObject>(TaskGuid, ObjectQueryOptions.Default);
ManagementPack SystemMP = _mg.ManagementPacks.GetManagementPack(
SystemManagementPack.System);
ManagementPack ActivityMP = _mg.ManagementPacks.GetManagementPack(
Resources.ActivityManagementMP, SystemMP.KeyToken, SystemMP.Version);
ManagementPackClass activityClass = _mg.EntityTypes.GetClass(
Resources.WorkItemActivityClass, ActivityMP);
ManagementPackProperty status = activityClass.PropertyCollection["Status"];
ManagementPackEnumeration Completed =
_mg.EntityTypes.GetEnumeration("ActivityStatusEnum.Completed", ActivityMP);
Activity[status].Value = Completed;
Activity.Commit();
}
catch (ArgumentNullException argNullException)
{
// Log to Tracking Service
TrackData(argNullException.ToString());
throw;
}
catch (EnterpriseManagementException mgmtException)
{
TrackData(mgmtException.ToString());
throw;
}
return ActivityExecutionStatus.Closed;
}
}
}
示例 WF 活动中的验证行为
SetActivityStatusToCompletedValidator.cs 文件定义了 WF 活动的验证行为。 此行为定义了设计器如何指明此 WF 活动是已完全定义还是仍需定义一项或多项输入。 通过在“创作”窗格中的工作流活动上使用红色感叹号(“!”)图标,创作工具可类似于 Visual Studio 指示验证错误。
namespace Microsoft.ServiceManager.WorkflowAuthoring.ActivityLibrary.Validators
{
// --------------------------------------------------------------------------------
/// <summary>
/// Validator for the SetActivityStatusToCompleted activity
/// </summary>
// --------------------------------------------------------------------------------
internal class SetActivityStatusToCompletedValidator : ActivityValidator
{
// --------------------------------------------------------------------------------
/// <summary>
/// Validator for the SetActivityStatusToCompleted activity
/// </summary>
// --------------------------------------------------------------------------------
public override ValidationErrorCollection Validate(ValidationManager manager, object obj)
{
// Performing default validation
ValidationErrorCollection errorColl = base.Validate(manager, obj);
SetActivityStatusToCompleted setActivityStatusToCompletedObj =
(SetActivityStatusToCompleted)obj;
// Check if validation is happening during compilation of activity and
// not during the hosting of an activity
if (setActivityStatusToCompletedObj.Parent == null)
{
return errorColl;
}
string propertyName = Common.GetPropertyName(setActivityStatusToCompletedObj);
// Add validation error if ActivityId is null or empty
if (setActivityStatusToCompletedObj.ActivityId == null
&&
setActivityStatusToCompletedObj.GetBinding(SetActivityStatusToCompleted.ActivityIdProperty) == null
&&
String.Compare(propertyName, "ActivityId", false, CultureInfo.InvariantCulture) != 0)
{
errorColl.Add(new ValidationError(
Resources.SetActivityStatusToCompleted_ActivityId_DesignTimeValidation, 10, false));
}
return errorColl;
}
}
}
在工作流中使用示例 WF 活动
“创作工具默认活动工具箱”窗格中包括“将活动状态设置为已完成”活动。 有关将自定义活动添加到 “活动工具箱 ”窗格的详细信息,请参阅 “如何安装自定义活动程序集”。
可以使用创作工具的创作窗格以类似于使用 Visual Studio 工作流设计界面的方式创作工作流。 但是,创作工具具有以下优势:
没有开发技能的用户可以生成工作流;它们不必直接使用代码。
当用户在创作工具中保存工作流时,该工具将生成相应的 Visual C# 和 XOML 代码,并将其编译为.dll文件。 该工具还将工作流与可以直接与 Service Manager 交互的管理包集成。
工作流的 Visual C# 代码
以下示例展示了一段由创作工具为示例工作流生成的 Visual C# 代码,该工作流使用了 设置活动状态为已完成 的活动。 此代码声明一个简单的顺序工作流 SetActivityStatusToCompleteWF ,该工作流具有一个工作流参数,即依赖属性 ActivityId。 ActivityID 的值由本例中稍后显示的管理包定义确定。 当工作流运行时,Service Manager 会标识该值并将其传递到工作流中。
namespace WorkflowAuthoring
{
using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Serialization;
using System.Workflow.ComponentModel.Compiler;
using System.Drawing;
using System.Collections;
using System.Workflow.Activities;
using System.Workflow.Runtime;
public partial class SetActivityStatusToCompleteWF : System.Workflow.Activities.SequentialWorkflowActivity
{
public static DependencyProperty ActivityIdProperty = DependencyProperty.Register("ActivityId", typeof(string), typeof(SetActivityStatusToCompleteWF));
[System.ComponentModel.DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
[System.ComponentModel.BrowsableAttribute(true)]
[System.ComponentModel.CategoryAttribute("Misc")]
public string ActivityId
{
get
{
return ((string)(this.GetValue(ActivityIdProperty)));
}
set
{
this.SetValue(ActivityIdProperty, value);
}
}
}
}
工作流的 XOML 代码
WF 对有些工作流定义使用 XOML 格式。 对于示例工作流,创作工具创建了名为“SetActivityStatusToCompleteWF.xoml”的文件,内容如下:
<SequentialWorkflowActivity x:Class="WorkflowAuthoring.SetActivityStatusToCompleteWF" x:Name="SetActivityStatusToCompleteWF" xmlns:ns0="clr-namespace:Microsoft.ServiceManager.WorkflowAuthoring.ActivityLibrary;Assembly=Microsoft.ServiceManager.WorkflowAuthoring.ActivityLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/workflow">
<ns0:SetActivityStatusToCompleted ActivityId="{ActivityBind SetActivityStatusToCompleteWF,Path=ActivityId}" x:Name="setActivityStatusToCompleted1" PropertyToBind="{x:Null}" />
</SequentialWorkflowActivity>
SetActivityStatusToCompleteWF.xoml 声明工作流, SetActivityStatusToCompleteWF运行一个工作流活动,即“将活动状态设置为‘已完成’” 。 该活动具有一个输入参数 ActivityId,它从工作流的 ActivityId 属性中获取其值。
在管理包中声明工作流及其触发器条件
Service Manager 无法使用独立工作流.dll文件;工作流必须与管理包集成。 管理包定义了工作流应何时运行以及要使用哪些输入值。 在生成工作流代码并编译工作流.dll文件时,创作工具会将工作流相关信息添加到管理包。
示例工作流 SetActivityStatusToCompleteWF与名为 Woodgrove.AutomatedActivity.AddComputerToGroupMP.xml 的示例管理包相关联。 此管理包通过新的自动化 Service Manager 活动来扩展更改管理过程。 在执行更改管理操作的过程中,当新活动激活时,它会触发 SetActivityStatusToCompleteWF 工作流。
管理包定义工作流的触发器(当新的 Service Manager 活动更改状态时),并定义要用于 ActivityId 属性的值(新的 Service Manager 活动的唯一标识符)。 工作流运行时,它将新 Service Manager 活动的状态更改为 “已完成”。 请注意,在一个正常的工作流中,这将是工作流中其他 WF 活动执行另一项任务后的最后一个步骤。
管理包的 Monitoring 部分包含工作流的 Rule 定义。 反过来, Rule 定义具有 DataSource 元素和 WriteAction 元素两个部分。
对于示例工作流,DataSource 元素包含一个 Subscription 元素,该元素指定当 AddComputerToGroup 类(自定义 Service Manager 类)的实例将状态更改为 Active 时,工作流应运行。
<Monitoring>
<Rules>
<Rule ID="SetActivityToCompleteRule" Enabled="true" Target="SystemCenterLibrary!Microsoft.SystemCenter.SubscriptionWorkflowTarget" ConfirmDelivery="false" Remotable="true" Priority="Normal" DiscardLevel="100">
<Category>Notification</Category>
<DataSources>
<DataSource ID="DS" TypeID="Subscriptions!Microsoft.SystemCenter.CmdbInstanceSubscription.DataSourceModule">
<Subscription>
<InstanceSubscription Type="$MPElement[Name='AddComputerToGroup']$">
<UpdateInstance><Criteria><Expression><SimpleExpression>
<ValueExpression>
<Property State="Post">$Context/Property[Type='Activity!System.WorkItem.Activity']/Status$</Property>
</ValueExpression>
<Operator>Equal</Operator>
<ValueExpression>
<Value>$MPElement[Name='Activity!ActivityStatusEnum.Active']$</Value>
</ValueExpression>
</SimpleExpression></Expression></Criteria></UpdateInstance>
</InstanceSubscription>
<StartWatermark>1</StartWatermark>
<PollingIntervalInSeconds>60</PollingIntervalInSeconds>
<BatchSize>100</BatchSize>
</Subscription>
</DataSource>
</DataSources>
</Rule>
</Rules>
</Monitoring>
WriteAction 元素(特别是 Microsoft.EnterpriseManagement.SystemCenter.Subscription.WindowsWorkflowTaskWriteAction)定义了触发条件得以满足时该怎么做。 在此元素中, Subscription 元素标识了要运行的工作流程序集文件 (SetActivityStatusToCompleteWF.dll) 以及代表工作流 WorkflowTypeName的程序集中的类。
Subscription 元素还包括一个 WorkflowParameter 元素,该元素定义 ActivityId 属性,并使用语法 $Data/BaseManagedEntityId$将其绑定到 DataSource 元素中记录的 Service Manager 活动的唯一标识符。
WriteAction 元素还存储工作流的可选配置详细信息,例如工作流失败时重试次数、重试频率以及工作流在关闭前应运行的最大时间(以秒为单位)。
<WriteActions>
<WriteAction ID="WA" TypeID="Subscriptions!Microsoft.EnterpriseManagement.SystemCenter.Subscription.WindowsWorkflowTaskWriteAction">
<Subscription>
<WindowsWorkflowConfiguration>
<AssemblyName>SetActivityStatusToCompleteWF</AssemblyName>
<WorkflowTypeName>WorkflowAuthoring.SetActivityStatusToCompleteWF</WorkflowTypeName>
<WorkflowParameters>
<WorkflowParameter Name="ActivityId" Type="string">
$Data/BaseManagedEntityId$
</WorkflowParameter>
</WorkflowParameters>
<RetryExceptions></RetryExceptions>
<RetryDelaySeconds>60</RetryDelaySeconds>
<MaximumRunningTimeSeconds>300</MaximumRunningTimeSeconds>
</WindowsWorkflowConfiguration>
</Subscription>
</WriteAction>
</WriteActions>
导入管理包
要使工作流在特定 Service Manager 管理服务器上运行,与工作流相关的所有文件都必须驻留在该服务器上。 这些文件包括下面的文件:
WF 活动程序集文件。 如果仅使用 Service Manager WF 活动,则默认安装相应的文件。 如果使用自定义活动,请参阅 “如何安装自定义活动程序集”。
本例中的工作流程序集文件为 SetActivityStatusToCompleteWF.dll。 必须将此文件手动复制到 Service Manager 管理服务器。
本例中的管理包文件为 Woodgrove.AutomatedActivity.AddComputerToGroupMP.xml。 必须将此文件手动复制到 Service Manager 管理服务器。
所有文件都准备就绪后,将管理包导入 Service Manager。 可以使用mpimport.exe命令行工具或 Service Manager 控制台执行此操作。 导入管理包后,只要满足定义为其触发器的条件,工作流就可以运行。