From 77bfaba7ff0c7a670c61dfd002d9f688a86d7aec Mon Sep 17 00:00:00 2001 From: yuetsh <517252939@qq.com> Date: Mon, 2 Nov 2026 22:19:28 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AF=BC=E5=87=BA=20EXE=EF=BC=9A=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=E4=B8=8A=E7=9A=84=E6=95=99=E6=9D=90=20dll=20?= =?UTF-8?q?=E8=AF=BB=E4=B8=8D=E4=BA=86=EF=BC=88root=20=E6=8B=B7=E8=BF=9B?= =?UTF-8?q?=E5=8E=BB=E7=9A=84=E6=96=87=E4=BB=B6=E6=98=AF=20600=EF=BC=8C?= =?UTF-8?q?=E5=AE=B9=E5=99=A8=E9=87=8C=E7=9A=84=E5=B9=B3=E5=8F=B0=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E8=AF=BB=E4=B8=8D=E5=88=B0=EF=BC=89=E6=97=B6=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=E4=B8=AD=E6=96=87=E5=8E=9F=E5=9B=A0=E5=92=8C=E6=94=B9?= =?UTF-8?q?=E6=B3=95=EF=BC=8C=E4=B8=8D=E5=86=8D=E6=8A=8A=E8=8B=B1=E6=96=87?= =?UTF-8?q?=E7=9A=84=E7=B3=BB=E7=BB=9F=E6=8A=A5=E9=94=99=E7=BB=99=E5=AD=A6?= =?UTF-8?q?=E7=94=9F=E7=9C=8B=EF=BC=9B=E9=83=A8=E7=BD=B2=E8=AF=B4=E6=98=8E?= =?UTF-8?q?=E8=A1=A5=E4=B8=8A=20chmod=20755=20=E7=9B=AE=E5=BD=95=E3=80=816?= =?UTF-8?q?44=20=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 --- deploy/README.md | 7 +++++++ runtime/Sim.Runner/ExeExporter.cs | 28 +++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/deploy/README.md b/deploy/README.md index 9894b96..e66078c 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -129,6 +129,13 @@ scp "$B"/公共库/设备控制类库/设备控制/DeviceCtrlLibrary.dll "$B"/ "$B"/项目7/任务二/寝室情景模式/寝室情景模式/bin/Debug/*Interop.WMPLib.dll 服务器:IOT_SIM/textbook-libs/ ``` +容器里的平台用普通用户运行,目录和文件要让其他用户能读(用 root 拷的文件常常是 `-rw-------`,导出时会提示"权限不够"): + +```bash +chmod 755 ~/IOT_SIM/textbook-libs +chmod 644 ~/IOT_SIM/textbook-libs/*.dll +``` + 拷好后不用重启,下一次导出就能用。本机开发时同样放在仓库根目录的 `textbook-libs/`(已在 .gitignore 里),也可以用环境变量 `SIM_TEXTBOOK_LIBS` 指到别处。 ## 备份与恢复 diff --git a/runtime/Sim.Runner/ExeExporter.cs b/runtime/Sim.Runner/ExeExporter.cs index 97fd722..9f1a69d 100644 --- a/runtime/Sim.Runner/ExeExporter.cs +++ b/runtime/Sim.Runner/ExeExporter.cs @@ -69,7 +69,7 @@ internal static class ExeExporter /// libsDir:教材 dll 所在目录;galleryDir:平台素材库 public static Result Export(string projectDir, string libsDir, string galleryDir, string assemblyName) { - var libs = Directory.Exists(libsDir) ? Directory.GetFiles(libsDir, "*.dll").OrderBy(p => p, StringComparer.Ordinal).ToArray() : Array.Empty(); + var libs = TextbookLibs(libsDir); if (!libs.Any(p => Path.GetFileName(p) == "DeviceCtrlLibrary.dll")) throw new InvalidOperationException("服务器上没有放教材的设备类库(真机版 DeviceCtrlLibrary.dll 等),不能导出 EXE,请联系老师"); @@ -135,6 +135,32 @@ internal static class ExeExporter return new Result(emit.Success, pe.ToArray(), diagnostics); } + /// + /// 教材 dll 的路径。目录或文件读不了时(服务器上拷进去的文件权限是 600,容器里的平台用户读不到)说明原因, + /// 不把英文的系统报错直接给学生看。 + /// + private static string[] TextbookLibs(string libsDir) + { + if (!Directory.Exists(libsDir)) return Array.Empty(); + string? current = null; + try + { + var libs = Directory.GetFiles(libsDir, "*.dll").OrderBy(p => p, StringComparer.Ordinal).ToArray(); + foreach (var lib in libs) + { + current = lib; + using var _ = File.OpenRead(lib); + } + return libs; + } + catch (UnauthorizedAccessException) + { + var what = current == null ? "目录" : Path.GetFileName(current); + throw new InvalidOperationException( + $"服务器上的教材设备类库读不了({what} 的权限不够),不能导出 EXE,请联系老师(服务器上执行 chmod 755 textbook-libs 和 chmod 644 textbook-libs/*.dll)"); + } + } + /// /// 每个窗体、控件类的 .resources:VS 生成的 Designer.cs 用 ComponentResourceManager 读窗体的 .resx, /// 平台没有 .resx。媒体播放器的 OcxState 放默认状态,其他取到 null(和运行时一样)。