在这里插入图片描述

前言

上一篇我们完整梳理了工业上位机整体架构、技术栈、分层设计与全套学习路线,让大家彻底明白:企业级工业项目绝对不能“代码堆一起、逻辑胡乱写”。

从本篇开始,我们正式进入从零落地实战阶段

很多新手学上位机开发,第一步就走错:直接新建一个WinForm项目,所有业务、硬件、数据逻辑全部堆砌在一个工程里。写出来的代码只能勉强运行,无法拓展、无法维护、无法适配多硬件、无法商用量产。

本篇带你从零搭建工业级标准化分层解决方案,严格遵循量产项目规范,手把手完成环境配置、多项目拆分、层级依赖约束、基础库引入与工程初始化,为后续所有模块开发打下坚实骨架。

本篇目标:搭建一套可直接用于企业量产的C#工业上位机项目骨架。

一、开发环境配置(工业项目稳定版)

1. 开发工具选择

工业现场软件对系统兼容性、运行稳定性要求极高,不会追逐最新框架版本,本项目统一使用工业领域通用稳定组合:

  • 开发工具:Visual Studio 2022(安装.NET桌面开发组件)

  • 目标框架:.NET Framework 4.7.2

  • 编译平台:x64 专用(适配工业设备64位系统)

选型说明:.NET Core/.NET 5+跨平台性更强,但工业老旧工控机、XP/Win7嵌入式系统兼容性差,.NET Framework 4.7.2是目前工业上位机的最优平衡点,兼顾稳定性、兼容性与功能完整性。

2. VS环境组件安装

安装VS2022时必须勾选以下组件,否则会出现窗体设计、编译、引用报错:

  • .NET桌面开发

  • Windows窗体设计器

  • C#编译与开发工具

二、企业级解决方案架构设计(10个子项目分层)

普通学生项目、个人Demo都是单项目架构,而工业量产项目必须是多项目分层架构

我们将整套工程拆分为 10个独立类库/应用项目,严格遵循单向依赖、层级隔离、单一职责原则,彻底解耦UI、业务、硬件、数据、脚本逻辑。

整体层级依赖规则(核心红线)

上层依赖下层,下层绝不反向依赖;同级禁止互相引用。

简单理解:UI层可以调用服务层、服务层可以调用数据层,但是数据层绝对不能引用UI层,杜绝所有循环依赖与耦合问题。

10大项目清单与定位回顾

  • 1. Core(核心基础层):全局枚举、接口、模型、通用工具、服务定位器(最底层、无任何依赖)

  • 2. Data(数据持久层):数据库、JSON仓储、配置读写、云端上报、离线缓冲

  • 3. Devices(设备驱动层):设备基类、设备工厂、通用设备逻辑封装

  • 4. HAL(硬件抽象层):真实/仿真硬件适配、硬件服务工厂、硬件解耦核心

  • 5. Workflow(流程引擎层):节点定义、连线逻辑、流程运行调度

  • 6. Scripting(脚本扩展层):Lua脚本引擎、C#脚本交互、脚本调试

  • 7. Services(基础服务层):报警、日志、多语言、审计、参数、状态管理

  • 8. Business(业务逻辑层):生产、品质、追溯、维保核心业务逻辑

  • 9. UI(界面展示层):所有窗口、控件、页面导航、可视化交互

  • 10. App(启动入口层):程序唯一入口、DI容器初始化、全局服务注册

三、手把手创建分层项目工程

1. 创建空白解决方案

  1. 打开 Visual Studio 2022 → 创建空解决方案

  2. 命名:IndustrialVisionPlatform

  3. 选择保存路径,不创建默认项目,先保留空解决方案

2. 依次创建底层类库项目(优先级从低到高)

所有底层模块统一选择 【类库(.NET Framework)】,目标框架全部指定为 4.7.2

按顺序创建,保证依赖顺序绝对正确:

  1. 创建 Core 项目(无任何引用,全局最底层)

  2. 创建 Data 项目(仅引用 Core)

  3. 创建 Devices 项目(仅引用 Core)

  4. 创建 HAL 项目(引用 Core、Devices)

  5. 创建 Workflow 项目(仅引用 Core)

  6. 创建 Scripting 项目(仅引用 Core)

  7. 创建 Services 项目(引用 Core、Data、HAL、Workflow、Scripting)

  8. 创建 Business 项目(引用 Core、Services、Data、HAL)

  9. 创建 UI 项目(Windows窗体应用,引用 Core、Services、Business、Workflow、Scripting)

  10. 创建 App 项目(Windows窗体应用,作为启动入口,引用所有层)

3. 统一项目配置规范(工业项目必设)

选中所有项目,统一配置以下参数,杜绝后续编译报错、平台不兼容问题:

  • 目标框架:.NET Framework 4.7.2

  • 生成平台:x64

  • 禁止不安全代码:关闭(适配硬件串口、指针、外设调用)

  • 程序集名称、默认命名空间:与项目名统一

  • 调试信息:完整PDB文件(方便线上报错定位)

四、基础NuGet包统一引入(全项目通用)

工业项目无需堆砌多余插件,只引入刚需、稳定、常用的第三方库,避免版本冲突与项目臃肿。

在Core公共层统一安装,下层统一复用:

  • Newtonsoft.Json:工业项目万能序列化,处理JSON配置、数据存储

  • NLog:分级日志记录、文件分割、异常日志持久化

  • MoonSharp:Lua脚本解析与执行(后续脚本引擎核心依赖)

  • Microsoft.Extensions.DependencyInjection:官方DI容器,实现项目解耦

规范说明:所有第三方包统一在底层Core引入,上层项目直接引用底层即可,不允许各项目单独重复安装,统一版本、统一管理。

五、基础通用工具类初始化(Core层打底)

为了让项目具备基础可用能力,我们先在Core层创建工业项目高频通用工具,后续所有模块直接复用。

1. 全局路径工具类

统一管理程序运行目录、配置目录、日志目录、缓存目录,避免代码中到处写死路径。

using System;
using System.IO;

namespace Industrial.Core.Utils
{
    public static class PathHelper
    {
        /// <summary>
        /// 程序根目录
        /// </summary>
        public static string RootPath => Environment.CurrentDirectory;

        /// <summary>
        /// 配置文件目录
        /// </summary>
        public static string ConfigPath => Path.Combine(RootPath, "Config");

        /// <summary>
        /// 日志目录
        /// </summary>
        public static string LogPath => Path.Combine(RootPath, "Logs");

        /// <summary>
        /// 脚本文件目录
        /// </summary>
        public static string ScriptPath => Path.Combine(RootPath, "Scripts");

        /// <summary>
        /// 确保目录存在,不存在则创建
        /// </summary>
        public static void EnsureDir(string path)
        {
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
        }

        /// <summary>
        /// 初始化所有全局目录
        /// </summary>
        public static void InitAllPath()
        {
            EnsureDir(ConfigPath);
            EnsureDir(LogPath);
            EnsureDir(ScriptPath);
        }
    }
}

2. 全局异常处理工具

using System;

namespace Industrial.Core.Utils
{
    public static class ExceptionHelper
    {
        /// <summary>
        /// 获取完整异常信息(包含内部异常)
        /// </summary>
        public static string GetExceptionMsg(Exception ex)
        {
            string msg = ex.Message;
            if (ex.InnerException != null)
            {
                msg += $" 内部异常:{ex.InnerException.Message}";
            }
            return msg;
        }
    }
}

六、程序启动入口初始化(App层)

App层作为唯一启动入口,负责程序启动时的目录初始化、日志初始化、全局配置加载

在App项目的Program.cs中编写启动逻辑:

using System;
using System.Windows.Forms;
using Industrial.Core.Utils;

namespace Industrial.App
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点
        /// </summary>
        [STAThread]
        static void Main()
        {
            try
            {
                // 1. 初始化全局目录
                PathHelper.InitAllPath();

                // 2. 开启程序视觉样式
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);

                // 3. 后续在此注入DI、服务、硬件初始化
                // 4. 启动主窗口
                Application.Run(new MainShellForm());
            }
            catch (Exception ex)
            {
                MessageBox.Show($"程序启动失败:{ExceptionHelper.GetExceptionMsg(ex)}", "启动异常", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
    }
}

七、本篇开发总结与工程规范复盘

到这里,我们已经彻底完成了工业上位机项目的标准化骨架搭建,区别于所有新手Demo项目,我们的工程具备以下企业级特质:

  • 层级清晰:10大项目分层隔离,职责单一、互不污染

  • 依赖规范:严格单向依赖,从根源杜绝代码耦合

  • 配置统一:框架版本、编译平台、第三方库全部统一标准

  • 基础能力完善:自带路径管理、异常处理、目录初始化

  • 可拓展性极强:后续新增硬件、业务、脚本、流程无需改动原有架构

很多开发者做项目后期崩溃、代码难以维护、改一个BUG崩一片,本质原因就是前期工程架构不规范。本篇的骨架搭建,直接决定了你后续项目的上限。

下篇预告

下一篇我们将进入工业UI框架核心实战!手把手搭建工业级主窗口架构,实现顶部标题栏、侧边导航、中间内容区、底部状态栏四分区布局,解决WinForms原生Dock布局错乱、自适应失效、控件错位等工业开发高频坑点。

更多推荐