帮酷LOGO
0 0 评论
文章标签:workflow-engine  Source  开源  流程  

这个开源项目由 JetBrains赞助 。

  • 下载设置(Windows )- 9.8 MB
  • 下载设置(macOS )- 2.2 MB
  • 下载设置(Linux )- 513 KB
  • 下载设置(Android )- 1 MB
  • 的下载源- 13.1 MB
  • Wexflow在GitHub上

目录

  • 简介
  • Wexflow是一个ETL系统 ?
  • 为什么不是Workflow Foundation?
  • 先决条件
  • 如何安装 Wexflow
  • Windows
  • macOS
  • Linux
  • 如何卸载 Wexflow
  • Windows
  • macOS
  • Linux
  • 如何使用 Wexflow
  • 通用
  • Wexflow管理器
  • Wexflow网络管理员
  • Wexflow Android Manager
  • 工作流示例
  • 顺序工作流
  • 执行图
  • 流程图工作流程
  • 工作流事件
  • 如何创建自定义任务
  • 如何调试 Wexflow
  • Bug,功能
  • 使用代码
  • Wexflow Windows服务
  • Wexflow引擎
  • Wexflow管理器
  • Wexflow使用的库
  • 历史记录

  • 工作流程变得简单

介绍

Wexflow旨在使系统,应用程序和人员之间的自动化,工作流程,长期运行的流程和交互变得简单,直接和清晰。 Wexflow旨在使自动化,工作流程长时间运行的流程以及系统,应用程序和人员之间的交互变得简单,straitforward和清洁 。

工作流是一系列不同的步骤或阶段。 每个步骤都在Wexflow中建模为任务。 可以使用XML将任务可视地组合到工作流中。

顺序工作流:顺序工作流按顺序逐个执行一组任务 。

  • 顺序工作流顺序工作流按顺序逐个执行一组任务 。 任务按顺序执行,直到最后一个任务完成。 流程图工作流:流程图工作流是在它执行图中至少包含一个流程图 节点(If/While/Switch)的工作流 。
  • 流程图节点将流程图任务(执行作业后返回true或false的任务)和一组要按顺序逐行执行的任务作为输入, 任务执行的顺序可以通过修改流程图节点的执行图来改变。 工作流事件:在工作流完成它作业后,它最终结果是成功或警告或错误 。
  • 工作流事件在工作流完成它作业后,它最终结果是成功或警告或错误 。 如果最终结果是成功的,则触发OnSuccess事件。 如果它的最终结果是警告,则触发OnWarning事件。 如果它最终结果为错误,则触发OnError事件。 事件包含一组任务和/或流程节点,它们按顺序执行。 Wexflow manager:Wexflow提供了一个管理工作流的图形界面可以在 Windows , macOS ,Linux和Android上运行 。
  • Wexflow网络管理员:Wexflow可以通过它轻量级的Javascript API (~6Kb)托管在任何网站上,
  • Wexflow网络管理员Wexflow可以通过它轻量级的Javascript API (~6Kb)托管在任何网站上,
  • 监控:Wexflow中发生的一切都在日志文件中跟踪 。
  • 内置任务:Wexflow为不同类型的作业提供了32个内置任务。
  • 可扩展:用户可以在C#或VB中创建自己的自定义任务 。
  • 可扩展用户可以在C#或VB中创建自己的自定义任务 。

文件系统任务:这些任务允许在文件系统上创建,复制,移动,重命名或删除文件和目录 。

  • 文件系统任务这些任务允许在文件系统上创建,复制,移动,重命名或delete文件和目录 。 同步任务:此任务允许将本地或远程源目录的内容同步到本地或远程目标目录 。
  • 此任务使用Microsoft Sync Framework 2.1. 压缩任务:这些任务允许从文件集合中创建ziptar或 tar.gz 。
  • MD5任务:此任务允许生成文件集合的MD5总和 。
  • FTP任务:此任务允许通过 FTP FTPS(显式/隐式)或 SFTP List,上传,下载或删除的文件 。
  • FTP任务此任务允许通过 FTP FTPS(显式/隐式)或 SFTP List,上传,下载或delete文件 。 HTTP任务:此任务允许通过HTTP或HTTPS访问下载的文件。
  • XML任务:这些任务允许使用XML数据 。
  • XML任务这些任务允许使用XML数据 。 XSLT可以与XPath一起使用来生成XML文档。 支持XSLT1.0和 XSLT 2.0.
  • CSV任务:这些任务允许使用CSV数据。 XML可以与XSLT一起使用来验证。比较和合并CSV数据。 这样的结果可以用CSV或XML格式存储。
  • SQL任务:此任务允许执行SQL脚本。 此任务支持微软 SQL Server 。Microsoft Access 。Oracle 。MySql 。SQLite 。PostgreSQL和 Teradata 。 此任务可用于批量插入,数据库更新,数据库清理,重建索引,重组索引,缩小数据库,更新统计信息,传输数据库数据等,
  • WMI任务:此任务允许执行WMI查询。 结果可以XML格式存储。
  • 图像任务:此任务允许将图像转换为以下格式, Bmp,Emf,Exif,Gif,图标,Jpeg,Png,Tiff和 Wmf 。
  • 音频和视频任务: 这些任务允许通过FFMEG或VLC转换。剪切或编辑音频和视频文件。 这些任务还可用于执行自定义操作,如从视频文件生成图像和缩略图。
  • 电子邮件任务:此任务允许发送电子邮件的集合。
  • Twitter任务:这个任务允许发送一组 tweet 。
  • 进程任务:此任务允许启动计算机上的任何进程。
  • 等待任务:此任务允许等待指定的时间持续时间。
  • 脚本任务:这些任务允许执行用C#或VB编写的自定义任务。

在本文中你将学习如何安装Wexflow,如何卸载它如何使用它如何创建自定义任务,最后你将看到它是如何编码,

在使用代码的部分中详细解释了版本1.0.1的源代码 。 源代码自发布后已经改变了,但是,那部分将对Wexflow如何工作有一个清晰的概念。

Wexflow是一个ETL系统?

你可能认为Wexflow比工作流引擎更像是一个ETL系统。 Wexflow的思路是以一种可以做任何事的方式提供通用的功能。 Wexflow的精神是以一种可以做任何事的方式提供通用的功能。 为什么不是Workflow Foundation?

WF (Windows Workflow Foundation)是微软的一个用于定义,执行和管理工作流。

WF是一种专有解决方案,内置有限的活动。

WF是一个专有解决方案,并附带了有限数量的活动。

以下是 Wexflow vsWF的优点:

  • 开放源代码。
  • 带有32个内置任务。
  • if流程图节点可以位于If,while和Switch流程图节点内。
  • 一段时间流程图节点可以在If,while和Switch流程图节点内。
  • Switch流程图节点可以位于If,a while和Switch流程图节点内。
  • 切换流程图node可以在 If,一段时间和一个切换流程图节点内。
  • 可以在Wexflow引擎手动启动或启动时启动工作流,也可以定期启动工作流。
  • 提供用于管理在 Windows,macOS和Linux上工作的工作流的GUI 。
  • 提供用于管理工作流的Android应用程序。
  • 提供一个轻量级的JavaScript API,允许在任何网站中管理工作流。
  • 在Wexflow中发生的一切都在日志文件中。

前提条件

要使用 Wexflow,你需要具备以下基本技能,

  • XML
  • XPath
  • XSL

要创建自定义任务,你需要具备以下基本技能,

  • XML
  • 必要时要懂 XSL
  • 必要时 XSL
  • C#或 VB

但是,在设计模式下创建和编辑工作流程在todo列表中很快就会出现。 但是,在设计模式下创建和编辑工作流程在 todo List中很快就会出现 comming 。 Wexflow设计者旨在允许不熟悉XML的人使用Wexflow,以便他们可以轻松地创建和编辑他们的工作流程,

如何安装 Wexflow?

Windows

Wexflow支持. NET Framework4.0和更高版本。 Wexflow支持。NET框架4.0和更高版本。

1 。安装微软. NET Framework4.0或更高

2.安装Microsoft Sync Framework2.1同步可再发行文件(Synchronization- v2.1 -x86-ENU.msi在wexflow_setup_windows.zip中可用)。

3 . 安装Microsoft Sync Framework2.1提供程序服务可再发行程序(ProviderServices- v2.1 -x86-ENU.msi在wexflow_setup_windows.zip中可用)。

3 。安装Microsoft同步框架2.1提供程序服务可再发行程序(ProviderServices- v2.1 -x86-ENU.msi在wexflow_setup_windows.zip中可用)。

4.安装WexflowSetup.exe(在wexflow_setup_windows.zip中可用),

5.你可以选择创建桌面快捷方式:

6.单击安装执行安装:

7.最后,单击完成完成安装:

将在开始菜单中添加以下菜单:

安装Wexflow之后,将安装一个名为Wexflow的Windows服务,并且自动启动。 要启动Wexflow管理器,此Windows服务必须运行。 "Manager "菜单打开Wexflow Manager GUI。

"Web Manager "菜单打开Wexflow Web Manager。 "Documentation "菜单打开Wexflow的文档文件夹。 "Configuration "菜单打开Wexflow的配置文件夹。 "Logs "菜单打开当天的日志文件。 "日志"菜单将打开当日的日志文件。

macOS

Wexflow为管理可安装在macOS系统上的工作流提供了一个 GUI 。

Wexflow Windows服务提供了一个自动加载的web服务,它允许查询Wexflow引擎。 Wexflow Windows服务提供了一个自承载的web服务,它允许查询Wexflow引擎。

Wexflow Windows服务安装在Windows计算机上之后,按照以下步骤在macOS上安装Wexflow管理器,

安装 Mono

2.打开 Wexflow.dmg:

3 。将Wexflow拖放到应用程序文件夹中以安装。

4.通过修改设置选项 WexflowWebServiceUri in/Applications/Wexflow. app/Contents/MonoBundle/Wexflow.Clients.Eto.Manager.exe.config配置WexflowWeb服务 URI,

如果安装成功,则在启动应用程序时将显示以下窗口,

Linux

Wexflow为管理可以安装在Linux系统上的工作流提供了一个 GUI 。

若要在Linux上运行 Wexflow,必须在Windows计算机上安装 Wexflow Windows服务。 Wexflow Windows服务提供了一个自承载的web服务,它允许查询Wexflow引擎。

在Windows机器上安装 Wexflow Windows服务后按以下步骤在Linux上安装 Wexflow manager,

2.安装mono完成:

2.安装单声道完成:

sudo apt install mono-complete

5.通过修改Wexflow管理器配置文件中的设置选项WexflowWebServiceUri来配置Wexflowweb服务 uri,

sudo mv wexflow.tar.gz/opt/
cd/opt/
sudo tar -zxvf wexflow.tar.gz
sudo chmod +x/opt/wexflow/wexflow.sh
sudo ln -s/opt/wexflow/wexflow.sh/usr/local/bin/wexflow

5.通过修改Wexflow管理器配置file:中的设置选项WexflowWebServiceUri来配置Wexflowweb服务 uri,

sudo vim/opt/wexflow/Wexflow.Clients.Eto.Manager.exe.config 

6.运行Wexflow管理器:

wexflow

Wexflow提供了一个GUI,用于管理可安装在Android设备上的工作流程。

Android

Wexflow为管理可以安装在Android设备上的工作流提供了一个 GUI 。

若要在Andoird上运行 Wexflow,必须在Windows计算机上安装 Wexflow Windows服务。 Wexflow Windows服务提供了一个自承载的web服务,它允许查询Wexflow引擎。

Wexflow Windows服务安装在Windows计算机上安装后,按照以下步骤在Android设备上安装Wexflow管理器,

3 . 安装 wexflow.apk

4.启动Wexflow应用程序,并且通过设置菜单打开应用程序设置 ,

3 。安装 wexflow.apk

4 。启动Wexflow应用程序,并且通过设置菜单打开应用程序设置 ,

5.配置WexflowWeb服务 Uri:

好了,Wexflow应用程序已经准备好工作了,

如何卸载 Wexflow?

Windows

要卸载 Wexflow,只需从"Windows开始菜单>Wexflow"中单击"卸载"菜单。

但是,如果您不需要它们,可以手动删除它们。

卸载Wexflow后,不会删除文件夹的C:WexflowC:WexflowTesting,以防止用户定义工作流和测试方案被删除。 但是,如果您不需要日志,则可以删除日志文件。

也不会删除日志文件 C:Program FilesWexflowWexflow.log以跟踪Wexflow完成的最后一次操作。 但是,如果你不需要日志,则可以delete文件。

macOS

要从macOS计算机卸载Wexflow管理器,只需从应用程序文件夹中使用deleteWexflow应用程序即可。

Linux

要从一台Linux机器上卸载Wexflow管理器,请按如下步骤操作,

sudo rm/usr/local/bin/wexflow
sudo rm -rf/opt/wexflow

Android

要从Android设备卸载 Wexflow,只需打开设置>应用程序> Wexflow,然后卸载它。

如何使用 Wexflow?

常规

安装Wexflow后,将创建文件夹C:WexflowC:WexflowTesting 。 文件夹C:Wexflow包含以下元素,

  • Wexflow.xml,它是Wexflow引擎的主要配置文件。 Temp/,它是Wexflow的临时文件 。 C:Program FilesWexflowWexflow.Clients.WindowsService.exe.config
  • Workflows/,它包含XML格式的工作流。
  • Temp/,它是Wexflow的临时 foler 。

文件夹C:WexflowTesting包含测试方案的数据。

这些日志是用 C:Program FilesWexflowWexflow.log写的。 每天有一个日志文件。 旧的日志文件以这种格式保存 C:Program FilesWexflowWexflow.logyyyyMMdd

在工作流的配置文件下面:

<?xmlversion="1.0"encoding="utf-8"?><!-- This is the configuration file of a workflow. 
 A workflow is composed of:
 - An id which is an integer that must be unique.
 - A name which is a string that must be unique.
 - A description wich is a string.
 - A settings section which is composed of the following elements:
 - A launchType which is one of the following options:
 - startup: The workflow is launched when Wexflow engine starts.
 - trigger: The workflow is launched manually from the Wexflow manager.
 - periodic: The workflow is lauched periodically.
 - A period which is necessary for the periodic launchType. It is 
 a timeSpan in this format dd.hh:mm:ss. For example the period
 00.00:02:00 will launch the workflow every 2 minutes.
 - The enabled option which allows to enable or disable a workflow.
 The possible values are true or false.
 - A Tasks section which contains the tasks that will be executed by
 the workflow one after the other.
 - A Task is composed of:
 - An id which is an integer that must be unique.
 - A name wich is one of the options described in the tasks documentation.
 - A description which is a string.
 - The enable option which allows to enable or disable a task. The possible 
 values are true or false.
 - A collection of settings.
 - An ExecutionGraph section which contains the execution graph of the workflow.
 This section is optional and described in the samples section.--><Workflowxmlns="urn:wexflow-schema"id="$int"name="$string"description="$string"><Settings><Settingname="launchType"value="startup|trigger|periodic"/><Settingname="period"value="dd.hh:mm:ss"/><Settingname="enabled"value="true|false"/></Settings><Tasks><Taskid="$int"name="$string"description="$string"enabled="true|false"><Settingname="$string"value="$string"/><Settingname="$string"value="$string"/><!-- You can add as many settings as you want. --></Task><Taskid="$int"name="$string"description="$string"enabled="true|false"><Settingname="$string"value="$string"/><Settingname="$string"value="$string"/></Task><!-- You can add as many tasks as you want. --></Tasks><!-- This node is optional and described in the samples section. --><ExecutionGraph/></Workflow>

Taskname选项必须是下列值之一,

  • CsvToXml:此任务将CSV文件转换为XML文件。 输出XML文件的格式在任务的文档中描述。
  • FilesCopier:此任务将文件集合复制到目标文件夹。
  • FilesLoader此任务加载位于文件夹中或通过file选项的文件集合 。
  • FilesMover:此任务将文件集合移动到目标文件夹。
  • FilesRemover:此任务删除文件的集合。
  • Ftp此任务允许通过 FTP FTPS(显式/隐式)或 SFTP List,上传,下载或delete文件 。 此任务使用C#编写的开放源代码库。
  • ListEntities:此任务列出了日志任务中由工作流任务加载的所有实体。 此任务对于解决问题非常有用。
  • ListFiles:此任务列出了日志任务中由工作流任务加载的所有文件。 此任务对于解决问题非常有用。
  • MailsSender:此任务发送来自XML文件的电子邮件集合。 任务的文档中描述了输入XML文件的格式。
  • Md5此任务生成文件集合的MD5总和,并且将结果写入XML文件 。 输出XML文件的格式在任务的文档中描述。
  • Mkdir:此任务创建文件夹的集合。
  • ProcessLauncher:此任务启动进程。 如果进程生成文件作为输出,就可以将文件集合传递给任务,以便对于每个文件将通过该进程生成输出文件 。 阅读任务的文档以获得更多信息。
  • Rmdir:此任务删除文件夹的集合。
  • Touch:此任务创建一个空文件的集合。
  • Twitter:此任务从XML文件发送一个tweet集合。 任务的文档中描述了输入XML文件的格式。
  • XmlToCsv:此任务将XML文件转换为CSV文件。 任务的文档中描述了输入XML文件的格式。
  • Xslt:此任务转换一个XML文件。 使用XSLT1.0处理器或XSLT2.0处理器是可能的。
  • Zip:这个任务从一个文件集合创建一个zip归档。
  • Tar:此任务从文件集合创建tar存档。
  • Tgz:此任务从一个文件集合创建一个tar.gz存档。
  • Sql此任务通过Sql设置选项执行colletion的SQL脚本文件或简单的SQL脚本 。 它支持微软 SQL Server,Microsoft Access,Oracle,MySql,SQLite,PostgreSQL和 Teradata 。
  • Wmi:此任务执行WMI查询,并且将结果输出到XML文件中。 输出XML文件的格式在任务的文档中描述。
  • ImagesTransformer:此任务将图像文件的集合转换为指定格式。 输出格式可以是下列格式之一: Bmp,Emf,Exif,Gif,图标,Jpeg,Png,Tiff或 Wmf 。
  • Http此任务允许downoad文件通过HTTP或 HTTPS,
  • Sync此任务允许将本地或远程源目录的内容同步到本地或远程目标目录 。 此任务使用微软同步框架 2.1.
  • FilesRenamer:此任务允许重命名文件系统上的文件集合。 可以与ListFiles任务一起使用Xslt任务来创建新的文件名。 查看这些任务的文档和工作流示例 Workflow_FilesRenamer.xml,以了解如何完成这些任务。
  • Wait:此任务等待指定的时间持续时间。
  • FilesExist此任务检查是否存在文件和或目录的集合 。
  • FileExists这是一个流程图任务,用于检查文件系统上是否存在给定文件 。
  • Movedir此任务移动文件夹,并且允许覆盖目标文件夹 。
  • Now:这是一个流程图任务,它以指定格式检索当前日期。 此任务被设计用来在Switch流程图node中使用。
  • Workflow:此任务允许启动。挂起。恢复或停止工作流的List 。

要了解如何制作自己的工作流,可以查看C:WexflowWorkflows中的工作流示例,并阅读文档文件夹中可用的任务文件。 C:Program FilesWexflowDocumentation

如果在C:WexflowWorkflows中创建新工作流或删除或修改了现有工作流,则必须重新启动 Wexflow Windows服务,以便这些修改生效。

若要禁用工作流,可以将工作流的enabled设置选项设置为 false 。 如果要使工作流从Wexflow引擎加载的工作流的List中消失,就可以在C:WexflowWorkflows中创建名为disabled的目录,并且将该工作流移动到该目录,然后重新启动 Wexflow Windows服务 。

Wexflow管理器

Wexflow管理器是一个简单的应用程序,允许用户执行以下操作,

  • 查看Wexflow引擎加载的所有工作流。
  • 查看所选工作流(运行,挂起或禁用)的状态。
  • 启动工作流。
  • 停止工作流。
  • 要查看Wexflow中的内容,请在文本编辑器中打开日志文件 C:Program FilesWexflowWexflow.log,如 NotePad ,
  • 恢复工作流。

要查看Wexflow中的内容,请在文本编辑器中打开日志文件 C:Program FilesWexflowWexflow.log,如 NotePad++ 。, 记事本++将在日志文件填充时更新日志文件。

Wexflow网络管理器

Wexflow提供一个轻量级的JavaScript (~6Kb ),它允许Wexflow管理器在任何网站上托管。

Wexflow WebManager允许用户执行以下操作 ,

  • 查看Wexflow引擎加载的所有工作流。
  • 查看所选工作流(运行,挂起或禁用)的状态。
  • 启动工作流。
  • 停止工作流。
  • 挂起工作流。
  • 恢复工作流。

要在网站上主持Wexflow网站管理器,只需按如下步骤操作,

  • 参考wexflow.min.css和 wexflow.min. js:
    这些文件位于 C:Program FilesWexfowWeb Manager中,
  • 创建Wexflow的实例。

HTML源代码应如下所示:

<!DOCTYPEhtml><html><head><title>Wexflow</title><linkrel="stylesheet"type="text/css"href="css/wexflow.min.css"/><scripttype="text/javascript"src="js/wexflow.min.js"></script><scripttype="text/javascript"> window.onload = function () {
 new Wexflow("wexflow", "http://localhost:8000/wexflow/");
 };
 </script></head><body><divid="wexflow"style="position: absolute; top:0; right:0; bottom:0; left:0;"></div></body></html>

WexflowAndroid管理器

Wexflow提供了一个用于管理工作流的Android应用程序。

WexflowAndroid管理器允许用户执行以下操作,

  • 查看Wexflow引擎加载的所有工作流。
  • 查看所选工作流(运行,挂起或禁用)的状态。
  • 启动工作流。
  • 停止工作流。
  • 挂起工作流。
  • 恢复工作流。

工作流示例

在本节中将展示一些工作流样本以使最终用户熟悉Wexflow工作流 synthax 。

顺序工作流

工作流1

此工作流将发票上载到SFTP服务器,然后等待2天,然后通知客户。

<Workflowxmlns="urn:wexflow-schema"id="1"name="Workflow_Invoices"description="Workflow_Invoices"><Settings><Settingname="launchType"value="trigger"/><Settingname="enabled"value="true"/></Settings><Tasks><Taskid="1"name="FilesLoader"description="Loading invioces"enabled="true"><Settingname="folder"value="C:WexflowTestingInvoices"/></Task><Taskid="2"name="Ftp"description="Uploading invoices"enabled="true"><Settingname="protocol"value="sftp"/><!-- ftp|ftps|sftp --><Settingname="command"value="upload"/><!-- list|upload|download|delete --><Settingname="server"value="127.0.1"/><Settingname="port"value="21"/><Settingname="user"value="user"/><Settingname="password"value="password"/><Settingname="path"value="/"/><Settingname="selectFiles"value="1"/></Task><Taskid="3"name="Wait"description="Waiting for 2 days"enabled="true"><Settingname="duration"value="2.00:00:00"/></Task><Taskid="4"name="FilesLoader"description="Loading emails"enabled="true"><Settingname="file"value="C:WexflowTestingEmailsInvoices.xml"/></Task><Taskid="5"name="MailsSender"description="Notifying customers"enabled="true"><Settingname="selectFiles"value="4"/><Settingname="host"value="127.0.0.1"/><Settingname="port"value="587"/><Settingname="enableSsl"value="true"/><Settingname="user"value="user"/><Settingname="password"value="password"/></Task><Taskid="6"name="FilesMover"description="Moving invoices"enabled="true"><Settingname="selectFiles"value="1"/><Settingname="destFolder"value="C:WexflowTestingInvoices_sent"/></Task></Tasks></Workflow>

首先 , FilesLoader任务加载位于文件夹C:WexflowTestingInvoices中的所有发票,然后Ftp任务将它们上传到SFTP服务器,然后Wait任务等待2天然后FilesLoader任务以XML格式加载电子邮件,然后MailsSender任务发送电子邮件 。 最后,FilesMover任务将发票移动到文件夹 C:WexflowTestingInvoices_sent

工作流2

此工作流等待文件到达C:WexflowTestingWatchfolder1C:WexflowTestingWatchfolder2,然后将它们上载到FTP服务器,然后将它们移动到C:WexflowTestingSent文件夹。 此工作流每2分钟启动一次。

<Workflowxmlns="urn:wexflow-schema"id="2"name="Workflow_FilesSender"description="Workflow_FilesSender"><Settings><Settingname="launchType"value="periodic"/><Settingname="period"value="00.00:02:00.00"/><Settingname="enabled"value="true"/></Settings><Tasks><Taskid="1"name="FilesLoader"description="Loading files"enabled="true"><Settingname="folder"value="C:WexflowTestingWatchfolder1"/><Settingname="folder"value="C:WexflowTestingWatchfolder2"/></Task><Taskid="2"name="Ftp"description="Uploading files"enabled="true"><Settingname="protocol"value="ftp"/><!-- ftp|ftps|sftp --><Settingname="command"value="upload"/><!-- list|upload|download|delete --><Settingname="server"value="127.0.1"/><Settingname="port"value="21"/><Settingname="user"value="user"/><Settingname="password"value="password"/><Settingname="path"value="/"/><Settingname="selectFiles"value="1"/></Task><Taskid="3"name="FilesMover"description="Moving files to Sent folder"enabled="true"><Settingname="selectFiles"value="1"/><Settingname="destFolder"value="C:WexflowTestingSent"/></Task></Tasks></Workflow>

首先,FilesLoader任务加载文件夹C:WexflowTestingWatchfolder1C:WexflowTestingWatchfolder2中的所有文件,然后Ftp任务加载文件,并且将它们上载到FTP服务器。 最后,FilesMover任务将文件移动到文件夹 C:WexflowTestingSent

工作流3

此工作流transcodes通过FFMPEG将C:WexflowTestingWAV中的WAV文件转换为MP3格式,并将转换文件移动到 C:WexflowTestingMP3

<Workflowxmlns="urn:wexflow-schema"id="3"name="Workflow_ffmpeg"description="Workflow_ffmpeg"><Settings><Settingname="launchType"value="trigger"/><Settingname="enabled"value="true"/></Settings><Tasks><Taskid="1"name="FilesLoader"description="Loading WAV files"enabled="true"><Settingname="folder"value="C:WexflowTestingWAV"/></Task><Taskid="2"name="ProcessLauncher"description="WAV to MP3"enabled="true"><Settingname="selectFiles"value="1"/><!-- You need to install FFMPEG --><Settingname="processPath"value="C:Program Filesffmpegbinffmpeg.exe"/><!-- variables: {$filePath},{$fileName},{$fileNameWithoutExtension}--><Settingname="processCmd"value="-i {$filePath} -codec:a libmp3lame -qscale:a 2 {$output:$fileNameWithoutExtension.mp3}"/> 
 <Settingname="hideGui"value="true"/><Settingname="generatesFiles"value="true"/> 
 </Task><Taskid="3"name="FilesMover"description="Moving MP3 files from temp folder"enabled="true"><Settingname="selectFiles"value="2"/><Settingname="destFolder"value="C:WexflowTestingMP3"/></Task></Tasks></Workflow>

首先 , FilesLoader任务加载位于文件夹C:WexflowTestingWAV中的所有文件,然后ProcessLauncher任务通过指定正确的命令来启动每个文件的FFMPEG进程以创建MP3文件 。 最后,FilesMover任务将MP3文件移动到文件夹 C:WexflowTestingMP3

工作流4

此工作流等待WAV文件到达C:WexflowTestingWAV然后transcodes它们到MP3文件通过VLC然后将MP3文件上传到FTP服务器然后将WAV文件移动到 C:WexflowTestingWAV_processed 。 此工作流每2分钟启动一次。

<Workflowxmlns="urn:wexflow-schema"id="4"name="Workflow_vlc"description="Workflow_vlc"><Settings><Settingname="launchType"value="periodic"/><Settingname="period"value="00.00:02:00.00"/><Settingname="enabled"value="true"/></Settings><Tasks><Taskid="1"name="FilesLoader"description="Loading WAV files"enabled="true"><Settingname="folder"value="C:WexflowTestingWAV"/></Task><Taskid="2"name="ProcessLauncher"description="WAV to MP3"enabled="true"><Settingname="selectFiles"value="1"/><!-- You need to install VLC--><Settingname="processPath"value="C:Program FilesVideoLANVLCvlc.exe"/><!-- variables: {$filePath},{$fileName},{$fileNameWithoutExtension}--><Settingname="processCmd"value="-I dummy {$filePath} :sout=#transcode{acodec=mpga}:std{dst={$output:$fileNameWithoutExtension.mp3},access=file} vlc://quit"/><Settingname="hideGui"value="true"/><Settingname="generatesFiles"value="true"/></Task><Taskid="3"name="Ftp"description="Uploading MP3 files"enabled="true"><Settingname="protocol"value="ftp"/><Settingname="command"value="upload"/><Settingname="server"value="127.0.1"/><Settingname="port"value="21"/><Settingname="user"value="user"/><Settingname="password"value="password"/><Settingname="path"value="/"/><Settingname="selectFiles"value="2"/></Task><Taskid="4"name="FilesMover"description="Moving WAV files"enabled="true"><Settingname="selectFiles"value="1"/><Settingname="destFolder"value="C:WexflowTestingWAV_processed"/></Task></Tasks></Workflow>

首先 , FilesLoader任务加载位于文件夹C:WexflowTestingWAV中的所有文件,然后ProcessLauncher任务通过指定正确的命令来启动每个文件的VLC进程以创建MP3文件 。 然后Ftp任务加载由ProcessLauncher任务生成的MP3文件,然后将它们上传到FTP服务器。 最后,FilesMover任务将处理后的WAV文件移动到文件夹 C:WexflowTestingWAV_processed

工作流5

此工作流从FTP服务器下载特定的文件。 此工作流程首先列出位于服务器根目录的所有文件,然后通过 XSLT (LisFiles.xslt)标记要下载的特定文件,然后Ftp任务通过todo="toDownload"from="app4"标签下载文件,然后下载文件被移动到文件夹 C:WexflowTestingFtp_download

 
  
 < 
  
Workflow  
  
  
  
xmlns  
  
="  
  
urn:wexflow-schema"  
  
  
  
id  
  
="  
  
5"  
  
  
  
name  
  
="  
  
Workflow_Ftp_download_tag"  
  
  
  
description  
  
="  
  
Workflow_Ftp_download_tag"  
  
>  
  
 < 
  
Settings  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
launchType"  
  
  
  
value  
  
="  
  
trigger"  
  
  
  
/ 
  
>  
  
<!- -  
  
  
startup|trigger|periodic  
  
-->  
  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
enabled"  
  
  
  
value  
  
="  
  
true"  
  
  
  
/ 
  
>  
  
<!- -  
  
  
true|false  
  
-->  
  
  
 < 
  
/Settings  
  
>  
  
 < 
  
Tasks  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
1"  
  
  
  
name  
  
="  
  
Ftp"  
  
  
  
description  
  
="  
  
Listing files (FTP)"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
command"  
  
  
  
value  
  
="  
  
list"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
protocol"  
  
  
  
value  
  
="  
  
ftp"  
  
  
  
/ 
  
>  
  
<!- -  
  
  
ftp|ftps|sftp  
  
-->  
  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
server"  
  
  
  
value  
  
="  
  
127.0.1"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
port"  
  
  
  
value  
  
="  
  
21"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
user"  
  
  
  
value  
  
="  
  
user"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
password"  
  
  
  
value  
  
="  
  
password"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
path"  
  
  
  
value  
  
="  
  
/"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
2"  
  
  
  
name  
  
="  
  
ListFiles"  
  
  
  
description  
  
="  
  
Listing files"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
3"  
  
  
  
name  
  
="  
  
Xslt"  
  
  
  
description  
  
="  
  
Renaming and tagging files"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
selectFiles"  
  
  
  
value  
  
="  
  
2"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
xsltPath"  
  
  
  
value  
  
="  
  
C:WexflowXsltListFiles.xslt"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
version"  
  
  
  
value  
  
="  
  
2.0"  
  
  
  
/ 
  
>  
  
<!- -  
  
  
1.0 |2.0  
  
-->  
  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
removeWexflowProcessingNodes"  
  
  
  
value  
  
="  
  
false"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
4"  
  
  
  
name  
  
="  
  
Ftp"  
  
  
  
description  
  
="  
  
Downloading files"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
command"  
  
  
  
value  
  
="  
  
download"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
protocol"  
  
  
  
value  
  
="  
  
ftp"  
  
  
  
/ 
  
>  
  
<!- -  
  
  
ftp|ftps|sftp  
  
-->  
  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
server"  
  
  
  
value  
  
="  
  
127.0.1"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
port"  
  
  
  
value  
  
="  
  
21"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
user"  
  
  
  
value  
  
="  
  
user"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
password"  
  
  
  
value  
  
="  
  
password"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
path"  
  
  
  
value  
  
="  
  
/"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
selectFiles"  
  
  
  
todo  
  
="  
  
toDownload"  
  
  
  
from  
  
="  
  
app4"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
5"  
  
  
  
name  
  
="  
  
FilesMover"  
  
  
  
description  
  
="  
  
Moving files to Ftp_download"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
selectFiles"  
  
  
  
value  
  
="  
  
4"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
destFolder"  
  
  
  
value  
  
="  
  
C:WexflowTestingFtp_download"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
overwrite"  
  
  
  
value  
  
="  
  
true"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
/Tasks  
  
>  
  
 < 
  
/Workflow  
  
>  
 

粗略地说Ftp任务在正在运行的工作流实例中加载位于FTP服务器的根目录的List文件,然后ListFiles任务输出和包含所有加载文件的XML文件,然后Xslt任务将此XML作为输入,并且生成一个包含系统node的XML该系统名为<WexflowProcessing>,其中包含要标记和或重命名的文件的 List 。

要理解标签和重命名文件的工作方式,请参阅ListFilesXslt任务的文档。

下面是用于标记文件的XSLT ListFiles.xslt

<?xmlversion="1.0"encoding="utf-8"?><xsl:stylesheetversion="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:outputmethod="xml"indent="yes"/><xsl:templatematch="/"><root><WexflowProcessing><xsl:for-eachselect="//WexflowProcessing/Workflow/Files//File"><xsl:choose><xsl:whentest="@name = 'file1.txt'"><FiletaskId="{@taskId}"name="{@name}"renameTo="file1_renamed.txt"todo="toRename"from="app1"/></xsl:when><xsl:whentest="@name = 'file2.txt'"><FiletaskId="{@taskId}"name="{@name}"renameTo="file2_renamed.txt"todo="toSend"from="app2"/></xsl:when><xsl:whentest="@name = 'file3.txt'"><FiletaskId="{@taskId}"name="{@name}"renameTo="file3_renamed.txt"todo="toDownload"from="app3"/></xsl:when><xsl:whentest="@name = 'file4.txt'"><FiletaskId="{@taskId}"name="{@name}"renameTo="file4_renamed.txt"todo="toDownload"from="app4"/></xsl:when></xsl:choose></xsl:for-each></WexflowProcessing></root></xsl:template></xsl:stylesheet>

执行图

此工作流加载文件 C:WexflowTestingfile1.txt,然后将它上载到FTP服务器,然后将它移动到C:WexflowTestingSent文件夹。

 
  
 < 
  
Workflow  
  
  
  
xmlns  
  
="  
  
urn:wexflow-schema"  
  
  
  
id  
  
="  
  
6"  
  
  
  
name  
  
="  
  
Workflow_Ftp_upload"  
  
  
  
description  
  
="  
  
Workflow_Ftp_upload"  
  
>  
  
 < 
  
Settings  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
launchType"  
  
  
  
value  
  
="  
  
trigger"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
enabled"  
  
  
  
value  
  
="  
  
true"  
  
  
  
/ 
  
>  
  
 < 
  
/Settings  
  
>  
  
 < 
  
Tasks  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
1"  
  
  
  
name  
  
="  
  
FilesLoader"  
  
  
  
description  
  
="  
  
Loading files"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
file"  
  
  
  
value  
  
="  
  
C:WexflowTestingfile1.txt"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
2"  
  
  
  
name  
  
="  
  
Ftp"  
  
  
  
description  
  
="  
  
Uploading files"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
protocol"  
  
  
  
value  
  
="  
  
ftp"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
command"  
  
  
  
value  
  
="  
  
upload"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
server"  
  
  
  
value  
  
="  
  
127.0.1"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
port"  
  
  
  
value  
  
="  
  
21"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
user"  
  
  
  
value  
  
="  
  
user"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
password"  
  
  
  
value  
  
="  
  
password"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
path"  
  
  
  
value  
  
="  
  
/"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
selectFiles"  
  
  
  
value  
  
="  
  
1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
3"  
  
  
  
name  
  
="  
  
FilesMover"  
  
  
  
description  
  
="  
  
Moving files to sent folder"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
selectFiles"  
  
  
  
value  
  
="  
  
1"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
destFolder"  
  
  
  
value  
  
="  
  
C:WexflowTestingSent"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
/Tasks  
  
>  
  
 < 
  
ExecutionGraph  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
1"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
-1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
2"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
1"  
  
  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
3"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
2"  
  
  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
/ExecutionGraph  
  
>  
  
 < 
  
/Workflow  
  
>  
 

首先,FilesLoader任务加载文件C:WexflowTestingfile1.txt,然后Ftp任务加载该文件,并且将它上载到FTP服务器。 最后,FilesMover任务将该文件移动到文件夹 C:WexflowTestingSent

按照约定,要执行的第一个任务的父任务id必须始终为 -1. 此工作流的执行图将按以下顺序执行任务,

但是,如果执行图按如下方式修改:

 
  
 < 
  
ExecutionGraph  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
1"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
-1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
3"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
2"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
3"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
/ExecutionGraph  
  
>  
 

任务将按如下方式执行:

如果执行图按如下方式修改:

 
  
 < 
  
ExecutionGraph  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
3"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
-1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
2"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
3"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
1"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
2"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
/ExecutionGraph  
  
>  
 

任务将按如下方式执行:

执行图中禁止有两种情况:

  • 无限循环。
  • 并行任务。

下面是一个无限循环的例子:

 
  
 < 
  
ExecutionGraph  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
1"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
-1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
2"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
1"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
2"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
/ExecutionGraph  
  
>  
 

下面是并行任务的示例:

 
  
 < 
  
ExecutionGraph  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
1"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
-1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
2"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
3"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
/ExecutionGraph  
  
>  
 

流程图工作流

if

下面的工作流是由文件file.trigger触发的流程图工作流。 如果在文件系统上找到文件file.trigger,就此工作流程将文件file1.txt上传到FTP服务器,然后它将通知客户上载成功 。 否则,如果在文件系统上没有找到触发器 file.trigger,那么工作流将通知客户上传失败。

 
  
 < 
  
Workflow  
  
  
  
xmlns  
  
="  
  
urn:wexflow-schema"  
  
  
  
id  
  
="  
  
7"  
  
  
  
name  
  
="  
  
Workflow_If"  
  
  
  
description  
  
="  
  
Workflow_If"  
  
>  
  
 < 
  
Settings  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
launchType"  
  
  
  
value  
  
="  
  
trigger"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
enabled"  
  
  
  
value  
  
="  
  
true"  
  
  
  
/ 
  
>  
  
 < 
  
/Settings  
  
>  
  
 < 
  
Tasks  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
1"  
  
  
  
name  
  
="  
  
FilesLoader"  
  
  
  
description  
  
="  
  
Loading files"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
file"  
  
  
  
value  
  
="  
  
C:WexflowTestingfile1.txt"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
2"  
  
  
  
name  
  
="  
  
Ftp"  
  
  
  
description  
  
="  
  
Uploading files"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
protocol"  
  
  
  
value  
  
="  
  
ftp"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
command"  
  
  
  
value  
  
="  
  
upload"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
server"  
  
  
  
value  
  
="  
  
127.0.1"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
port"  
  
  
  
value  
  
="  
  
21"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
user"  
  
  
  
value  
  
="  
  
user"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
password"  
  
  
  
value  
  
="  
  
password"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
path"  
  
  
  
value  
  
="  
  
/"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
selectFiles"  
  
  
  
value  
  
="  
  
1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
3"  
  
  
  
name  
  
="  
  
FilesLoader"  
  
  
  
description  
  
="  
  
Loading emails (OK)"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
file"  
  
  
  
value  
  
="  
  
C:WexflowTestingEmailsEmails.xml"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
4"  
  
  
  
name  
  
="  
  
MailsSender"  
  
  
  
description  
  
="  
  
Notifying customers (OK)"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
selectFiles"  
  
  
  
value  
  
="  
  
3"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
host"  
  
  
  
value  
  
="  
  
127.0.0.1"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
port"  
  
  
  
value  
  
="  
  
587"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
enableSsl"  
  
  
  
value  
  
="  
  
true"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
user"  
  
  
  
value  
  
="  
  
user"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
password"  
  
  
  
value  
  
="  
  
password"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
5"  
  
  
  
name  
  
="  
  
FilesLoader"  
  
  
  
description  
  
="  
  
Loading emails (KO)"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
file"  
  
  
  
value  
  
="  
  
C:WexflowTestingEmailsEmails.xml"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
6"  
  
  
  
name  
  
="  
  
MailsSender"  
  
  
  
description  
  
="  
  
Notifying customers (KO)"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
selectFiles"  
  
  
  
value  
  
="  
  
5"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
host"  
  
  
  
value  
  
="  
  
127.0.0.1"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
port"  
  
  
  
value  
  
="  
  
587"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
enableSsl"  
  
  
  
value  
  
="  
  
true"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
user"  
  
  
  
value  
  
="  
  
user"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
password"  
  
  
  
value  
  
="  
  
password"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
99"  
  
  
  
name  
  
="  
  
FileExists"  
  
  
  
description  
  
="  
  
Checking trigger file"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
file"  
  
  
  
value  
  
="  
  
C:WexflowTestingfile.trigger"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
/Tasks  
  
>  
  
 < 
  
ExecutionGraph  
  
>  
  
 < 
  
If  
  
  
  
id  
  
="  
  
100"  
  
  
  
parent  
  
="  
  
-1"  
  
  
  
if  
  
="  
  
99"  
  
>  
  
 < 
  
Do  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
1"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
-1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
2"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
3"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
2"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
4"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
3"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
/Do  
  
>  
  
 < 
  
Else  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
5"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
-1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
6"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
5"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
/Else  
  
>  
  
 < 
  
/If  
  
>  
  
 < 
  
/ExecutionGraph  
  
>  
  
 < 
  
/Workflow  
  
>  
 

约定中,在<Do><Else>节点中执行的第一个任务的父任务id必须始终为 -1.

你可以在执行图中的任意位置添加If流程图节点。 此外,你可以按需要添加 mush 。 你还可以将它们添加到事件节点的OnSuccessOnWarningOnError中。

一个If可以在 IfWhileSwitch中。

while

此工作流由文件file.trigger触发。 当文件file.trigger存在时此工作流程将文件file1.txt上传到FTP服务器然后它将通知客户然后它将等待2天然后它将再次启动 。

 
  
 < 
  
Workflow  
  
  
  
xmlns  
  
="  
  
urn:wexflow-schema"  
  
  
  
id  
  
="  
  
8"  
  
  
  
name  
  
="  
  
Workflow_While"  
  
  
  
description  
  
="  
  
Workflow_While"  
  
>  
  
 < 
  
Settings  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
launchType"  
  
  
  
value  
  
="  
  
trigger"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
enabled"  
  
  
  
value  
  
="  
  
true"  
  
  
  
/ 
  
>  
  
 < 
  
/Settings  
  
>  
  
 < 
  
Tasks  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
1"  
  
  
  
name  
  
="  
  
FilesLoader"  
  
  
  
description  
  
="  
  
Loading files"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
file"  
  
  
  
value  
  
="  
  
C:WexflowTestingfile1.txt"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
2"  
  
  
  
name  
  
="  
  
Ftp"  
  
  
  
description  
  
="  
  
Uploading files"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
protocol"  
  
  
  
value  
  
="  
  
ftp"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
command"  
  
  
  
value  
  
="  
  
upload"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
server"  
  
  
  
value  
  
="  
  
127.0.1"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
port"  
  
  
  
value  
  
="  
  
21"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
user"  
  
  
  
value  
  
="  
  
user"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
password"  
  
  
  
value  
  
="  
  
password"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
path"  
  
  
  
value  
  
="  
  
/"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
selectFiles"  
  
  
  
value  
  
="  
  
1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
3"  
  
  
  
name  
  
="  
  
FilesLoader"  
  
  
  
description  
  
="  
  
Loading emails"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
file"  
  
  
  
value  
  
="  
  
C:WexflowTestingEmailsEmails.xml"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
4"  
  
  
  
name  
  
="  
  
MailsSender"  
  
  
  
description  
  
="  
  
Notifying customers"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
selectFiles"  
  
  
  
value  
  
="  
  
3"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
host"  
  
  
  
value  
  
="  
  
127.0.0.1"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
port"  
  
  
  
value  
  
="  
  
587"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
enableSsl"  
  
  
  
value  
  
="  
  
true"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
user"  
  
  
  
value  
  
="  
  
user"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
password"  
  
  
  
value  
  
="  
  
password"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
5"  
  
  
  
name  
  
="  
  
Wait"  
  
  
  
description  
  
="  
  
Waiting for 2 days..."  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
duration"  
  
  
  
value  
  
="  
  
02.00:00:00"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
99"  
  
  
  
name  
  
="  
  
FileExists"  
  
  
  
description  
  
="  
  
Checking trigger file"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
file"  
  
  
  
value  
  
="  
  
C:WexflowTestingfile.trigger"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
/Tasks  
  
>  
  
 < 
  
ExecutionGraph  
  
>  
  
 < 
  
While  
  
  
  
id  
  
="  
  
100"  
  
  
  
parent  
  
="  
  
-1"  
  
  
  
while  
  
="  
  
99"  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
1"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
-1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
2"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
3"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
2"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
4"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
3"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
5"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
4"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
/While  
  
>  
  
 < 
  
/ExecutionGraph  
  
>  
  
 < 
  
/Workflow  
  
>  
 

约定中,要在 <While> node中执行的第一个任务的父任务id必须始终为 -1.

你可以在执行图中的任意位置添加While流程图节点。 此外,你可以按需要添加 mush 。 你还可以将它们添加到事件节点的OnSuccessOnWarningOnError中。

一个While可以在 WhileIfSwitch中。

Switch

此工作流每24小时启动一次。 星期一,它将文件上传到一个FTP服务器上,周三它会通知客户。

 
  
 < 
  
Workflow  
  
  
  
xmlns  
  
="  
  
urn:wexflow-schema"  
  
  
  
id  
  
="  
  
43"  
  
  
  
name  
  
="  
  
Workflow_Switch"  
  
  
  
description  
  
="  
  
Workflow_Switch"  
  
>  
  
 < 
  
Settings  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
launchType"  
  
  
  
value  
  
="  
  
periodic"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
period"  
  
  
  
value  
  
="  
  
24.00:00:00"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
enabled"  
  
  
  
value  
  
="  
  
true"  
  
  
  
/ 
  
>  
  
 < 
  
/Settings  
  
>  
  
 < 
  
Tasks  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
1"  
  
  
  
name  
  
="  
  
Now"  
  
  
  
description  
  
="  
  
Getting current day"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
culture"  
  
  
  
value  
  
="  
  
en-US"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
format"  
  
  
  
value  
  
="  
  
dddd"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
2"  
  
  
  
name  
  
="  
  
FilesLoader"  
  
  
  
description  
  
="  
  
Loading files"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
file"  
  
  
  
value  
  
="  
  
C:WexflowTestingfile1.txt"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
3"  
  
  
  
name  
  
="  
  
Ftp"  
  
  
  
description  
  
="  
  
Uploading files"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
protocol"  
  
  
  
value  
  
="  
  
ftp"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
command"  
  
  
  
value  
  
="  
  
upload"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
server"  
  
  
  
value  
  
="  
  
127.0.1"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
port"  
  
  
  
value  
  
="  
  
21"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
user"  
  
  
  
value  
  
="  
  
user"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
password"  
  
  
  
value  
  
="  
  
password"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
path"  
  
  
  
value  
  
="  
  
/"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
selectFiles"  
  
  
  
value  
  
="  
  
1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
4"  
  
  
  
name  
  
="  
  
FilesLoader"  
  
  
  
description  
  
="  
  
Loading emails"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
file"  
  
  
  
value  
  
="  
  
C:WexflowTestingEmailsEmails.xml"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
5"  
  
  
  
name  
  
="  
  
MailsSender"  
  
  
  
description  
  
="  
  
Notifying customers"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
selectFiles"  
  
  
  
value  
  
="  
  
3"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
host"  
  
  
  
value  
  
="  
  
127.0.0.1"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
port"  
  
  
  
value  
  
="  
  
587"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
enableSsl"  
  
  
  
value  
  
="  
  
true"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
user"  
  
  
  
value  
  
="  
  
user"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
password"  
  
  
  
value  
  
="  
  
password"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
/Tasks  
  
>  
  
 < 
  
ExecutionGraph  
  
>  
  
 < 
  
Switch  
  
  
  
id  
  
="  
  
100"  
  
  
  
parent  
  
="  
  
-1"  
  
  
  
Switch  
  
="  
  
1"  
  
>  
  
 < 
  
Case  
  
  
  
value  
  
="  
  
Monday"  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
2"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
-1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
3"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
2"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
/Case  
  
>  
  
 < 
  
Case  
  
  
  
value  
  
="  
  
Wednesday"  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
4"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
-1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
5"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
4"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
/Case  
  
>  
  
 < 
  
Default  
  
  
  
/ 
  
>  
  
 < 
  
/Switch  
  
>  
  
 < 
  
/ExecutionGraph  
  
>  
  
 < 
  
/Workflow  
  
>  
 

约定中,要在Case/Default节点中执行的第一个任务的父任务id必须始终为 -1.

你可以在执行图中的任意位置添加Switch流程图节点。 此外,你可以按需要添加 mush 。 你还可以将它们添加到事件节点的OnSuccessOnWarningOnError中。

一个Switch可以在 WhileIfSwitch中。

工作流事件

此工作流将file1.txt上载到FTP服务器,并在成功时通知客户。

 
  
 < 
  
Workflow  
  
  
  
xmlns  
  
="  
  
urn:wexflow-schema"  
  
  
  
id  
  
="  
  
9"  
  
  
  
name  
  
="  
  
Workflow_Events"  
  
  
  
description  
  
="  
  
Workflow_Events"  
  
>  
  
 < 
  
Settings  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
launchType"  
  
  
  
value  
  
="  
  
trigger"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
enabled"  
  
  
  
value  
  
="  
  
true"  
  
  
  
/ 
  
>  
  
 < 
  
/Settings  
  
>  
  
 < 
  
Tasks  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
1"  
  
  
  
name  
  
="  
  
FilesLoader"  
  
  
  
description  
  
="  
  
Loading files"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
file"  
  
  
  
value  
  
="  
  
C:WexflowTestingfile1.txt"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
2"  
  
  
  
name  
  
="  
  
Ftp"  
  
  
  
description  
  
="  
  
Uploading files"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
protocol"  
  
  
  
value  
  
="  
  
ftp"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
command"  
  
  
  
value  
  
="  
  
upload"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
server"  
  
  
  
value  
  
="  
  
127.0.1"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
port"  
  
  
  
value  
  
="  
  
21"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
user"  
  
  
  
value  
  
="  
  
user"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
password"  
  
  
  
value  
  
="  
  
password"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
path"  
  
  
  
value  
  
="  
  
/"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
selectFiles"  
  
  
  
value  
  
="  
  
1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
3"  
  
  
  
name  
  
="  
  
FilesLoader"  
  
  
  
description  
  
="  
  
Loading emails"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
file"  
  
  
  
value  
  
="  
  
C:WexflowTestingEmailsEmails.xml"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
4"  
  
  
  
name  
  
="  
  
MailsSender"  
  
  
  
description  
  
="  
  
Notifying customers"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
selectFiles"  
  
  
  
value  
  
="  
  
3"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
host"  
  
  
  
value  
  
="  
  
127.0.0.1"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
port"  
  
  
  
value  
  
="  
  
587"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
enableSsl"  
  
  
  
value  
  
="  
  
true"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
user"  
  
  
  
value  
  
="  
  
user"  
  
  
  
/ 
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
password"  
  
  
  
value  
  
="  
  
password"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
/Tasks  
  
>  
  
 < 
  
ExecutionGraph  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
1"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
-1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
2"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
OnSuccess  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
3"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
-1"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
Task  
  
  
  
id  
  
="  
  
4"  
  
>  
  
 < 
  
Parent  
  
  
  
id  
  
="  
  
3"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
  
 < 
  
/OnSuccess  
  
>  
  
 < 
  
/ExecutionGraph  
  
>  
  
 < 
  
/Workflow  
  
>  
 

流程图事件节点<OnWarning><OnError>可以相同的方式使用。 可以将 IfWhileSwitch流程图节点放置在事件节点中。

这些是简单而且基本的工作流,可以让你了解如何制作自己的工作流。 但是,如果你在工作流程中涉及多个系统,应用程序和自动化则工作流程可能非常有趣 。

如何创建自定义任务?

自定义任务是工作流引擎中必须的,并且允许系统和应用程序交互。

要创建自定义任务 MyTask,你需要按如下方式进行操作,

  • 在 Visual Studio中创建一个类库项目,并且将它命名为 Wexflow.Tasks.MyTask
  • 引用程序集的Wexflow.Core.dlllog4net.dll 。 这些程序集位于 Wexflow C:Program FilesWexflow的安装文件夹中。
  • 创建实现抽象类Wexflow.Core.Task的公共类 MyTask

Wexflow.Tasks.MyTask代码应如下所示,

 
  
public  
  
class  
MyTask : Wexflow.Core. Task {  
public  
MyTask(XElement xe, Workflow wf) :  
base  
(xe, wf) {  
// 
  
Task settings goes here  
}  
public  
  
override  
  
void  
Run() {  
try  
{  
// 
  
Task logic goes here  
  
return  
  
new  
TaskStatus(Status.Success); }  
catch  
(ThreadAbortException) {  
throw  
; } } } 

每个任务完成任务后,都会返回一个TaskStatus对象。 TaskStatus由以下元素组成:

 
  
public  
Status Status {  
get  
;  
set  
; }  
public  
  
bool  
Condition {  
get  
;  
set  
; }  
public  
  
string  
SwitchValue {  
get  
;  
set  
; } 

Status可以是以下类型之一,

 
  
public  
  
enum  
Status { Success, Warning, Error } 

例如,如果任务对文件集合执行 opetation,如果该操作成功,那么它的Status应该是 Success 。 否则,如果该操作成功,而且其他文件失败,则它Status应为 Warning 。 否则,如果该操作失败,那么它的Status应该是 Error

Condition属性是为流程图任务设计的。 除了任务的Status外,流程图任务在执行操作后,还返回truefalse

对于顺序任务 , Condition属性应始终设置为 false

SwitchValue被设计为Switch流程图节点使用。 如果在SwitchValue属性中设置值,并且在Switch流程图node中使用此任务,则对应于该值的大小写将被执行。 否则,如果设置了Default案例,它将被执行。

你可以使用符合你需要的TaskStatus构造函数。

若要检索设置,可以使用以下方法:

 
  
string  
settingValue =  
this  
.GetSetting (  
"  
  
settingName"  
) ;  
string  
settingValue =  
this  
.GetSetting (  
"  
  
settingName"  
, defaultValue) ; string [] settingValues =  
this  
.GetSettings (  
"  
  
settingName"  
) ; 

要通过selectFiles设置选项选择工作流运行实例加载的文件,可以按如下方式执行,

 
FileInf [] files =  
this  
.SelectFiles() ; 

要通过selectEntities设置选项选择由工作流运行实例加载的实体,可以按如下方式执行操作,

 
Entity [] entities =  
this  
.SelectEntities() ; 

Entity类在处理来自数据库或Web服务的对象的自定义任务时非常有用,例如,

要在任务中加载文件,可以按如下方式执行该操作,

 
  
this  
.Files.Add (  
new  
FileInf(path,  
this  
.Id)) ; 

要在任务中加载实体,可以按如下方式执行该操作,

 
  
this  
.Entities.Add(myEntity) ; 

最后,如果编写完自定义任务,编译类库项目,并且在 C:Program FilesWexflow中复制程序集 Wexflow.Tasks.MyTask.dll 。 然后,你的自定义任务就可以按如下方式使用,

 
  
 < 
  
Task  
  
  
  
id  
  
="  
  
$int"  
  
  
  
name  
  
="  
  
MyTask"  
  
  
  
description  
  
="  
  
My task description"  
  
  
  
enabled  
  
="  
  
true"  
  
>  
  
 < 
  
Setting  
  
  
  
name  
  
="  
  
settingName"  
  
  
  
value  
  
="  
  
settingValue"  
  
  
  
/ 
  
>  
  
 < 
  
/Task  
  
>  
 

这就对了这就是开始编写自己的自定义任务所需要知道的所有事情 。

如何调试 Wexflow?

要调试 Wexflow,请按如下步骤操作:

  • 安装微软净框架4.0或更高
  • 安装微软同步框架 2.1 SDK 。 你可以从这里下载,
  • 安装 Visual Studio2010或更高版本。
  • 将文件夹的"wexflow"和"wexflowtesting"复制到C: 。 你可以从这里下载,

Wexflow Windows服务

要调试 Wexflow Windows服务(wexflow.clients.windowsservice项目),请在"propject设置>调试>启动选项"中添加"调试"命令行参数,

Wexflow管理器

要调试Wexflow管理器(wexflow.clients.manager项目),请在"propject设置>调试>启动选项"中添加"调试"命令行参数,

Bug和特性

如果你发现Wexflow有任何问题,请在问题追踪器提交Bug报告。 请包括以下内容:

  • 你正在使用的Wexflow的版本。
  • 如何重现(step-by-step的描述)问题。
  • 预期结果。

如果你想添加一个特性请求,请添加一些细节,它应该如何工作。

使用代码

在本节中将详细解释版本1.0.1的源代码 。 源代码自发布后已经改变,但是,这一节将对Wexflow如何工作起到一个。

Wexflow源代码很容易理解。 源代码项目按如下方式组织:

Wexflow.Clients解决方案文件夹包含 Wexflow Windows服务和Wexflow管理器。 Wexflow.Core解决方案文件夹包含 Wexflow Wexflow.Core的核心程序集Wexflow.Core.Service.Contracts中的WCF服务契约和Wexflow.Core.Service.Client中的WCF代理 。 Wexflow.Tasks包含Wexflow任务。

Wexflow Windows服务

Wexflow使用承载WCFWeb服务的Windows服务。 当 Wexflow Windows服务启动WexflowEngine的新实例时,就运行方法 Run() 。 WCF网络服务允许执行以下操作:

  • 获取由WexflowEngine加载的工作流的List 。
  • 从工作流标识中获取WorkflowInfo对象。
  • 从工作流标识启动工作流。
  • 从工作流标识停止工作流。
  • 从工作流标识挂起工作流。
  • 从工作流标识恢复工作流。

在 Wexflow Windows服务的源代码下面。

 
  
public  
  
partial  
  
class  
WexflowWindowsService : ServiceBase { public  
static  
  
string  
SETTINGS_FILE = ConfigurationManager.AppSettings [  
"  
  
WexflowSettingsFile"  
]; public  
static  
WexflowEngine WEXFLOW_ENGINE =  
new  
WexflowEngine(SETTINGS_FILE); private ServiceHost _serviceHost =  
null  
; public WexflowWindowsService() { InitializeComponent(); this.ServiceName =  
"  
  
Wexflow"  
; WEXFLOW_ENGINE.Run(); } public  
void  
OnDebug() { this.OnStart (  
null  
); } protected  
override  
  
void  
OnStart(string [] args) { if (  
this  
._serviceHost!=  
null  
) { this._serviceHost.Close(); }  
// 
  
Create a ServiceHost for the WexflowService type and  
  
// 
  
provide the base address.  
this._serviceHost =  
new  
ServiceHost (  
typeof  
(WexflowService)) ;  
// 
  
Open the ServiceHostBase to create listeners and start  
  
// 
  
listening for messages.  
this._serviceHost.Open(); } protected  
override  
  
void  
OnStop() { if (  
this  
._serviceHost!=  
null  
) { this._serviceHost.Close(); this._serviceHost =  
null  
; } } } 

WexflowSettingsFile默认为 C:WexflowWexflow.xml

ServiceHost用于在 Wexflow Windows服务中承载 WexflowService WCFWeb服务。

WexflowService源代码下面。

 
  
[  
  
ServiceContract(Namespace =  
"  
  
http://WexflowService/"  
)  
]  
  
  
public  
  
interface  
IWexflowService { [OperationContract] string Hello(); [OperationContract] WorkflowInfo [] GetWorkflows(); [OperationContract] void StartWorkflow (  
int  
workflowId); [OperationContract] void StopWorkflow (  
int  
workflowId); [OperationContract] void SuspendWorkflow (  
int  
workflowId); [OperationContract] void ResumeWorkflow (  
int  
workflowId); [OperationContract] WorkflowInfo GetWorkflow (  
int  
workflowId) ; } [ServiceBehavior(IncludeExceptionDetailInFaults =  
true  
) ]  
public  
  
class  
 WexflowService:IWexflowService { public  
string  
Hello() { return  
"  
  
Hello!"  
; } public WorkflowInfo [] GetWorkflows() { List <WorkflowInfo> wfis =  
new  
List <WorkflowInfo> (); foreach (Workflow wf  
in  
WexflowWindowsService.WEXFLOW_ENGINE.Workflows) { wfis.Add (  
new  
WorkflowInfo(wf.Id, wf.Name, wf.LaunchType, wf.IsEnabled, wf.Description, wf.IsRunning, wf.IsPaused)); } return wfis.ToArray(); } public  
void  
StartWorkflow (  
int  
workflowId) { WexflowWindowsService.WEXFLOW_ENGINE.StartWorkflow(workflowId); } public  
void  
StopWorkflow (  
int  
workflowId) { WexflowWindowsService.WEXFLOW_ENGINE.StopWorkflow(workflowId); } public  
void  
SuspendWorkflow (  
int  
workflowId) { WexflowWindowsService.WEXFLOW_ENGINE.PauseWorkflow(workflowId); } public  
void  
ResumeWorkflow (  
int  
workflowId) { WexflowWindowsService.WEXFLOW_ENGINE.ResumeWorkflow(workflowId); } public WorkflowInfo GetWorkflow (  
int  
workflowId) { Workflow wf = WexflowWindowsService.WEXFLOW_ENGINE.GetWorkflow(workflowId); return  
new  
WorkflowInfo(wf.Id, wf.Name, wf.LaunchType, wf.IsEnabled, wf.Description, wf.IsRunning, wf.IsPaused); } } 

在 Wexflow Windows服务的system.serviceModel配置下。

 
  
 < 
  
 system.serviceModel  
  
>  
  
 < 
  
services  
  
>  
  
 < 
  
service  
  
  
  
behaviorConfiguration  
  
="  
  
WexflowServiceBehavior"  
  
  
  
name  
  
="  
  
Wexflow.Clients.WindowsService.WexflowService"  
  
>  
  
 < 
  
endpoint  
  
  
  
address  
  
="  
  
"  
  
  
  
binding  
  
="  
  
wsHttpBinding"  
  
  
  
contract  
  
="  
  
Wexflow.Clients.WindowsService.IWexflowService"  
  
  
  
/ 
  
>  
  
 < 
  
endpoint  
  
  
  
address  
  
="  
  
mex"  
  
  
  
binding  
  
="  
  
mexHttpBinding"  
  
  
  
contract  
  
="  
  
IMetadataExchange"  
  
  
  
/ 
  
>  
  
 < 
  
host  
  
>  
  
 < 
  
baseAddresses  
  
>  
  
 < 
  
add  
  
  
  
baseAddress  
  
="  
  
http://localhost:8000/WexflowService/"  
  
  
  
/ 
  
>  
  
 < 
  
/baseAddresses  
  
>  
  
 < 
  
/host  
  
>  
  
 < 
  
/service  
  
>  
  
 < 
  
/services  
  
>  
  
 < 
  
behaviors  
  
>  
  
 < 
  
serviceBehaviors  
  
>  
  
 < 
  
behavior  
  
  
  
name  
  
="  
  
WexflowServiceBehavior"  
  
>  
  
 < 
  
serviceMetadata  
  
  
  
httpGetEnabled  
  
="  
  
true"  
  
/ 
  
>  
  
 < 
  
serviceDebug  
  
  
  
includeExceptionDetailInFaults  
  
="  
  
False"  
  
/ 
  
>  
  
 < 
  
/behavior  
  
>  
  
 < 
  
/serviceBehaviors  
  
>  
  
 < 
  
/behaviors  
  
>  
  
 < 
  
/system.serviceModel  
  
>  
 

SvcUtil.exe用于生成WCF代理,如下所示,

 
SvcUtil.exe http://localhost:8000/WexflowService//out:WexflowServiceClient.cs/config:App.config 

为了调试 Wexflow Windows服务,已经使用了以下技巧,

 
  
namespace  
 Wexflow.Clients.WindowsService {  
static  
  
class  
Program {  
static  
  
void  
Main(string [] args) {  
if  
(args.Length  
>  
  
0  
&& args [0]. Equals (  
"  
  
debug"  
)) { WexflowWindowsService service =  
new  
WexflowWindowsService(); service.OnDebug(); Thread.Sleep(Timeout.Infinite); }  
else  
{ ServiceBase [] servicesToRun =  
new  
ServiceBase [] {  
new  
WexflowWindowsService() }; ServiceBase.Run(servicesToRun); } } } } 

Wexflow引擎

下面的类图描述了Wexflow引擎的总体架构。

WexflowEngine类由工作流和其他属性的集合组成。 工作流由任务集合和其他属性组成。 Task是由Wexflow任务继承的抽象类。

大致来说,WexflowEngine类通过linqtosql将工作流的所有XML文件解析到Workflow对象中。 然后当调用该类的方法Run()时自动启动startuplaunchType的工作流,然后通过计时器启动periodiclaunchType的工作流 。

创建WexflowEngine的新实例时,会发生以下情况,

 
  
public  
WexflowEngine (  
string  
settingsFile) { this.SettingsFile = settingsFile; LoadSettings(); LoadWorkflows() ; } 

然后加载工作流引擎设置,然后从它XML文件加载工作流。

这些设置按如下方式加载:

 
  
private  
  
void  
LoadSettings( ) { XDocument xdoc = XDocument.Load (  
this  
.SettingsFile); this.WorkflowsFolder = GetWexflowSetting(xdoc,  
"  
  
workflowsFolder"  
); this.TempFolder = GetWexflowSetting(xdoc,  
"  
  
tempFolder"  
) ; }  
private  
  
string  
GetWexflowSetting(XDocument xdoc,  
string  
name ) { return xdoc.XPathSelectElement (  
string  
.Format (  
"  
  
/Wexflow/Setting[@name='{0}']"  
, name)).Attribute (  
"  
  
value"  
).Value ; } 

工作流按如下方式加载:

 
  
private  
  
void  
LoadWorkflows( ) { List <Workflow> workflows =  
new  
List <Workflow> (); foreach (  
string  
file  
in  
Directory.GetFiles (  
this  
.WorkflowsFolder)) { try { Workflow workflow =  
new  
Workflow(file,  
this  
.TempFolder); workflows.Add(workflow); Logger.InfoFormat (  
"  
  
Workflow loaded : {0}"  
, workflow); } catch (Exception e) { Logger.ErrorFormat (  
"  
  
An error occured while loading the workflow : {0} please check the workflow configuration."  
, file); } } this.Workflows = workflows.ToArray() ; } 

创建工作流的新实例时,会发生以下情况,

 
  
public  
Workflow (  
string  
path,  
string  
wexflowTempFolder ) { this.JobId =  
1  
; this._thread =  
null  
; this.WorkflowFilePath = path; this.WexflowTempFolder = wexflowTempFolder; this.FilesPerTask =  
new  
Dictionary <int, List <FileInf>> (); this.EntitiesPerTask =  
new  
Dictionary <int, List <Entity>> (); Load() ; }  
private  
  
void  
Load( ) { XDocument xdoc = XDocument.Load (  
this  
.WorkflowFilePath); this.Id =  
int  
.Parse(GetWorkflowAttribute(xdoc,  
"  
  
id"  
)); this.Name = GetWorkflowAttribute(xdoc,  
"  
  
name"  
); this.Description = GetWorkflowAttribute(xdoc,  
"  
  
description"  
); this.LaunchType = (LaunchType)Enum.Parse (  
typeof  
(LaunchType), GetWorkflowSetting(xdoc,  
"  
  
launchType"  
),  
true  
); if (  
this  
.LaunchType == Core.LaunchType.Periodic )  
this  
.Period = TimeSpan.Parse(GetWorkflowSetting(xdoc,  
"  
  
period"  
)); this.IsEnabled =  
bool  
.Parse(GetWorkflowSetting(xdoc,  
"  
  
enabled"  
)); List <Task> tasks =  
new  
List <Task> (); foreach (XElement xTask  
in  
xdoc.XPathSelectElements (  
"  
  
/Workflow/Tasks/Task"  
)) { string name = xTask.Attribute (  
"  
  
name"  
).Value; string assemblyName =  
"  
  
Wexflow.Tasks."  
+ name; string typeName =  
"  
  
Wexflow.Tasks."  
+ name +  
"  
  
."  
+ name +  
"  
  
,"  
+ assemblyName; Task task = (Task)Activator.CreateInstance(Type.GetType(typeName), xTask,  
this  
); tasks.Add(task); } this.Taks = tasks.ToArray() ; }  
private  
  
string  
GetWorkflowAttribute(XDocument xdoc,  
string  
attr ) { return xdoc.XPathSelectElement (  
"  
  
/Workflow"  
).Attribute(attr).Value ; }  
private  
  
string  
GetWorkflowSetting(XDocument xdoc,  
string  
name ) { return xdoc.XPathSelectElement (  
string  
.Format (  
"  
  
/Workflow[@id='{0}']/Settings/Setting[@name='{1}']"  
,  
this  
.Id, name)).Attribute (  
"  
  
value"  
).Value ; } 

首先,检索工作流设置,然后通过反射构建任务。

当Wexflow引擎通过方法Run()启动时,会发生以下事情,

 
  
public  
  
void  
Run( ) { foreach (Workflow workflow  
in  
  
this  
.Workflows) { if (workflow.IsEnabled) { if (workflow.LaunchType == LaunchType.Startup) { workflow.Start(); } else  
if  
(workflow.LaunchType == LaunchType.Periodic) { Action <object> callback = o =  
>  
{ Workflow wf = (Workflow)o; if (!wf.IsRunning) wf.Start(); }; WexflowTimer timer =  
new  
WexflowTimer (  
new  
TimerCallback(callback), workflow, workflow.Period); timer.Start(); } } } } 

对于每个工作流,如果工作流已启用,Wexflow将在launchTypestartup时启动它否则如果它launchTypeperiodic则Wexflow将创建WexflowTimerWexflowTimer将每period启动工作流 。

WexflowTimer类非常简单,如下所示,

 
  
public  
  
class  
WexflowTimer { public TimerCallback TimerCallback {  
get  
;  
private  
  
set  
; } public  
object  
State {  
get  
;  
private  
  
set  
; } public TimeSpan Period {  
get  
;  
private  
  
set  
; } public WexflowTimer(TimerCallback timerCallback,  
object  
state, TimeSpan period) { this.TimerCallback = timerCallback; this.State = state; this.Period = period; } public  
void  
Start() { Thread thread =  
new  
Thread (  
new  
ThreadStart(() =  
>  
{ Stopwatch stopwatch =  
new  
  
>  
=  
this  
.Period.TotalMilliseconds) { stopwatch.Reset(); stopwatch.Start(); this.TimerCallback.Invoke (  
this  
.State); } Thread.Sleep (  
100  
); } })); thread.Start(); } } 

我使用了自定义计时器,因为我在测试复杂的定期工作流程时遇到了很多System.Threading.Timer问题 。

当工作流启动时,会发生以下情况:

 
  
public  
  
void  
Start( ) { Thread thread =  
new  
Thread (  
new  
ThreadStart(() =  
>  
{ try { this.IsRunning =  
true  
; Logger.InfoFormat (  
"  
  
{0} Workflow started."  
,  
this  
.LogTag) ;  
// 
  
Create the temp folder  
CreateTempFolder() ;  
// 
  
Run the tasks  
foreach (Task task  
in  
  
this  
.Taks) { if (task.IsEnabled) { task.Run(); } } } catch (ThreadAbortException) { } catch (Exception e) { Logger.ErrorFormat (  
"  
  
An error occured while running the workflow : {0}"  
, e,  
this  
); } finally {  
// 
  
Cleanup  
foreach (List <FileInf> files  
in  
  
this  
.FilesPerTask.Values) files.Clear(); foreach (List <Entity> entities  
in  
  
this  
.EntitiesPerTask.Values) entities.Clear(); this._thread =  
null  
; this.IsRunning =  
false  
; GC.Collect(); Logger.InfoFormat (  
"  
  
{0} Workflow finished."  
,  
this  
.LogTag); this.JobId++; } })); this._thread = thread; thread.Start() ; }  
private  
  
void  
CreateTempFolder( ) {  
// 
  
WorkflowId/dd-MM-yyyy/HH-mm-ss-fff  
string wfTempFolder = Path.Combine(  
this  
.WexflowTempFolder,  
this  
.Id.ToString()); if (!Directory.Exists(wfTempFolder)) Directory.CreateDirectory(wfTempFolder); string wfDayTempFolder = Path.Combine(wfTempFolder,  
string  
.Format (  
"  
  
{0:yyyy-MM-dd}"  
, DateTime.Now)); if (!Directory.Exists(wfDayTempFolder)) Directory.CreateDirectory(wfDayTempFolder); string wfJobTempFolder = Path.Combine(wfDayTempFolder,  
string  
.Format (  
"  
  
{0:HH-mm-ss-fff}"  
, DateTime.Now)); if (!Directory.Exists(wfJobTempFolder)) Directory.CreateDirectory(wfJobTempFolder); this.WorkflowTempFolder = wfJobTempFolder ; } 

创建并启动一个新线程。 在此线程中,创建临时文件夹,然后将任务逐个启动。 在工作流结束时,将清除任务加载的文件和实体。

FileInf类下面:

 
  
public  
  
class  
FileInf { public  
string  
Path {  
get  
;  
private  
  
set  
; } public  
string  
FileName {  
get  
;  
private  
  
set  
; } public  
int  
TaskId {  
get  
;  
private  
  
set  
; } public FileInf (  
string  
path,  
int  
taskId) { this.Path = path; this.FileName = System.IO. Path.GetFileName (  
this  
.Path); this.TaskId = taskId; } } 

Entity类下面:

 
  
public  
  
abstract  
  
class  
Entity { public  
int  
TaskId {  
get  
;  
private  
  
set  
; } } 

使用trigger作为launchType的工作流是通过调用Workflow.Start()方法从Wexflow管理器启动的。

工作流可以从Wexflow管理器停止。挂起和恢复。

最后,每个任务实现抽象类 Wexflow.Core.Task

 
  
public  
  
abstract  
  
class  
Task { public  
int  
Id {  
get  
;  
private  
  
set  
; } public  
string  
name {  
get  
;  
private  
  
set  
; } public  
string  
Description {  
get  
;  
private  
  
set  
; } public  
bool  
IsEnabled {  
get  
;  
private  
  
set  
; } public Workflow Workflow {  
get  
;  
private  
  
set  
; } public List <FileInf> Files { get { return  
this  
.Workflow.FilesPerTask [this.Id] ; } } public List <Entity> Entities { get { return  
this  
.Workflow.EntitiesPerTask [this.Id] ; } } private XElement _xElement; public Task(XElement xe, Workflow wf) { this._xElement = xe; this.Id =  
int  
.Parse(xe.Attribute (  
"  
  
id"  
).Value); this.Name = xe.Attribute (  
"  
  
name"  
).Value; this.Description = xe.Attribute (  
"  
  
description"  
).Value; this.IsEnabled =  
bool  
.Parse(xe.Attribute (  
"  
  
enabled"  
).Value); this.Workflow = wf; this.Workflow.FilesPerTask.Add (  
this  
.Id,  
new  
List <FileInf> ()); this.Workflow.EntitiesPerTask.Add (  
this  
.Id,  
new  
List <Entity> ()); } public  
abstract  
  
void  
Run(); public  
string  
GetSetting (  
string  
name) { return  
this  
._xElement.XPathSelectElement (  
string  
.Format (  
"  
  
Setting [@name='{0} ']"  
, name)).Attribute (  
"  
  
value"  
).Value; } public  
string  
GetSetting (  
string  
name,  
string  
defaultValue) { XElement xe =  
this  
._xElement.XPathSelectElement (  
string  
.Format (  
"  
  
Setting [@name='{0} ']"  
, name)); if (xe = =  
null  
)  
return  
defaultValue; return xe.Attribute (  
"  
  
value"  
).Value; } public string [] GetSettings (  
string  
name) { List <string> settings =  
new  
List <string> (); foreach (XElement xe  
in  
  
this  
._xElement.XPathSelectElements (  
string  
.Format (  
"  
  
Setting [@name='{0} ']"  
, name))) { settings.Add(xe.Attribute (  
"  
  
value"  
).Value); } return settings.ToArray(); } public FileInf [] SelectFiles() { List <FileInf> files =  
new  
List <FileInf> (); foreach (  
string  
id  
in  
  
this  
.GetSettings (  
"  
  
selectFiles"  
)) { int taskId =  
int  
.Parse(id); files.AddRange (  
this  
.Workflow.FilesPerTask [taskId] ); } return files.ToArray(); } public Entity [] SelectEntities() { List <Entity> entities =  
new  
List <Entity> (); foreach (  
string  
id  
in  
  
this  
.GetSettings (  
"  
  
selectEntities"  
)) { int taskId =  
int  
.Parse(id); entities.AddRange (  
this  
.Workflow.EntitiesPerTask [taskId] ); } return entities.ToArray(); }  
// 
  
...  
} 

每个任务都在Run()方法中实现一个自定义逻辑。 每个任务可以通过Files属性加载一个文件集合,通过Entities属性加载一个实体集合。 本文不会详细介绍每个任务的源代码,但是,你可以查看每个任务的源代码,以便了解如何构建自定义任务 。

Wexflow管理器

WexflowManager是一个非常简单的Windows窗体应用程序,它显示了Wexflow加载的所有工作流,允许最终用户启动。停止。挂起或恢复工作流。

Wexflow管理器的源代码如下所示:

 
  
private  
  
const  
  
string  
COLUMN_ID =  
"  
  
Id"  
;  
private  
  
const  
  
string  
COLUMN_ENABLED =  
"  
  
Enabled"  
;  
private  
  
const  
  
int  
TIMER_INTERVAL =  
100  
;  
// 
  
ms  
  
private  
WexflowServiceClient _wexflowServiceClient ;  
private  
WorkflowInfo [] _workflows ;  
private  
Dictionary <int, Timer> _timers ;  
private  
Dictionary <int, bool> _previousIsRunning ;  
private  
Dictionary <int, bool> _previousIsPaused ;  
private  
  
bool  
_windowsServiceWasStopped ;  
public  
Form1( ) { InitializeComponent(); this.textBoxInfo.Text =  
"  
  
Loading workflows..."  
; this._timers =  
new  
Dictionary <int, Timer> (); this._previousIsRunning =  
new  
Dictionary <int, bool> (); this._previousIsPaused =  
new  
Dictionary <int, bool> (); this.backgroundWorker1.RunWorkerAsync() ; }  
private  
  
void  
backgroundWorker1_DoWork (  
object  
sender, DoWorkEventArgs e ) { if (Program.DEBUG_MODE || Program.IsWexflowWindowsServiceRunning()) { this._wexflowServiceClient =  
new  
WexflowServiceClient(); this._workflows = _wexflowServiceClient.GetWorkflows(); } else { this._workflows =  
new  
WorkflowInfo [] { }; this.textBoxInfo.Text =  
"  
  
"  
; } }  
private  
  
void  
backgroundWorker1_RunWorkerCompleted (  
object  
sender, RunWorkerCompletedEventArgs e ) { BindDataGridView(); }  
private  
  
void  
BindDataGridView( ) { SortableBindingList <WorkflowDataInfo> workflows =  
new  
SortableBindingList <WorkflowDataInfo> (); foreach (WorkflowInfo workflow  
in  
  
this  
._workflows) { workflows.Add (  
new  
WorkflowDataInfo(workflow.Id, workflow.Name, workflow.LaunchType, workflow.IsEnabled, workflow.Description)); } this.dataGridViewWorkflows.DataSource = workflows; this.dataGridViewWorkflows.Columns [0]. AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells; this.dataGridViewWorkflows.Columns [1]. AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells; this.dataGridViewWorkflows.Columns [2]. AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells; this.dataGridViewWorkflows.Columns [3]. AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells; this.dataGridViewWorkflows.Columns [3]. Name = COLUMN_ENABLED; this.dataGridViewWorkflows.Columns [3]. HeaderText = COLUMN_ENABLED; this.dataGridViewWorkflows.Columns [4]. AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; this.dataGridViewWorkflows.Sort (  
this  
.dataGridViewWorkflows.Columns [0], ListSortDirection.Ascending) ; } 

当创建Form1的新实例时,异步启动 BackgroundWorker 。 此BackgroundWorker检索由Wexflow引擎加载的工作流,并且将DataGridview绑定到OnCompleted事件中。

WorkflowDataInfo类下面:

 
  
public  
  
class  
 WorkflowDataInfo:IComparable { public  
int  
Id {  
get  
;  
private  
  
set  
; } public  
string  
name {  
get  
;  
private  
  
set  
; } public LaunchType LaunchType {  
get  
;  
private  
  
set  
; } public  
bool  
IsEnabled {  
get  
;  
private  
  
set  
; } public  
string  
Description {  
get  
;  
private  
  
set  
; } public WorkflowDataInfo (  
int  
id,  
string  
name, LaunchType launchType,  
bool  
isEnabled,  
string  
desc) { this.Id = id; this.Name = name; this.LaunchType = launchType; this.IsEnabled = isEnabled; this.Description = desc; } public  
int  
CompareTo (  
object  
obj) { WorkflowDataInfo wf = (WorkflowDataInfo)obj; return wf.Id. CompareTo (  
this  
.Id); } } 

在每个按钮的Click事件的实现下面,

 
  
private  
  
void  
buttonStart_Click (  
object  
sender, EventArgs e ) { int wfId = GetSlectedWorkflowId(); if (wfId  
>  
-1 ) { this._wexflowServiceClient.StartWorkflow(wfId); } }  
private  
  
void  
buttonPause_Click (  
object  
sender, EventArgs e ) { int wfId = GetSlectedWorkflowId(); if (wfId  
>  
-1 ) { this._wexflowServiceClient.SuspendWorkflow(wfId); this.UpdateButtons(wfId,  
true  
); } }  
private  
  
void  
buttonResume_Click (  
object  
sender, EventArgs e ) { int wfId = GetSlectedWorkflowId(); if (wfId  
>  
-1 ) { this._wexflowServiceClient.ResumeWorkflow(wfId); } }  
private  
  
void  
buttonStop_Click (  
object  
sender, EventArgs e ) { int wfId = GetSlectedWorkflowId(); if (wfId  
>  
-1 ) { this._wexflowServiceClient.StopWorkflow(wfId); this.UpdateButtons(wfId,  
true  
); } }  
private  
  
int  
GetSlectedWorkflowId( ) { int wfId = -1 ; if (dataGridViewWorkflows.SelectedRows.Count  
>  
  
0  
) { if(Program.DEBUG_MODE || Program.IsWexflowWindowsServiceRunning()) { wfId =  
int  
.Parse(dataGridViewWorkflows.SelectedRows [0]. Cells [COLUMN_ID]. Value.ToString()); } else { HandleNonRunningWindowsService(); } } return wfId ; }  
private  
WorkflowInfo GetWorkflow (  
int  
id ) { if (Program.DEBUG_MODE || Program.IsWexflowWindowsServiceRunning()) { if (  
this  
._windowsServiceWasStopped) { this._wexflowServiceClient =  
new  
WexflowServiceClient(); this._windowsServiceWasStopped =  
false  
; this.backgroundWorker1.RunWorkerAsync(); } return  
this  
._wexflowServiceClient.GetWorkflow(id); } else { this._windowsServiceWasStopped =  
true  
; HandleNonRunningWindowsService(); } return  
null  
; }  
private  
  
void  
HandleNonRunningWindowsService( ) { this.buttonStart.Enabled =  
this  
.buttonPause.Enabled =  
this  
.buttonResume.Enabled =  
this  
.buttonStop.Enabled =  
false  
; this.textBoxInfo.Text =  
"  
  
Wexflow Windows Service is not running."  
; }  
private  
  
void  
UpdateButtons (  
int  
wfId,  
bool  
force ) { if (wfId  
>  
-1 ) { Workflow workflow = _wexflowEngine.GetWorkflow(wfId); if (workflow!=  
null  
) { if (!workflow.IsEnabled) { this.textBoxInfo.Text =  
"  
  
This workflow is disabled."  
; this.buttonStart.Enabled =  
this  
.buttonPause.Enabled =  
this  
.buttonResume.Enabled =  
this  
.buttonStop.Enabled =  
false  
; } else { if (!force &&!WorkflowStatusChanged(workflow) )  
return  
; buttonStart.Enabled =!workflow.IsRunning; buttonStop.Enabled = workflow.IsRunning &&!workflow.IsPaused; buttonPause.Enabled = workflow.IsRunning &&!workflow.IsPaused; buttonResume.Enabled = workflow.IsPaused; if (workflow.IsRunning &&!workflow.IsPaused) { this.textBoxInfo.Text =  
"  
  
This workflow is running..."  
; } else  
if  
(workflow.IsPaused) { this.textBoxInfo.Text =  
"  
  
This workflow is paused."  
; } else { this.textBoxInfo.Text =  
"  
  
"  
; } } } } }  
private  
  
bool  
WorkflowStatusChanged(Workflow workflow ) { bool changed =  
false  
; if (!this._previousIsRunning.ContainsKey(workflow.Id)) { this._previousIsRunning.Add(workflow.Id, workflow.IsRunning); changed =  
true  
; } if (!this._previousIsPaused.ContainsKey(workflow.Id)) { this._previousIsPaused.Add(workflow.Id, workflow.IsPaused); changed =  
true  
; } if (changed) { return  
true  
; } else { if (  
this  
._previousIsRunning [workflow.Id]!= workflow.IsRunning) { changed =  
true  
; } if (  
this  
._previousIsPaused [workflow.Id]!= workflow.IsPaused) { changed =  
true  
; } this._previousIsRunning [workflow.Id] = workflow.IsRunning; this._previousIsPaused [workflow.Id] = workflow.IsPaused; return changed; } } 

DataGridviewSelectionChanged事件实现下面,

 
  
private  
  
void  
dataGridViewWorkflows_SelectionChanged (  
object  
sender, EventArgs e ) { int wfId = GetSlectedWorkflowId(); if (wfId  
>  
-1 ) { Workflow workflow = _wexflowEngine.GetWorkflow(wfId); foreach (Timer timer  
in  
  
this  
._timers.Values) timer.Stop(); if (workflow.IsEnabled) { if (!this._timers.ContainsKey(wfId)) { Timer timer =  
new  
Timer(); timer.Interval = TIMER_INTERVAL; timer.Tick +=  
new  
EventHandler((o, ea) =  
>  
{ this.UpdateButtons(wfId,  
false  
); }); this._timers.Add(wfId, timer); } this.UpdateButtons(wfId,  
true  
); this._timers [wfId]. Start(); } else { this.UpdateButtons(wfId,  
true  
); } } } 

DataGridview的选择发生更改时如果所选工作流不存在,就会为所选工作流创建计时器,如果所选工作流的状态随时间变化,就此计时器会更新按钮的enabled选项和textBoxInfo文本框 。

如果在Wexflow管理器中双击工作流,它将启动或恢复,如果按如下方式挂起,

 
  
private  
  
void  
dataGridViewWorkflows_CellDoubleClick (  
object  
sender, DataGridViewCellEventArgs e ) { int wfId =  
this  
.GetSlectedWorkflowId(); if (wfId  
>  
-1 ) { Workflow workflow = _wexflowEngine.GetWorkflow(wfId); if (workflow!=  
null  
&& workflow.IsEnabled) { if (!workflow.IsRunning &&!workflow.IsPaused) { buttonStart_Click (  
this  
,  
null  
); } else  
if  
(workflow.IsPaused) { buttonResume_Click (  
this  
,  
null  
); } } } } 

就是这样我希望你喜欢阅读这篇文章。 如果你有任何改进Wexflow的想法或者如果你遇到任何问题或想要为此项目做出贡献请在评论中告诉我,

Wexflow使用的库

下面是Wexflow所使用的库的List:

  • FluentFTP支持FTP和FTPS(exmplicit/隐式)的FTP客户端用C#和MIT许可证编写 。
  • SSH.NET:一个用于。 NET写在C#和MIT许可证下
  • SharpZipLib一个用C#和MIT许可证编写的 Zip GZipTar和BZip2库,
  • saxon he一个XSLT和XQuery处理器它在W3C定义的基本一致性级别提供 XSLT (1.0,3.0和3.1)和 XPath (2.0,3.0和3.1)的实现 。 它是一个开源库,可在Mozilla公共许可证版本1.0下获得。
  • log4net微软着名的 Apache Log4J框架的一个端口 。 NET运行时。它位于Apache许可版本 2.0.
  • TweetSharp在C#中写的TwitterAP周围快速,而且干净的包装器,
  • Microsoft Sync Framework 2.1 , 一种数据同步平台,允许跨多个数据存储同步数据。
  • Json.NET:一个高性能的JSON框架。 NET写在C#和MIT许可证下
  • Hammock一个简化消费和包装RESTful服务的HTTP库,
  • Mono.Security:提供丢失部分的库。 网络安全。
  • Oracle数据访问组件(ODAC ), Oracle数据库客户端。
  • MySQL连接器/net:用于MySQL的完全管理的ADO.NET驱动程序。
  • System.Data.SQLite:SQLite的ADO.NET提供程序。
  • Npgsql PostgreSQL的开源ADO.NET数据提供程序写在C#和PostgreSQL许可证下是一个自由的osi批准的开源许可证 。
  • 用于Teradata的 .NET数据提供程序:, 用于Teradata的ADO.NET提供程序。
  • Eto.Forms用于桌面和移动应用程序的跨平台GUI框架 。 网网。

历史记录

  • 5 2017年月:
  • 9 2017年月:
    • 发布了1.0.1版本 。
    • 创建 Wexflow Windows服务。
    • 创建 TarTgzSql任务。
    • 更新的Wexflow管理器。
    • 修正了一些 Bug 。
  • 162017年月:
    • 发布了1.0.2版本 。
    • 创建WmiImagesTransformer任务。
    • 更新的Wexflow管理器。
  • 232017年月:
    • 发布了1.0.3版本 。
    • 创建 HttpSyncFilesRenamerFilesExistWait任务。
    • 创建的文件标记功能。
    • 添加 List,下载和delete命令到Ftp任务 (FTP/FTPS(explicit/implicit)/SFTP).,
    • retryCountretryTimeout设置选项添加到Ftp任务。
    • 更新的Wexflow管理器。
    • 更新的Wexflow引擎。
    • 修正了一些 Bug 。
    • 更新的安装文件。
    • 更新的文章内容。
  • 262017年月:
    • 发布了1.0.4版本 。
    • 在加载worklfow文件之前创建验证。
    • 创建的任务执行图。
    • 创建流程图工作流(DoIfDoWhile )。
    • 创建工作流事件(OnSuccessOnWarningOnError )。
    • 创建FileExists流程图任务。
    • 更新的设置。
    • 更新的文章内容。
  • 302017年月:
    • 发布了1.0.5版本 。
    • 创建Wexflow网页管理器:用于管理工作流的轻量级 JavaScript API (~6Kb )。
    • 为Linux创建Wexflow管理器 GUI 。
    • 更新了Windows的Wexflow管理器。
    • 已更新Windows的安装程序。
    • 为Linux创建了一个设置。
  • 062017年月:
    • 发布了1.0.6版本 。
    • 创建WexflowAndroid管理器:用于管理工作流的Android应用程序。
    • 更新的Wexflow网站管理器。
    • 更新的Wexflow管理器(Windows和 Linux )。
    • 更新的Wexflow引擎。
  • 172017年月:
    • 发布了1.0.7版本 。
    • 创建Movedir任务。
    • 更新的Wexflow网站管理器。
    • 更新的Wexflow管理器(Windows,Linux和安卓)。
    • 更新的Wexflow引擎。
    • 修正了一些 Bug 。
  • 062017年月:
    • 发布了1.0.8版本 。
    • 创建swictch/案例流程图 node 。
    • 已创建任务。
    • 为macOS创建Wexflow管理器。
    • 如果流程图节点的语法已更新,则更新。
    • 更新的安装项目。
    • 如果流程图node可以在 an,一段时间和一个切换流程图节点内。
    • 现在,流程图node可以在一个 If,一段时间和一个切换流程图节点内。
    • 现在,切换流程图node可以在 If,一段时间和一个切换流程图节点内。
    • 代码重构。
    • 修正了一些 Bug 。
  • 072017年月:
    • 发布了1.0.9版本 。
    • 固定开关流程图node子进程执行。
    • 固定WCF服务配置问题。
  • 222017年05月:
    • 发布了1.1版本 。
    • 创建Workflow任务。此任务允许启动,挂起,恢复或停止工作流的List 。
    • 性能优化。
    • 代码重构。


文章标签:Source  开源  流程  workflow-engine  

Copyright © 2011 HelpLib All rights reserved.    知识分享协议 京ICP备05059198号-3  |  如果智培  |  酷兔英语