☰
Delphi Web 老包 deweb2020-05-23 beta2 拆包与 UniGUI 实战指南
2026/10/14 13:39:49 网站建设 项目流程

简介:DeWeb 是一套面向 Delphi 开发者的网页化转换工具,让习惯 Object Pascal 的工程师无需学习 HTML、JavaScript、Java、PHP、ASP 或 C#,即可把现有 Delphi 程序快速改造成可在手机、平板等各类客户端访问的网页应用,适合希望低成本迁移桌面项目、拓展 Web 交付能力的中高级开发者。压缩包共 2669 个文件,约 24.59MB,以 pas、dfm、dpr、dproj 等 Delphi 源码与工程文件为主,辅以 dcu 编译单元、cpp、h 等 C++ 相关文件,以及 js、css、html 等前端资源,并包含 res、ico、jpg、gif 等界面素材和 exe、dll、bat 等运行与构建脚本,目录结构完整。资源内附安装控件、按版本复制 dcu、编译 DelphiWeb.dproj、浏览器访问演示页面以及新建 Form 并注册类等关键流程说明,可帮助读者快速跑通示例、理解页面注册机制,并在此基础上扩展自己的业务窗体。目前已有 1073 人学习下载,适合作为 Delphi 转 Web 方向的实践参考。

1. 从一份 Delphi Web 老包说起:deweb2020-05-23 beta2 new2.rar 到底能跑什么

如果你手头还压着几套 Delphi 老项目,又不想把业务逻辑重写成 Java 或 .NET,那deweb2020-05-23 beta2 new2.rar这类包就是典型的“续命型资源”。它本质是一套基于 Delphi 的 Web 应用开发框架,核心思路是用 Delphi 写服务端逻辑,通过 UniGUI 这类组件把 VCL 风格的界面直接映射成浏览器可访问的 Web 页面。换句话说,你原来写的窗体、按钮、事件,不用推倒重来,就能跑在浏览器里。

这个包适合谁?一是维护存量 Delphi 系统的工程师,二是想用 Pascal 语法快速搭内部管理后台的开发者,三是需要把桌面端工具改造成 B/S 架构但又不想换技术栈的团队。它解决的不是“高并发互联网级应用”,而是“让 Delphi 代码以最低成本上网”。下面我按实际拆包、配置、跑通、排错的顺序,把这份资源讲透。

2. 拆包先看目录:UniGUI 运行时、Demo 与编译产物的分布逻辑

拿到deweb2020-05-23 beta2 new2.rar后,别急着双击运行。先解压到一个纯英文、无空格的路径下,比如D:\delphi_web\deweb_beta2。中文路径在 Delphi 的包加载和 Web 资源映射阶段容易出玄学问题,血泪经验是:路径里带一个中文字符,都可能让服务端找不到ext-6之类的静态资源目录。

2.1 解压后的典型目录结构与识别方法

解压后你通常会看到类似这样的结构(不同打包者可能微调,但核心一致):

目录/文件作用是否必须
bin/或exe/编译好的可执行服务端程序是,快速验证用
source/或src/Delphi 源码单元,含 UniGUI 框架文件是,二次开发用
demo/或samples/示例项目,展示登录、表格、上传等建议看
ext/或ext-6/ExtJS 前端静态资源是,缺了页面白屏
lib/编译好的 dcu 或 bpl 包视版本而定
readme.txt版本说明、编译环境要求先读

我一般会先打开readme.txt,确认它要求的 Delphi 版本(常见是 Delphi 10.2 Tokyo 到 10.4 Sydney 之间)和 UniGUI 版本号。如果 readme 缺失,就看source/下是否有uniGUIBase.pas这类文件,用编辑器打开看头部注释里的版本信息。

2.2 判断这份包是“运行时完整版”还是“仅 Demo 源码”

这一步很关键,直接决定你能不能编译。判断方法:

  • 如果source/下只有demo相关的几个.pas,没有uniGUI*.pas核心单元,那它只是示例源码,你还需要单独安装 UniGUI 商业版。
  • 如果source/下包含uniGUIBase.pas、uniGUIConst.pas、uniGUIServer.pas等,并且lib/下有对应的.dcu,那这份包是带运行时的,可以直接编译。
  • 如果只有bin/下的 exe,没有源码,那只能跑现成功能,不能改。

常见做法是:先看bin/里有没有 exe,有就先跑起来看界面,确认功能符合预期,再回头折腾源码编译。别一上来就配 Delphi 环境,容易在版本兼容上卡半天。

3. 跑通第一个 UniGUI 页面:从 exe 启动到浏览器访问的完整链路

假设你拿到的是带 exe 的完整包,那最快验证方式就是直接启动服务端,然后用浏览器访问。这一章把启动参数、端口配置、静态资源映射和常见白屏问题一次讲清。

3.1 启动 exe 并确认监听端口

进入bin/目录,双击 exe 或从命令行启动。命令行方式能看到更多日志:

cd /d D:\delphi_web\deweb_beta2\bin start server.exe

如果 exe 名称是deweb_server.exe或uniGUIApp.exe,替换即可。启动后,控制台通常会打印类似:

Server started on port 8077 Document root: D:\delphi_web\deweb_beta2\bin

记下端口号。如果没打印,就看 exe 同目录下有没有.ini或.cfg配置文件,里面一般有Port=8077这样的字段。我一般会先确认端口没被占用:

netstat -ano | findstr :8077

有输出就说明端口被占,改配置文件里的端口,或者杀掉占用进程。

3.2 浏览器访问与静态资源路径校验

打开浏览器,输入http://localhost:8077。如果出现登录页或主界面,说明服务端和 ExtJS 资源都正常。如果白屏或 404,按 F12 看 Network 面板:

  • 如果ext-6/...下的 js/css 报 404,说明静态资源目录没映射对。检查 exe 同目录下是否有ext-6文件夹,或者配置文件里ExtRoot指向的路径是否存在。
  • 如果根路径就 404,说明服务端没把默认页配好。常见做法是在配置文件里设DefaultPage=index.html或StartPage=main。

提示:UniGUI 的静态资源映射对路径大小写敏感,Windows 下不觉得,部署到 Linux 或容器里就会翻车。建议统一用小写目录名。

3.3 用 Demo 源码编译一个最小页面

如果你要改功能,就得走源码编译。以 Delphi 10.4 为例,步骤:

  1. 打开 Delphi,File -> Open Project,选择demo/下的.dproj文件。
  2. 在Project -> Options -> Delphi Compiler -> Search Path里,把source/和lib/加进去。
  3. 确认Output Directory指向bin/,这样编译完直接能跑。
  4. 按 F9 编译运行。

一个最小的 UniGUI 窗体单元长这样:

unit MainForm; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, uniGUIBaseClasses, uniGUIClasses, uniGUImainmodule, uniGUIForm, uniGUIApplication, uniButton, uniLabel, uniEdit; type TMainForm = class(TUniForm) lblHello: TUniLabel; btnClick: TUniButton; edtName: TUniEdit; procedure btnClickClick(Sender: TObject); private { Private declarations } public { Public declarations } end; function MainForm: TMainForm; implementation {$R *.dfm} function MainForm: TMainForm; begin Result := TMainForm(UniMainModule.GetFormInstance(TMainForm)); end; procedure TMainForm.btnClickClick(Sender: TObject); begin lblHello.Caption := '你好,' + edtName.Text; end; end.

逻辑说明:TUniForm是 UniGUI 的窗体基类,TUniLabel、TUniButton、TUniEdit分别对应浏览器里的标签、按钮和输入框。btnClickClick是服务端事件,点击按钮后回传,服务端改完Caption再刷新到前端。参数上,UniMainModule.GetFormInstance负责窗体实例管理,避免多用户串数据。

编译前确认Search Path里uniGUIBaseClasses等单元能找到,否则会报File not found: 'uniGUIBaseClasses.dcu'。这时候就回到第 2 章,检查lib/下有没有对应 dcu,或者source/下有没有 pas 需要一起编译。

4. 避坑与排查:UniGUI 老包在 Win10/Win11 上的五个翻车点

这一章全是实际踩过的坑,每条按“现象 → 原因 → 解决”写。你如果卡在某个环节,先来这里对号入座。

4.1 启动即报“Cannot load package uniGUIXX.bpl”

现象:双击 exe 或编译时弹窗,提示找不到某个 bpl 包。
原因:Delphi 的包搜索路径没配,或者系统 PATH 里没有 bpl 所在目录。
解决:把lib/或bin/下所有.bpl所在目录加到系统环境变量PATH里,重启 Delphi。如果是编译期报错,在Project -> Options -> Packages里把Runtime Packages的搜索路径补上。

4.2 浏览器打开是空白页,Network 里 js 全 404

现象:页面白屏,F12 看到ext-6/ext-all.js404。
原因:静态资源目录没放对,或者配置文件里ExtRoot指向了绝对路径但实际不存在。
解决:确认 exe 同目录下有ext-6文件夹,且里面至少有ext-all.js、theme-triton等。如果是从别的机器拷来的包,经常漏掉这个目录。补上后重启服务端。

4.3 编译报“Unit uniGUIServer was compiled with a different version”

现象:编译时提示某个 dcu 版本不一致。
原因:lib/下的 dcu 是用另一个 Delphi 版本编译的,和你当前 IDE 不匹配。
解决:删掉lib/下所有 dcu,把source/下的 pas 全部加入项目重新编译。或者换用 readme 里指定的 Delphi 版本。我一般会先看source/uniGUIBase.pas头部注释里的版本号,再决定用哪个 IDE。

4.4 多用户访问时数据串了

现象:A 用户填的表单,B 用户刷新后看到了。
原因:把用户状态存到了全局变量或窗体类的 published 字段里,UniGUI 的窗体实例默认是每会话一个,但如果你用了Var全局变量就会串。
解决:所有会话相关数据放到TUniMainModule或TUniSession里,用UniSession取当前会话。别用全局var存用户输入。

4.5 部署到 Windows Server 后端口不通

现象:本机跑得好好的,放到服务器上外网访问不了。
原因:防火墙没放行端口,或者服务端绑定了127.0.0.1而不是0.0.0.0。
解决:在服务器防火墙入站规则里放行对应端口。检查配置文件里BindAddress或Host字段,改成0.0.0.0或留空。如果用了 IIS 反代,还要确认 IIS 的 URL Rewrite 规则把请求转到了正确端口。

注意:老版本 UniGUI 在 Win11 上可能遇到 Indy 组件兼容问题,表现为服务端启动后立即退出。常见做法是换用更新一点的 Indy 单元,或者直接在 Win10 虚拟机里跑。别在 Win11 上死磕,时间成本不划算。

5. 进阶:把老包改造成可维护的内部工具,以及我的验证习惯

跑通之后,下一步就是让它真正干活。我一般会做三件事:把配置外置、加一个健康检查接口、写一个最小回归清单。

5.1 配置外置与健康检查

别把端口、数据库连接串硬编码在代码里。在 exe 同目录放一个config.ini:

[Server] Port=8077 BindAddress=0.0.0.0 ExtRoot=./ext-6 [Database] Driver=SQLite Path=./data/app.db

然后在 Delphi 里用TIniFile读取:

uses System.IniFiles, System.SysUtils; var Ini: TIniFile; Port: Integer; begin Ini := TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'config.ini'); try Port := Ini.ReadInteger('Server', 'Port', 8077); UniServerModule.Port := Port; finally Ini.Free; end; end;

逻辑说明:ExtractFilePath(ParamStr(0))取 exe 所在目录,保证配置文件跟着程序走。ReadInteger第三个参数是默认值,配置缺失时不会崩。参数上,UniServerModule.Port是 UniGUI 服务端模块的端口属性,改完需要重启服务端生效。

健康检查接口更简单,加一个TUniPageControl或直接用一个返回 JSON 的TUniCustomSession处理:

procedure TMainModule.UniSessionCreate(Sender: TObject); begin // 会话创建时记录日志,便于排查 end; function TMainModule.HealthCheck: string; begin Result := '{"status":"ok","time":"' + FormatDateTime('yyyy-mm-dd hh:nn:ss', Now) + '"}'; end;

这样运维可以用curl http://localhost:8077/health确认服务活着。

5.2 我的验证清单与一个习惯

每次改完配置或升级包,我会按这个清单走一遍:

检查项命令/操作预期
端口监听netstat -ano | findstr :8077有 LISTENING
首页可访问浏览器打开http://localhost:8077出现登录页
静态资源F12 Network 看ext-all.js200
登录流程用 demo 账号登录进入主界面
数据提交填表单点保存数据库有记录
多会话隔离两个浏览器分别登录数据不串

最后说个习惯:从那以后我每次拿到这种带 beta 字样的老包,都强制先在虚拟机里跑一遍完整流程,确认没有捆绑奇怪东西、没有缺静态资源、没有端口冲突,再往生产环境搬。因为 beta 版的包,打包者自己可能都没在干净环境里验证过,你直接上生产就是给自己埋雷。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询