DcmGet 是一个默认离线运行的 DICOM C-MOVE 下载工作站。3.6.1 在现有 FastAPI/Uvicorn 服务与任务核心上使用 NiceGUI 提供中文界面:Windows 本机通过独立 WebView2 窗口操作,不再默认弹出系统浏览器;局域网电脑仍可使用浏览器访问。每个 Profile 进程只运行一个下载任务,并独立启动一个 DCMTK storescp;任务中的检查号按顺序执行 movescu。关闭、刷新或断开界面不会停止后台下载,重新打开即可查看实时状态。
应用仍支持多个持久 Profile(i1、i2……)。Windows 安装版使用固定端口 8786 的统一工作台,通过紧凑 Profile 卡片进入实例,并可在页面顶部快速切换 Profile;任务、设置、日志、PDI 和运维功能始终留在同一个管理页面。每个 Profile 仍是独立后台进程,配置、Web 端口、接收 AE/端口、任务恢复点和日志互相隔离。不同 Profile 必须使用不同的 Web 端口和接收端口,通常也应配置独立接收 AE,并在 PACS 中分别建立 Move Destination 映射。收到的文件按可配置的 DICOM 元数据目录归档,下载结束后可自动生成包含原始 DICOM、DICOMDIR、中文 OHIF 和本地只读 HTTP 启动器的 PDI 便携目录。
各版本新增内容见 CHANGELOG.md,也可以在 Web 控制台点击“版本说明”查看。
- Windows x64、macOS ARM64/x86_64、Linux x86_64;不支持任何 32 位系统或运行时
- 64 位 Python 3.10 或更高版本;Windows 源码运行必须使用 AMD64/x64 Python
- 发布部署使用 DCMTK 3.7.0;代码兼容本机 DCMTK 3.6.9。Windows 成品仅携带运行所需的
movescu、storescp、dcmmkdir、dcmdump及其 DLL、字符集和许可证数据 - 当前自动发布只生成 Windows x64 一键安装器、便携版和 ZIP;macOS/Linux 仍可从源码运行,但暂不生成成品安装包
- 主控制台、API、字体和图标均随程序本地提供,下载与 PDI 运行不依赖 CDN 或云服务;仅当 Windows 管理中心启用自动更新时会访问固定的 HTTPS 发布源
- 3.0.0 起不再包含或依赖 PyQt5;旧版 Qt 说明仅保留在历史版本记录中
源码部署不携带第三方二进制,首次部署需要能访问 Python 包源、OFFIS DCMTK 下载源和 npm 官方源以下载经过固定 SHA-256 校验的 OHIF。Windows 成品发布物已内置 OHIF 与本地启动器;PDI 导出完成后的阅片不需要访问互联网。
Windows 发布物拆分为三个独立下载项,获取安装器时不再同时下载重复的便携运行时:
DcmGet-3.6.1-Setup-x64.exe:默认推荐的一键安装器,内置 x64 Python 运行时、FastAPI/Uvicorn、NiceGUI 离线工作台、Windows WebView 外壳、精简的 x64 DCMTK 3.7.0 运行集、离线中文 OHIF、PDI 本地只读 HTTP 启动器、Microsoft Visual C++ x64 Runtime 和kayisoft-dcmgetWindows 服务。服务随系统自动启动管理中心,并只恢复用户明确选择运行的 Profile;安装器创建DcmGet Web TCP与DcmGet Receiver TCP两条仅限域/专用网络的程序级入站规则。DcmGet-3.6.1-windows-x64-portable.exe:无需安装的单文件便携版;首次启动会把逐文件 SHA-256 校验通过的精简 x64 DCMTK 运行集发布到%LOCALAPPDATA%\DcmGet\runtime\dcmtk\<版本与清单哈希>\,以后启动和软件升级会复用内容相同的稳定用户级路径。两个进程同时首次启动时也只会原子发布一份运行集。PDI 同样使用原始 DICOM 和离线 OHIF。便携版不注册 Windows 服务,也不自动常驻管理中心。DcmGet-3.6.1-windows-x64.zip:解压后直接运行的独立目录版,包含与安装版一致的 NiceGUI 离线工作台与 Windows WebView 外壳、精简 DCMTK 运行集、离线 OHIF 和 PDI 启动器,但不自动注册 Windows 服务或常驻管理中心。
Windows 32 位系统、32 位 Python 和 x86 应用载荷均不受支持。安装器使用 x64compatible 限制目标架构:可在 x64 Windows 原生运行,也允许 Windows 11 ARM64 通过系统的 x64 兼容层运行;不需要也不接受原生 ARM64 Python。Inno Setup 6 的安装引导程序自身是 x86 兼容程序,但它会拒绝 32 位 Windows,且只安装经过校验的 AMD64 DcmGet、Python 和 DCMTK。构建脚本会同时验证构建 Python、DcmGet.exe、DcmGetPdiServer.exe、storescp.exe 和 movescu.exe 的 PE 架构,任何一项不是 AMD64 都会停止发布;PDI 的 Python 回退启动器也会拒绝 32 位运行时。
便携版和 ZIP 不会自动取得管理员权限创建防火墙规则;需要从其他主机打开 Web 控制台或接收 C-STORE 时,请手工允许 DcmGet.exe 和实际运行的 storescp.exe,或优先使用安装版。单文件便携版应放行便携 EXE 本身,以及 %LOCALAPPDATA%\DcmGet\runtime\dcmtk\<版本与清单哈希>\dcmtk-3.7.0-win64-dynamic\bin\storescp.exe;ZIP 版应放行解压目录中的 DcmGet.exe 和 _internal\.runtime\dcmtk\windows-x86_64\dcmtk-3.7.0-win64-dynamic\bin\storescp.exe。不要放行每次启动都会变化的 PyInstaller _MEI... 临时路径。
三种发布物的 PDI 阅片过程均不连接互联网:OHIF 静态资源已内置并校验,同时会复制一份到便携目录;DICOM 清单和影像数据只从用户选择的 PDI 根目录读取。
安装版不要求目标电脑预装 Python。再次运行新版安装包时,会识别原安装记录并在原目录完成覆盖升级;用户配置、注册码和试用计数保存在 Windows 用户数据目录,升级和卸载都不会覆盖或删除这些数据与下载结果。默认下载目录为“文档\DcmGet\Dicom”。
- 自动更新只在 Windows x64 安装版的
8786统一管理中心启用。便携版、ZIP 和源码运行不会自动替换程序文件。 - 默认策略为外网可用时后台检查。没有外网时只记录“离线”状态,不阻塞管理中心、Profile 或 DICOM 下载。专网环境可在“软件更新”中关闭自动检查;关闭后不会访问更新服务器。
- 更新客户端只访问由
bwg-snell提供的固定地址https://dcmget.v2ex.com.cn/updates/,不依赖 GitHub Releases。地址不可达时显示离线状态并等待下次检查,不影响 DICOM 下载。 - 管理中心优先选择与当前版本精确匹配的组件增量包,只下载并替换发生变化的
DcmGet.exe或_internal/**文件。增量条件不成立时自动选择完整安装包。 - 稳定通道使用单文件
UPDATE-MANIFEST.signed.json。客户端先使用内置的独立 Ed25519 更新公钥验证清单,再校验版本、下载地址边界、文件大小、SHA-256、允许替换路径和安装树哈希;更新私钥不放入客户端或更新服务器,也不与注册码私钥共用。 - 组件更新在受限暂存目录中逐文件备份、替换和校验;失败时回滚,并按更新前状态恢复
kayisoft-dcmget服务。Profile 配置、任务恢复点、日志、授权/试用数据和下载影像都不在可替换路径中。 - 3.6.0 及更旧安装未内置新的 Ed25519 更新公钥,首次升级到 3.6.1 需要手动运行一次完整测试安装包。完成这次引导升级后,后续小版本即可通过管理中心下载组件更新;只有 Python/DCMTK、Windows 服务或安装布局变化时才需要完整安装包。
安装完成后,kayisoft-dcmget 以 LocalSystem 自动服务运行,但固定使用安装用户的 %APPDATA%、%LOCALAPPDATA% 和 %USERPROFILE%,因此会继续读取原有 Profile、恢复点和配置。桌面和开始菜单的“DcmGet”主入口会启动本机 WebView2 窗口并连接 http://127.0.0.1:8786/;关闭该窗口不停止后台服务或下载任务。开始菜单另提供“DcmGet 启动后台服务”和“DcmGet 停止后台服务”。内置服务权限允许普通本机用户查询、启动和停止服务,不需要应用密码或再次提升权限。注册、升级和卸载 Windows 服务本身仍属于系统级安装操作,首次运行安装器时需要管理员/UAC。
同一局域网的管理电脑可打开 http://<DcmGet Windows 主机 IP>:8786/。任务、设置、日志、PDI 和运维功能都在统一工作台内完成;管理中心只通过本机回环地址访问各 Profile 的独立 Web 端口,不会把浏览器跳转到其他端口。为避免与管理中心冲突,Profile 的 SCP 和 Web 端口均不能使用 8786。
新建 Profile 默认保持停止。用户在统一工作台明确启动后,运行选择会写入独立的管理状态文件,kayisoft-dcmget 在 Windows 或服务重启后只恢复这些 Profile;用户明确停止后则保持停止。受监管的 Profile 异常退出时仍会自动拉起,删除 Profile 前必须先停止。切换当前 Profile 只改变右侧页面内容,不会停止其他正在执行的下载任务。
发布门禁会复核 Windows 运行时和应用载荷为 AMD64,核对精简 DCMTK 白名单,并输出 RELEASE-MANIFEST.json 和 SHA256SUMS.txt。GitHub Actions 配置 DCMGET_SIGN_CERTIFICATE_BASE64 与 DCMGET_SIGN_CERTIFICATE_PASSWORD 机密后,会对 EXE 载荷和最终发布物执行 Authenticode 签名、时间戳及签名复核。未配置证书时仍可生成内部测试包,但发布清单会明确标记 UNSIGNED,Windows SmartScreen 也可能显示未知发布者;对外商业交付应只发放清单为 SIGNED 的发布物。
维护者可在 GitHub Actions 中手动运行 Windows Release 工作流,也可在 Windows x64 构建机执行:
python -m pip install -r requirements-build.txt
python scripts/download_dcmtk.py --platform windows-x86_64
python scripts/build_windows.py --version 3.6.1PyInstaller 生成的可执行文件已包含 Python 解释器,因此不再额外运行独立的 Python 安装程序。
- Windows 安装版管理中心固定监听
0.0.0.0:8786;首个 Profile 默认监听0.0.0.0:8787,后续 Profile 使用各自的web_port。本机优先从http://127.0.0.1:8786/进入,局域网管理端使用 Windows 主机 IP 访问同一端口。 - 按当前产品决策,Web 控制台使用裸 HTTP,不生成证书,也不启用 HTTPS。患者相关数据、配置和操作内容在网络中未加密传输,只能部署在受信任的医院内网或隔离 VLAN;禁止把端口映射到公网、访客 Wi-Fi 或不受信任网络。
- 控制台不再要求设置或输入应用密码。浏览器会自动取得绑定当前客户端地址的短期会话,修改操作仍要求同源请求与 CSRF 令牌;这些机制不能替代传输加密,也不能把裸 HTTP 安全地暴露到公网。
- 主控制台不向第三方发送遥测,不引用 CDN。PACS、DICOM、日志、配置、任务状态和 PDI 均留在部署主机或用户明确选择的目录。
- Windows 安装器的两条入站规则只允许域/专用网络并阻止边缘遍历;如网络被 Windows 标记为“公用”,远端访问会被拒绝。便携版和 ZIP 需由管理员按相同边界手工配置。
程序启动时不再要求输入日期口令。未注册电脑默认可免费启动 30 个批量下载任务;每个任务仅在第一次真正开始 C-MOVE 时扣一次,暂停、恢复、重试失败项和 PDI 导出都不会重复扣次。配置错误、storescp 启动失败或只打开页面不会扣次。试用次数和注册码属于整台电脑,多开 Profile 不会各自获得额外次数。试用结束后必须输入当前电脑的离线注册码。Web 控制台会显示剩余次数,并可随时点击“软件注册”查看和复制机器码。
授权人员在保存有私钥的 Mac 上生成注册码:
# 从源码运行注册机
python tools/dcmget_license_generator.py ABCDEF-123456-7890AB-CDEF12 --customer "示例医院"
# 可选:指定到期日并写入文件
python tools/dcmget_license_generator.py ABCDEF-123456-7890AB-CDEF12 \
--customer "示例医院" --expires 2027-12-31 --output 示例医院.lic
# 构建仅供授权人员使用的 macOS 单文件注册机
python tools/build_license_generator_macos.py注册机默认从 ~/.dcmget-license/ed25519-private.pem 读取 Ed25519 私钥。私钥不会写入注册码、客户端、源码部署包或 Windows 安装包;请离线备份并且不要交给客户。macOS 构建产物位于 release/license-generator/。
客户端只保存签名后的注册码和机器绑定试用计数。试用计数采用文件锁和双份冗余状态;Windows 安装版的锚点位于共享程序数据目录,普通重装、切换用户或只删除主 trial.json 不会恢复次数,安装升级与卸载也不会删除这些文件。macOS/Linux 源码部署的锚点仍属于当前系统用户。
复制限制来自“机器码 + Ed25519 签名”。纯离线客户端无法阻止管理员清除全部本地试用状态,若需要不可重置的强试用限制,应增加在线授权服务。源码部署包便于内部部署,但持有源码的人能够修改校验逻辑;对外发放时应使用构建后的 EXE,而不是源码包。
使用源码时,在项目目录执行:
Set-ExecutionPolicy -Scope Process Bypass
.\scripts\bootstrap_windows.ps1
.\scripts\run_ui.ps1部署脚本会检查 AMD64/x64 Python 3.10+、拒绝 32 位和原生 ARM64 Python、重建干净的 .venv、安装 FastAPI/Uvicorn 等运行依赖、下载 x64 DCMTK 3.7.0、准备离线 Web 控制台、离线 OHIF 和 PDI 本地启动器,并检查 VC++ Runtime。管理员模式下会为主程序和实际监听的 storescp.exe 创建仅限域/专用网络的程序级入站规则;规则不固定端口,可覆盖不同 Profile 配置。Windows 11 ARM64 用户应安装 x64 Python 并通过系统兼容层运行。重建虚拟环境不会改动配置、注册码、试用记录或下载结果。
./scripts/bootstrap_macos.sh
./scripts/run_ui.sh./scripts/bootstrap_linux.sh
./scripts/run_ui.shmacOS/Linux 使用与 Windows 相同的离线 OHIF 静态资源;启动器只为当前 PDI 目录提供本地只读 HTTP 服务,不对外网开放。
- 启动 DcmGet。Windows 安装版由
kayisoft-dcmget服务自动启动统一管理中心,并恢复用户上次明确选择运行的 Profile;新 Profile 需要在工作台中手动启动。点击 DcmGet 快捷方式会打开统一工作台;源码版、便携版和 ZIP 版仍由程序进程启动 Web 服务。全程不要求应用密码,页面顶部始终提示当前为“仅限可信内网、HTTP 未加密”。 - 打开“设置”,填写 PACS 地址、端口和 PACS AE。三类 AE Title 必须是 1-16 个可打印 ASCII 字符,非法字符会在对应字段直接提示。首个实例默认使用本机调用 AE
DCMGET、接收 AEDCMGET和接收端口6666;如需下载后脱敏,可在同一页启用匿名处理并选择方案。 - 选择或拖入 TXT、CSV 或 XLSX,也可以直接粘贴多行检查号。CSV/XLSX 可选择表头列;空行会忽略,重复项会按首次出现顺序去重,公式单元格会被拒绝。选择服务器上的目标目录、目录模板和 PDI 快捷选项后开始任务。
- 开始前会检查配置、DCMTK、目标目录、磁盘保留空间和当前 Profile 的接收端口。
storescp就绪后,程序按检查号顺序执行movescu。 - 任务主页显示总进度、当前检查号、文件数、下载速度、状态统计、PDI 状态和操作按钮。可暂停、继续、停止、重试失败项、打开目标目录、打开 PDI 和查看默认脱敏的验收报告;关闭浏览器不会停止后台任务,也不会删除已收到文件。
- 需要同时运行另一个任务时,在统一工作台左侧点击“新建”,先配置新 Profile,再明确启动。新 Profile 使用独立后台进程;请改用不同 Web 端口和接收端口,通常也要使用独立接收 AE,并同步配置 PACS 的 Move Destination。不同 Profile 可以选择不同目标目录和 PDI 设置。源码版和便携版仍可使用
--profile N明确启动指定 Profile。 - 任务不超过 200 个检查号时显示逐项文件数、速度和耗时;超过 200 个时只显示聚合进度和状态统计,避免 40,000 条任务拖慢浏览器。所有归档文件统一以
.dcm结尾。 - 运行日志默认只显示错误,便于快速定位需要处理的问题;开启“显示详细日志”后才显示调试、信息、成功和警告。“清空显示”只清空浏览器视图,当前 Profile 的磁盘日志始终完整保留。
- 如需交付 U 盘,可在任务主页勾选“下载完成后生成 PDI 便携目录”并选择保存目录;首次使用仍需在设置中填写机构名称,阅片器等高级选项也在设置页管理。批次结束后点击“打开影像”,或用“打开导出目录”将整个目录复制到 U 盘。重启程序后也可点击“打开已有 PDI 目录”直接选择根目录阅片,无需寻找 JSON 文件。PDI 失败可单独重试,无需重新下载。
- DcmGet Web 版采用“一个 Profile 后台进程对应一个任务”模式,没有进程内任务列表或全局调度器。每次启动都会优先选择含未完成恢复点且当前未被占用的 Profile,否则选择编号最小的空闲 Profile。
- Profile 以
i1、i2等编号持久保存。每个 Profile 分别拥有配置文件、Web 端口、任务恢复点、会话状态和日志目录;关闭界面不会结束进程或删除任何状态。也可以用--profile N明确打开指定 Profile;若它已经运行,Windows 会重新打开连接现有地址的 WebView 窗口,不会创建重复后台进程。 - 管理中心的“Profile 工作台”可为任一 Profile 生成固定使用
--profile N的桌面快捷方式。默认名称取该 Profile 的接收端口和接收 AE,例如dcmget-6666-DCMGET;以后点击该快捷方式会启动对应进程或打开其现有页面。安装器创建的通用 DcmGet 快捷方式则固定打开8786管理中心。 - 每个运行实例只启动一个外部 DCMTK
storescp,任务中的movescu逐条顺序执行。不同实例必须使用不同监听端口;通常还应使用不同接收 AE,例如DCMGET:6666与DCMGET2:6667,并在 PACS 中把两个 Move Destination 分别映射到本机 IP 和对应端口。端口冲突会在预检时给出明确错误,不会自动共用接收器。 - 因为一个实例同一时刻只处理一个 C-MOVE,当前接收时间窗内新到达的 DICOM 会直接作为当前检查号结果接收,不要求返回文件中的
AccessionNumber与请求值一致;缺少该标签也不会再被隔离。程序仍会验证 DICOM 文件结构、SOP Instance UID 和最终文件完整性,损坏文件不会伪装成成功结果。 - 每处理完一个检查号都会写入当前 Profile 的恢复点。主机重启、进程异常或服务端临时中断后,再次启动会优先取得该 Profile 并继续未完成任务;已完成项不会重复下载,退出时正在处理的检查号会重新执行。浏览器关闭不属于任务中断。遗留的 DCMTK 子进程会先经过身份校验再清理;只有异常退出后无法确定属于哪个 Profile 的遗留暂存文件才会移入隔离目录,不会猜测归属或自动删除。
- 从 2.8.x 升级时,旧
tasks.sqlite3中的未完成任务会一次性拆分迁移到独立实例槽;从 2.7.x 直接升级时,全局active-task.sqlite3也会迁移。迁移保留任务编号、已完成结果、PDI 阶段和试用扣次状态;原数据库和迁移记录会保留,防止重复迁移或数据丢失。 - 接收暂存目录与目标目录可以位于不同卷。Windows 从
C:暂存归档到D:、U 盘或网络共享,以及 macOS/Linux 的跨文件系统归档,都会先在目标目录写入并同步临时文件,再原子发布最终.dcm;复制失败时保留源文件,避免跨卷重命名失败造成丢失。 - 多个实例可以选择同一个目标根目录。最终文件发布使用跨进程锁;相同 SOP UID 且内容相同的文件会去重,内容不同的同名对象不会互相覆盖。为了便于区分任务和减少目录竞争,仍建议为不同实例选择独立目标目录。
匿名功能默认关闭,可在“设置 → 下载后匿名处理”中开启。最终目录名使用处理后的 Patient ID、检查号和 Study UID,文件名使用处理后的 SOP Instance UID。三个内置方案如下:
- “基础脱敏(院内)”:处理患者姓名、Patient ID、检查号、常见直接身份字段、人员姓名和私有标签,但保留日期、机构、描述及 DICOM UID。该档仍可能保留自由文本身份信息,
PatientIdentityRemoved会写为NO,只适合受控院内流程。 - “研究匿名(推荐)”:在直接身份处理基础上稳定映射关联 UID、对同一患者一致偏移日期,并清理机构、描述和私有标签;保留部分人口学及设备信息。
- “严格元数据匿名”:在研究方案基础上继续清除日期、时间、人口学及设备字段。
这些方案参考 DICOM PS3.15 Annex E 的常见元数据处理思路,不等同于完整的 PS3.15 合规认证。程序不会分析或修改像素中的烧录文字、人脸特征;研究/严格方案遇 BurnedInAnnotation=YES、RecognizableVisualFeatures=YES、PDF、SR、图形标注、缩略图、曲线或叠加层时会拒绝归档,而不是把未处理内容标成已匿名。外发前仍需按实际模态和数据类型复核。
启用匿名时,原始接收暂存、失败文件和运行日志不会写入结果目录,而是保存在当前系统用户的应用状态目录:
- Windows:
%LOCALAPPDATA%\DcmGet\ - macOS:
~/Library/Application Support/DcmGet/ - Linux:
$XDG_STATE_HOME/dcmget/,未设置时为~/.local/state/dcmget/
假名映射密钥为上述目录中的 anonymization.key。同一密钥会让重试和后续批次保持稳定映射;丢失或删除密钥后,新生成的 Patient ID、检查号和 UID 将与以前不同。匿名写入采用“生成临时文件 → 校验 DICM 与 SOP UID → 发布结果 → 删除原始暂存”的顺序,处理失败不会把半成品计入下载结果。
任务主页可快速启用 PDI 并选择保存目录;设置页继续管理机构名称、离线阅片器等高级选项。启用后,每批下载归档完成会自动导出一个可整体复制到 U 盘的目录。此功能不生成 ISO,也不控制光驱或刻录机。默认输出到 DICOM 保存目录/PDI/DCMGET_PDI_日期时间;也可以选择独立输出位置。
典型目录结构如下:
DCMGET_PDI_20260716_120000/
├── DICOMDIR
├── INDEX.HTM # 目录说明与检查摘要,不承担 DICOM 解码
├── README.TXT
├── MANIFEST.SHA256
├── DICOM/ # 原始 DICOM 的 PDI 短路径副本
├── VIEWER/ # 程序运行数据、64 位校验脚本与离线中文阅片资源,请勿删除
└── OPEN_VIEWER.* # 当前平台的本地阅片启动器
- 普通下载结果仍以
.dcm结尾;PDI 内部复制件使用符合 DICOM File ID 约束的无扩展名短路径,源文件不会被修改。 - 用户只需点击“打开已有 PDI 目录”选择根目录,或在当前任务中点击“打开影像”,不需要选择 JSON、
DICOMDIR或逐个影像文件。DcmGet 始终使用安装包内经过校验的 OHIF 与本地服务,只从所选 PDI 读取 DICOM 和内部索引;即使是旧版 PDI,也不会加载 U 盘中的网页脚本。预先生成的隐藏索引可避免每次启动重新扫描大量 DICOM。 - 离线阅片器直接读取 PDI 内的原始 DICOM,不生成 JPG 或 PNG 预览副本,也不携带 Weasis。阅片界面默认使用中文,支持序列、窗宽窗位、测量和多帧查看能力。
- 现代浏览器不允许 OHIF 通过
file://自动枚举本机目录,因此请运行OPEN_VIEWER.exe(Windows 安装版导出的首选入口,也可用OPEN_VIEWER.bat)、OPEN_VIEWER.command(macOS)或OPEN_VIEWER.sh(Linux)。启动器以当前 PDI 根目录为唯一入口,只绑定127.0.0.1随机端口并打开本机浏览器;地址使用/viewer/directory/,不再显示dicomjson。macOS/Linux 启动脚本依赖目标电脑已安装 Python 3;Windows 成品导出的OPEN_VIEWER.exe不需要另装 Python。 - 阅片过程不联网:主程序使用自身内置阅片资源,便携启动器使用目录内副本;内部索引和 DICOM 影像始终来自当前 PDI,不使用外部 CDN、在线 DICOMweb 服务或远程账号。
- DcmGet 会等本地目录服务通过就绪检查后再打开浏览器;服务连续空闲约 4 小时才自动退出。再次点击“打开影像”可重新打开已经运行的页面。
- 为避免超大批次耗尽内存,离线阅片索引最多 100,000 帧且估算不超过 64 MiB;超限时仍保留有效的 DICOMDIR 和原始 DICOM,并提示按批次拆分后重试阅片器导出。
dcmmkdir先尝试严格 Profile;遇到目录字段、传输语法或编码不兼容时会使用兼容模式重试,并在README.TXT和界面中明确警告,不会宣称严格 Profile 合规。- PDF、SR、视频或当前 OHIF 不支持显示的对象仍会保留为原始 DICOM 并列入报告。
DICOMDIR失败则不会发布半成品目录。 - PDI 使用本批次实际归档文件,不会扫描并混入目标目录中的历史检查。PDI 失败不改变下载状态、不重新下载,也不额外消耗试用次数。
- 可按介质容量生成
DCMGET_PDI_SET_日期时间。每个VOLUME_###都是包含独立DICOMDIR、清单和阅片入口的完整介质目录;同一 Study 永远不跨卷,超过单卷容量的 Study 会独占一卷并明确告警。容量设为0时不分卷。 - 将 PDI 复制到 U 盘或其他介质后,使用“运维工具 → 验证已复制 PDI”核对 SHA-256 清单、
DICOMDIR内部引用和离线阅片资源。验证结果不等于临床诊断适用性或匿名合规证明;验收报告会写到介质目录之外,不改动已复制内容。 - 未匿名的 DICOM 可能包含患者隐私。外发前应启用合适的匿名方案并完成复核。
保留两个直接入口:
python DICOM_download_ui.py
python DICOM_download_ui.py --profile 2
python DICOM_download_script.py --config config.json
python DICOM_download_script.py --config config.json --accessions 检查清单.xlsx --accession-column 检查号
python DICOM_download_script.py --task-state <独立任务恢复点路径>
# 运维命令互斥,不启动下载任务
python DICOM_download_script.py --config config.json --health-check
python DICOM_download_script.py --config config.json --support-bundle DcmGet-support.zip
python DICOM_download_script.py --backup-profiles DcmGet-profiles.zip
python DICOM_download_script.py --restore-profiles DcmGet-profiles.zip
python DICOM_download_script.py --verify-pdi E:\DCMGET_PDI_20260718_120000Web 入口使用持久 Profile:未指定 --profile 时自动取得空闲或待恢复 Profile;指定 --profile N 时只使用对应 Profile,若它已被另一个进程占用则打开现有 Web 地址后退出新进程。--config PATH 只作为首次创建该 Profile 时的配置初始化模板,不会把 Profile 的长期身份改到模板所在目录;旧版本曾在自定义配置目录创建的 Profile 会在首次打开时自动迁移到规范目录,并保留原文件。命令行继续作为单任务前台客户端运行,并保留显式 --task-state 恢复参数;--task-id 仅用于尚未迁移的 2.8 旧任务目录。默认旧任务目录迁移到实例 Profile 后,命令行会拒绝再次打开它,避免与 Web 后台重复执行同一批任务。所有入口共享整机 30 次试用计数和注册码,不再要求日期口令。可用 --license PATH 指定注册码文件;--accept-download-failures 可接受当前下载结果并继续 PDI,--discard-checkpoint 可明确放弃所选恢复点。
--health-check 输出运行时、DCMTK、目录、磁盘、端口、进程和 PACS TCP 可达性检查;这是网络可达性检查,不是 DICOM C-ECHO。--support-bundle 生成默认脱敏的诊断 ZIP。Profile 备份包含配置和可选显示名,不包含注册码、试用计数、匿名密钥、下载结果或任务恢复点;恢复前会自动创建现有配置与显示名快照,旧版 v1 备份仍可兼容恢复。管理中心的“Profile 工作台”可复制、重命名、删除安全空闲 Profile,并启动 Profile 或创建固定 --profile N 快捷方式;复制时会自动分配未占用的接收端口和 Web 端口,接收 AE 与 PACS Move Destination 映射仍必须由用户确认。CLI 和 Web 控制台的 PDI 验证都可直接选择单卷目录,或选择含 VOLUME_SET.json 的分卷集根目录并严格按清单逐卷验证。
命令行退出码:
0:下载及启用的 PDI 导出全部完成1:配置、预检或接收器启动失败2:存在下载失败、部分成功,或启用的 PDI 导出失败/部分成功130:用户取消
首次部署会从 config.example.json 创建 config.json。Web 入口传入的 --config PATH 仅用于初始化尚未创建的 Profile,之后始终读写该 Profile 的规范配置目录;旧版自定义目录中的 Profile 会自动迁移且不覆盖原文件。主要字段:
| 字段 | 说明 |
|---|---|
dcmtk_bin_dir |
DCMTK 的 bin 目录;留空时自动查找 |
access_numbers_file_path |
检查号 TXT、CSV 或 XLSX 路径;多列表格需明确选择检查号列 |
dicom_destination_folder |
DICOM 保存目录 |
pacs_server_ip / pacs_server_port |
PACS 地址与端口 |
calling_ae_title |
movescu 本机调用 AE |
pacs_ae_title |
PACS AE |
storage_ae_title / storage_port |
C-STORE 接收 AE 与端口 |
web_bind_address |
Web 监听地址;局域网版默认 0.0.0.0 |
web_port |
Web 控制台 HTTP 端口;首个 Profile 默认 8787,不同 Profile 必须不同,且不能使用管理中心保留的 8786 |
web_open_browser |
后台启动后是否自动打开本机界面;Windows 使用 WebView2,macOS/Linux 源码运行使用系统浏览器 |
web_session_timeout_minutes |
自动安全会话的空闲超时时间 |
max_concurrent_moves |
仅为兼容 2.8.x 配置保留,自 2.9.0 起不再生效;每个实例始终顺序执行 C-MOVE |
directory_template |
目录组合模板;支持 PatientID、AccessionNumber、StudyInstanceUID |
anonymization_enabled |
是否在最终归档前启用 DICOM 元数据处理,默认 false |
anonymization_profile |
basic、research 或 strict;默认 research |
pdi_export_enabled |
是否在每批下载结束后自动生成 PDI 便携目录,升级配置默认 false |
pdi_institution_name |
PDI 首页和说明中的机构名称;启用 PDI 时必填 |
pdi_output_folder |
PDI 输出根目录;留空时使用 DICOM 保存目录/PDI |
pdi_include_ohif_viewer |
是否加入中文 OHIF 和本地只读 HTTP 启动器;默认 true |
pdi_volume_size_bytes |
PDI 单卷目标容量;0 表示不分卷,同一 Study 不会被拆分 |
minimum_free_space_bytes |
下载前和任务中必须保留的磁盘空间;默认 2 GiB,0 关闭保护 |
auto_retry_attempts |
单个检查号瞬时故障的自动重试次数;默认 2 |
auto_retry_backoff_seconds |
自动重试的基础退避秒数;默认 3 |
circuit_breaker_failures |
连续瞬时失败到达该数量时暂停后续队列;默认 5 |
max_log_file_size_bytes |
单个日志文件最大字节数 |
旧版配置会自动迁移到 v8,且不覆盖现有设置;原 PACS、AE、目录、PDI 机构名称和输出位置会保留。v8 为 Web 监听、本机界面自动打开和会话超时补入默认值;v7 的 PDI 分卷、磁盘保护、重试和熔断语义保持不变。max_concurrent_moves 字段仅为读取旧配置兼容而保留,自 2.9.0 起不显示该设置,也不会据此并发 C-MOVE。首次创建 i1 时会从现有配置初始化;后续新 Profile 以首个 Profile 配置为模板,并自动选择可用接收端口和 Web 端口,再由用户确认接收 AE、目标目录以及 PACS Move Destination 映射。v5 的 OHIF 迁移语义保持不变:旧 JPEG 预览和 Weasis 选项均关闭时继续关闭,任一开启时启用 OHIF,迁移后不再保存旧字段。DCMTK 的查找顺序是:Profile 配置目录、.runtime/dcmtk 部署目录、旧版 dcmtk/bin、系统 PATH。
程序从启动最早阶段开始写入独立诊断日志。dcmget-diagnostics-<进程号>.log 记录启动、Python、Web 服务和后台线程异常,dcmget-crash-<进程号>.log 记录原生崩溃信息;不同进程不会争用同一个轮转日志文件。即使 Web 服务尚未就绪,也可以直接查看:
- Windows:
%LOCALAPPDATA%\DcmGet\logs\dcmget-diagnostics-<进程号>.log,安装版也可从开始菜单点击“DcmGet 诊断日志”。 - macOS:
~/Library/Application Support/DcmGet/logs/dcmget-diagnostics-<进程号>.log。 - Linux:
$XDG_STATE_HOME/dcmget/logs/dcmget-diagnostics-<进程号>.log,未设置时为~/.local/state/dcmget/logs/dcmget-diagnostics-<进程号>.log。
Profile Web 的“管理”页可打开该固定目录;启动失败时请提供对应时间和进程号的诊断、崩溃文件。非匿名任务的下载与接收日志写入影像目标目录下的 _DcmGetLogs,便于与结果一同交付;匿名任务日志始终位于 Profile 私有状态目录 iN/logs,不会泄露到结果目录。目标日志目录不可写时也会回退到该 Profile 私有目录。
每个实例创建带微秒级唯一名称的独立暂存子目录,先启动 storescp -aet <接收AE> -od <暂存目录> +xa <端口>,确认进程存活且端口就绪后,再顺序执行带连接与 DIMSE 超时的 movescu --no-port。当前检查号完成后读取本次新增 DICOM 的元数据,按该实例配置中的目标目录和目录模板归档并补充 .dcm 后缀;关键元数据缺失时使用安全占位值,匿名失败文件会保留并写入日志。无法可靠归属的文件进入隔离目录,绝不猜测写入其他任务。
每个任务还会写入独立的 WAL SQLite 验收台账。在可选匿名化前,程序记录返回对象的 Accession Number、Study/Series/SOP UID、字节数和元数据错误,将归属标记为“核对通过”、“内容不一致”或“无法核验”。这是下载后的审计证据,不是接收前置条件:核验告警不会丢弃已收到的有效 DICOM,也不会擅自把传输成功改成失败。任务结束后会在目标目录的 _DcmGetReports/task-<任务编号前8位>/ 输出默认脱敏的 HTML、CSV 和 JSON 验收报告。
DCMTK storescp 在 Windows、macOS 和 Linux 上接收 C-STORE association,并按原始传输语法写入,不需要为下载而解压像素。若 PACS 已返回待处理响应、对象无法归属或接收连接中止但没有有效落盘文件,任务会标记为失败而不是“无数据”,并可通过“重试失败项”再次执行。
开始前和执行期间都会检查磁盘可用空间,低于保留阈值时安全停止后续下载。只有被识别为瞬时故障的检查号才会按配置自动退避重试;连续失败达到熔断阈值时会暂停后续队列,避免在 PACS、网络或接收端持续异常时快速刷完整批失败。
速度按暂存目录中实际收到的原始 DICOM 字节计算;任务进行中每 0.5 秒采样一次,单个检查号结束后显示其平均传输速度。匿名转换和最终归档耗时不会计入网络下载速度。
- “接收端口已占用”:关闭占用程序或在设置中更换端口,并同步 PACS 的 Move Destination。
- 修改默认接收端口
6666后:Windows 安装版和默认源码部署的storescp.exe程序规则会自动兼容所有自定义端口;如果在设置中改用另一套 DCMTK 路径,需要为那一份storescp.exe单独放行域/专用网络入站连接。 - “C-MOVE 完成但未收到文件”:检查 PACS 中接收 AE、客户端 IP、接收端口及防火墙映射。
- DCMTK 启动失败:下载需要同一套
storescp和movescu,PDI 还需要dcmmkdir、dcmdump。Windows 3.6.1 成品已包含这四个程序及所需 DLL、字符集和许可证数据,不包含dcmj2pnm、dcmdjpeg等未使用工具;源码部署或自定义路径请选择同时包含这四个程序的 DCMTK 3.7.0bin目录。 - Windows 本机界面启动失败:DcmGet 只使用 Edge Chromium WebView,不回退到旧版 IE 内核或默认浏览器。请安装或修复 Microsoft Edge WebView2 Runtime 后重新打开 DcmGet;后台服务和已经运行的下载不受窗口启动失败影响。
- Windows 缺少 DLL:安装部署脚本提示的 Microsoft Visual C++ x64 Runtime。
python -m pip install -r requirements-dev.txt
python -m pytest
python DICOM_download_ui.py --web-self-test --config build/web-self-test.json
python scripts/build_deploy_bundle.pybuild_deploy_bundle.py 仅保留为维护者本地生成源码归档的工具;CI 与发布工作流不会上传源码、macOS 或 Linux 安装包,当前发布物只有 Windows x64 三种形式。
自动测试覆盖免密码会话/CSRF、Web API、离线静态资源、浏览器断开后的后台任务生命周期和任务恢复。真实 DICOM 集成测试覆盖每 Profile 独立 storescp、顺序 movescu、多进程端口隔离、压缩传输语法原样接收和跨进程安全归档,并检查输出文件的 DICM 标识。
项目原仓库未提供独立开源许可证,因此本部署包没有擅自选择许可证。详见 LICENSE 和 THIRD_PARTY_NOTICES.md。