# 总体介绍

提示

本节内容快速浏览即可,通过教程的练习后,再回来加深理解。

# 项目结构

proj structure

# 项目依赖

proj denpendency

如上图所示:

  • Ligg.Ewa.WinformApp和Ligg.Ewa.ConsoleApp是Winform和控制台应用的启动项目; 对应不同的启动参数,进入不同的应用(Application)和UI。一个应用可以同时具有多个Winform和Console的界面。
  • Ligg.Ewa.Winform, Ligg.Ewa.Console项目主要作用是对UI的管理。
  • Ligg.Ewa.Parser为Ligg.Ewa.Winform, Ligg.Ewa.Console共用。框架内置基础功能(如字符、文件处理, 逻辑、数值运算, 数据输入输出、数据格式转换、加密解密、表单字段验证、Windows脚本执行、Python脚本执行等...), 框架通过Ligg.Ewa.Parser项目以Get(), Do(), GetConstant(), Validate()调用Ligg.Infra项目实现。
  • Cblp项目(核心业务逻辑处理)实现Get(), Do(), GetConstant(), Validate()的功能扩展。一个应用对应一个的Cblp项目。
  • OeStdServiceComponent项目(外嵌标准服务组件)通常是通用共享的组件。实现Get(), Do()的功能扩展; 为多个应用共用。
  • 启动项目和Cblp项目以及外嵌标准服务项目项目都需要引用Ligg.Ewa.Interface项目。启动项目和Cblp项目之间, 启动项目和OeStdServiceComponent项目之间没有依赖关系,通过Ioc来调用。
  • Cblp和OeStdServiceComponent项目的目标框架可以是.net Framework、.net Standand或.net Core。 详见集成开发部分及示例。

# 开发环境

  • project

.NET Framework 4.7.2
.NET Standard 2.0
.NET Core 3.1

  • Visual Studio

Microsoft Visual Studio 2019
Version 16.9.2

# 运行目录

# Root目录,常量表达式: %rootDir%
├── Conf                                    # 配置目录, 常量表达式: %cfgDir%
│   │── Apps                                         
│   │   │── App-1                           # App配置目录, 常量表达式: %appCfgDir%
│   │   │   │── Shared                      # %appSharedDir%  
│   │   │   └── UIs                          
│   │   │       │── Console                 # App Console UI 配置目录, 常量表达式: %appUiDir%           
│   │   │       │── │── Scenarios           # 常量表达式: %snrsDir%
│   │   │       │── │── │──.Start         
│   │   │       │── │── │──│──Logon   
│   │   │       │   │   │  └──SoftwareCover           
│   │   │       │── │── │── Scenario-1      
│   │   │       │── │── │── Scenario-2      
│   │   │       │── │── └── Scenario-n          
│   │   │       │── Winform                 # App Winform UI 配置目录, 常量表达式: %appUiDir%          
│   │   │       │── │── functions           # 常量表达式: %funcsDir%
│   │   │       │── │── │──function-1        
│   │   │       │   │   │  │──Menus         # Menu的起始位置
│   │   │       │   │   │  └──Tray          # Tray的起始位置
│   │   │       │── │── │──function-2       
│   │   │       │── │── └──function-n       
│   │   │       │── │── views               # 常量表达式: %viewsDir%
│   │   │       │── │── │──view-1           
│   │   │       │   │   │  └──Tray          # Tray的起始位置
│   │   │       │── │── │──view-2           
│   │   │       │── │── └──view-n           
│   │   │       │── └── zones               # 常量表达式: %zonesDir%
│   │   │       │── │── │──.Start         
│   │   │       │── │── │──│──Logon   
│   │   │       │   │   │  └──SoftwareCover          
│   │   │       │── │── │──zone-1           
│   │   │       │   │   │  └──Tray          # Tray的起始位置
│   │   │       │── │── │──zone-2           
│   │   │       │── └── └──zone-n           
│   │   │       │── ApplicationAnnexes.*    # 应用的名称、描述、备注多语言配置文件
│   │   │       │── SharedAnnexes.*         # 共用的多语言配置文件
│   │   │       └── ApplicationSetting.*    # 应用配置文件
│   │   │── App-2                           # 同上
│   │   └── App-n                           # 同上
│   │── Languages                           # 多语言配置目录
│   │  │── Images                           # 多语言图标配置目录
│   │  └── Languages.*                      # 多语言配置文件
│   │── Global                              # 全局配置目录,常量表达式: %glbCfgDir%
|   │   │── Shared                          #常量表达式: %glbSharedDir%  
|   │   └── UIs                              
||── Console                    # 常量表达式: %glbUiDir%, 
|   │       └── Winform                    # 常量表达式: %glbUiDir%, |—— OeServiceComponents.*               # OeServiceComponents配置文件
│   └── GlobalSetting.*                     # 全局配置文件
├── Data                                    # 数据目录,常量表达式: %dataDir%
│   │── Apps                                      
│   │   │── App-1                          # App数据目录,常量表达式: %appDataDir%
│   │   │── App-2                          # 同上
│   │   └── App-n                          # 同上
│   └── Global                             # 全局数据目录,常量表达式: %glbDataDir%
├── Ini                                    # 可以把启动程序的ini文件放在此处,让根目录比较整洁
├── Lib                                    # Lib目录,常量: %libDir%; 下放第3方的程序包- 
├   │                                      # -例如嵌入式Python    
│   │── Apps                                      
│   │   │── App-1                          # App Lib 目录,常量表达式: %appLibDir%
│   │   │── App-2                          # 同上
│   │   └── App-n                          # 同上
│   └── Global                             # 全局Lib 目录,常量表达式: %glbLibDir%
├── Program                                # 本框架相关的程序文件
│   │── Boot.exe                           # 引导程序, debug阶段使用            
│   │── Boot-cpp.exe                       # 引导程序, release阶段使用                 
│   │── Cblps                                       
│   │   │── App-1                          # 下放应用的Cblp编译出来程序文件
│   │   │── App-2                          # 下放应用的Cblp编译出来程序文件
│   │   └── App-n                          # 下放应用的Cblp编译出来程序文件
│── │── Main                               # 下放启动程序项目编译出来程序文件
│   │   │── netcoreapp3.1                           
│   │   │   │── ConsoleApp.exe             # 控制台执行文件, 启动程序
│   │   │   │── debug.ini                  # 调试时的启动参数文件
│   │   │   └── WinformApp.exe             # Winform执行文件, 启动程序
│   │   └── netfxapp4.72                           
│   │   │   │── ConsoleApp.exe             # 控制台执行文件, 启动程序
│   │   │   │── debug.ini                  # 调试时的启动参数文件
│   │   │   └── WinformApp.exe             # Winform执行文件, 启动程序
│── └── OeStdServiceComponents             # 下放'外嵌标准服务'项目编译出来程序文件
│       │── OeStdServiceComponent-1               
│       │── OeStdServiceComponent-2               
│       └── OeStdServiceComponent-n       
│── Boot-1.exe                             # 具体的引导程序
│── Boot-1.ini                             # 具体的引导程序同名的的ini文件,包含启动参数-# -也可放到@rootDir\ini 目录下
│── Boot-2.exe                                    
│── Boot-2.ini                                   
│── Boot-n.exe                                    
└── Boot-n.ini                                    

# 程序运行

# 控制台程序运行

每个Application可以有多个Console的应用窗口, 每个应用窗口就是一个Scenario, 比如IT运维工具箱(OrpTk)有2个Scenario: RunShell、RunPython; OrpTk的控制台应用最少有2个Boot.exe(根据不同的初始化参数, 一个Scenario可能有多个引导程序)。每个Boot.exe对应一个同名的.ini文件。.ini文件的args分3部分, 第1部分是Application级别的参数, 中间以参数分隔符相隔; 第2部分是Scenario级别的参数, 中间以参数分隔符相隔; 第3部分是起始语言参数; 前后部分之间以空格相隔。

  • 起始语言的参数: Culture|LangugageCode
    例如:
    --en-US:en Culture: US, 英文
    --zh-CN:szh Culture: 中国, 简体中文
    --zh-CN:czh Culture: 中国, 繁体中文
    --zh-CN:en Culture: 中国, 英文

    备注

    在配置文件ApplicationSetting.* 也设置了起始语言, 优先级此处为高, 详见 教程-Winform-多语言支持, 教程-Console-多语言支持

  • Application级别的参数: appCode^startPassword
    说明:
    --appCode: Application的编码, 程序运行以此为关联。
    --startPassword: Application的起始密码, 如果在ApplicationSetting.*配置文件里设置了需要起始密码, 如果启动参数里带密码文本, 系统则进行隐式验证, 否则会弹出对话框, 进行显式验证。详见教程-Winform:起始密码示例, 教程-Console:起始密码示例

  • Scenario级别的参数: scenarioLocation^formTitle^initParams
    说明:
    --scenarioLocation: 起始ScenarioLocation的位置, 只支持相对路径(第一个''可以省略), 父路径是常量%appScenariosDir%。
    --formTitle: 控制台窗口的Text, 在UI的配置文件里也会设置formTitle, 如果此处为empty, 以UI的配置文件的为准。
    --initParams: 初始化参数, Larray格式。

    以下是2个示例(1个Scenario对应2个Boot.exe):

    • 通过RunPython实现一个加法
      修改引导程序Boot.exe为OrpTk-Console-PythonAdd.exe, 相应的.ini文件OrpTk-Console-PythonAdd.ini内容如下
    [setting]
    path=Program\Main\netFxApp4.72\ConsoleApp.exe
    args=OrpTk \Basic\RunPython^it-is-run-python-example1^%AppData%\py\calc-add.py,1,2
    
    • 同理, 通过RunPython实现一个减法
      修改引导程序Boot.exe为OrpTk-Console-PythonMinus.exe, 相应的.ini文件OrpTk-Console-PythonMinus.ini如下
[setting]
path=Program\Main\netFxApp4.72\ConsoleApp.exe
args=OrpTk Basic\RunPython^it-is-run-python-example1^%AppData%\py\calc-minus.py,2,1 zh-CN:szh

示例说明:
--参数分隔符: '^'
--appCode: OrpTk
--无startPassword
--scenarioLocation: \Conf\Apps\OrpTk\UI\Console\Basic\RunPython\
--formTitle: it-is-run-python-example1
--initParams: '\Data\Apps\OrpTk\py\calc-add.py','1','2'
--起始语言: 中国-简体中文

运行过程: 系统运行引导程序, 然后运行启动程序Program\Main\netFxApp4.72\ConsoleApp.exe, 通过scenarioLocation找到Scenario RunPython的UI配置文件, 传入参数, 运行并输出。

# Winform程序运行

每个Application可以有多个Winform的启动Form, 比如OrpTk有4个 不同类型的Form分别是: 管理员主界面(Function Form)、用户主界面(Function Form)、巡检工具Svi界面(Single View Interface, Svi Form)、备份作业工具Szi界面(Single Zone Interface, SziForm), OrpTk的Winform应用最少有4个Boot.exe(根据不同的初始化参数, 一个Form可能有多个引导程序)。每个Boot.exe对应一个同名的.ini文件。.ini文件的args分3部分, 第1部分是Application级别的参数, 中间以参数分隔符相隔; 第2部分是Form级别的参数, 中间以参数分隔符相隔; 第3部分是起始语言参数; 前后部分之间以空格相隔。

  • 起始语言的参数: 同上, 详见 教程-Winform-多语言支持

  • Application级别的参数: appCode^startPassword, 与控制台类似, 详见 教程-Winform:起始密码示例

  • Form级别的参数: 根据Form类型有所不同
    说明:
    --formTitle: Form窗口的Text, 在UI的配置文件里也会设置formTitle, 如果此处为empty, 以UI的配置文件的为准。
    --initParams: 初始化参数, Larray格式。

    --Szi/ Svi的Form级别的参数: formType^FormLocation^formTitle^initParams
    ----formType: Szi 或Svi, 如果为Empty则为Szi
    ----FormLocation起始Form的位置, 只支持相对路径(第一个''可以省略), Szi的父路径是常量: %appZonesDir%, Svi的父路径是常量: %appViewsDir%,。

    --Mvi的Form级别的参数: formType^FormLocation|StartView^initParams
    ----formType: Mvi
    ----FormLocation: FormLocation是单层的, 只支持相对路径(第一个''可以省略), 父路径是常量: %appFunctionsDir%, 详见教程-Winform-Mvi
    ----StartView: 起始View, 每个FuctionForm的UI配置里有设置StartView, 如果此处为empty, 以UI的配置文件的为准。

    以下是4个示例:

    • OrpTk管理员主界面
      修改引导程序Boot.exe为OrpTk-Winform-Func-Admin.exe, 相应的.ini文件OrpTk-Winform-Func-Admin.ini内容如下
    [setting]
    path=Program\Main\netFxApp4.72\WinformApp.exe
    args=OrpTk Mvi^Admin|OrpMgr
    

    说明: 没有startPassword, 没有formTitle, 没有初始化参数; Form类型是Mvi, Admin是管理员主界面的FormLocation, OrpMgr表示首先进入运维管理View(缺省是SysMgr-系统管理View)。

    • OrpTk巡检工具Svi界面
      修改引导程序Boot.exe为OrpTk-Winform-Svi-Insp.exe, 相应的.ini文件OrpTk-Winform-Svi-Insp.ini内容如下
    [setting]
    path=Program\Main\netFxApp4.72\WinformApp.exe
    args=OrpTk Svi^\Admin\Insp^Inspection-Server^server
    

    说明: 没有startPassword; Form类型是Svi; \Admin\Insp是Form的相对路径; formTitle是Inspection-Server; server是初始化参数, 表示Server的巡检, 配置的UI会根据传入参数把Server的巡检界面显示在最前面。

    • OrpTk备份作业工具Szi界面-备份Db
      修改引导程序Boot.exe为OrpTk-Winform-Szi-BakWorkerForDb.exe, 相应的.ini文件OrpTk-Winform-Szi-BakWorkerForDb.ini内容如下
    [setting]
    path=Program\Main\netFxApp4.72\WinformApp.exe
    args=OrpTk Szi^Common\BakWorker^db-backup^db,2days,1:00
    

    说明: 该工具通过配置已集成备份服务器上所有Db和备份磁盘柜相关文件功能。 Form类型是Szi; \Common\BakWorker是Form的相对路径; formTitle: db-backup, Form的Text显示db-backup, 与文件备份有个区分; db,2days,1:00是初始化参数, 表示备份Db,每隔2天, 每天1:00开始作业。

    • OrpTk备份作业工具Szi界面-备份文件
      修改引导程序Boot.exe为OrpTk-Winform-Szi-BakWorkerForFile.exe, 相应的.ini文件OrpTk-Winform-Szi-BakWorkerForFile.ini内容如下
    [setting]
    path=Program\Main\netFxApp4.72\WinformApp.exe
    args=OrpTk Szi^\Common\BakWorker^file-backup^files,3days,2:00
    

    说明: 该工具通过配置已集成备份服务器上所有Db和备份磁盘柜相关文件功能; Form类型是Szi, \Common\BakWorker是Form的相对路径; formTitle: file-backup, Form的Text显示file-backup,与db备份有个区分; file,3days,2:00是初始化参数, 表示备份file,每隔3天, 每天2:00开始作业。

运行过程: 系统运行引导程序, 然后运行启动程序Program\Main\netFxApp4.72\WinformApp.exe, 通过参数找到Form的UI配置文件, 传入参数, 显示Form。见教程示例

# 注意事项

注意事项

  • 引导程序Boot-x.exe必须放到根目录。引导程序可采用Boot.exe, 源码及下载见 博客园: C#通过System.Diagnostics.Process扩展实现引导程序; 也可采用Boot-cpp.exe, 源码及使用方法详见 Gitee: Liggin2019/Ligg.SeqExec.
  • Boot-x.ini可以放到根目录, 也可以统一放到根目录下的\ini下, 这样根目录比较整洁。
  • Conf下各文件夹名称和位置不能改变。
  • Data、Lib、Cblps的文件夹可以在配置文件ApplicationSetting.*里设置, 如在配置文件采用相对路径则在缺省位置。
  • OeStdServiceComponents文件夹在配置文件OeStdServiceComponents.*里设置, 如在配置文件采用相对路径则在缺省位置。
  • 启动程序WinformApp.exe、ConsoleApp.exe必须放到根目录的第3层子目录下如: \Program\Main\netcoreapp3.1, 系统SetCurrentDirectory的方式如下:
 var executableDir = 
 Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath);
 _startUpDir = Directory.GetParent(executableDir).ToString();
 _startUpDir = Directory.GetParent(_startUpDir).ToString();
 _startUpDir = Directory.GetParent(_startUpDir).ToString();
 Directory.SetCurrentDirectory(_startUpDir);

# 编译和调试

  • Cblp、OeStdServiceComponent项目都需要引用Ligg.Ewa.Interface项目。启动项目和Ligg.Ewa.Cblp项目之间, 启动项目和OeStdServiceComponent项目之间没有依赖关系,通过Ioc来调用; Vs2019是可以进去Debug的。详见 博客园: C# 通过Ioc和反射的实现依赖注入(DI)和面向切面编程(AOP)

  • Cblp、OeStdServiceComponent项目的标准服务都必须继承Ligg.Ewa.Interface的接口OeStdService, Cblp的Service不用继承。

  • Cblp和OeStdServiceComponent项目的目标框架可以是.net Framework、.net Standand或.net Core。

  • 开发时的目录结构和启动项目Ligg.Ewa.WinformApp和Ligg.Ewa.ConsoleApp的Output Path, 设置如下, 比较方便: proj debug

  • 在启动文件WinformApp.exe、ConsoleApp.exe并列, 有一个debug.ini文件, 可以方便调试不同的UI配置和初始化参数, 这样不用频繁更改Visual Studio的 Command line arguments。 在发行阶段要把此文件删除或者设置debug=false。这个参数会传递给程序, 决定程序的某些功能, 如读取配置文件的格式的顺序。内容示例如下:

[setting]
debug=true
path=Program\Main\netFxApp4.72\WinformApp.exe
//args=Demo Mvi^Function20|NoAuth zh-CN|szh
//args=Demo Svi^demo\SendLocalEmail2
args=Demo Szi^Demo\ChooseFile

# 集成开发

可以从下面几个方面进行集成开发

  • Winform控件的扩展

  • Cblp、OeStdService组件的开发, 采用提供的\release\下的Release版本作为主运行程序即可。

  • 当采用开源版本做集成开发, 请保留"Powered by Liggin2019"标识, 这是本框架唯一的额外版权要求。

  • 当然你也可以魔改本框架, 本框架采用MIT开源协议, 请遵循该协议即可。注意事项如下:

    • 发行版本的try/catch的处理
      在\src\Ligg.Ewa.WinForm\Forms\FunctionForm.cs, \src\Ligg.Ewa.Console\ScenarioForm.cs的如下所示的注释处, 往上删除不必要的try/catch

      //--Please optimize all try/catch before Release in front of this point, after full testing!!!//

    • 发行版本的错误日志的处理
      在\src\Ligg.Ewa.WinForm\Forms\FunctionForm.cs, \src\Ligg.Ewa.Console\ScenarioForm.cs的如下所示的注释处, 自行添加错误日志

      //--write into error log

    • 发行版本的事务日志的处理
      在\src\Ligg.Ewa.WinForm\Forms\FunctionForm.cs, \src\Ligg.Ewa.Console\ScenarioForm.cs的如下所示的注释处, 自行添加事务日志

      //--write into readTextlog
      //--write into transaction log


注意

  • 从3.0版本开始Cblp已不支持COM组件