You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#编写的Windows服务调用Ghostscript DLL在部分机器挂起求助

Ghostscript.NET在Windows服务中跨机器挂起的排查方向

问题背景

我有一个基于Ghostscript.NET调用Ghostscript DLL的Windows服务,本地机器运行及打印均正常,但部署到其他物理机和虚拟机时出现挂起现象。Ghostscript本体及使用它的测试控制台应用在所有机器上都能正常运行和打印,且已确认本地与其他机器的权限、服务属性、打印机属性等配置一致。

相关代码

服务端调用代码

var dllPath = $"{Path.GetDirectoryName(AppContext.BaseDirectory)}{Path.DirectorySeparatorChar}gsdll64.dll";

_logger.LogInformation("DLL path - {DllPath}", dllPath);

using var processor = new GhostscriptProcessor(new GhostscriptVersionInfo(dllPath));

processor.Completed += ProcessorOnCompleted;
processor.Error += ProcessorOnError;
processor.Started += ProcessorOnStart;
processor.Processing += ProcessorOnProcessing;

var switches = new List<string>
{
    "-empty",
    "-q",
    "-dQUIET",
    "-dSAFER",
    "-dBATCH",
    "-dNOPAUSE",
    "-dNOPROMPT",
    "-dNoCancel",
    $"-dDEVICEWIDTHPOINTS={width}",
    $"-dDEVICEHEIGHTPOINTS={height}",
    "-dPDFFitPage",
    "-dNumCopies=1",
    "-sDEVICE=mswinpr2",
    "-sOutputFile=%printer%" + printerName,
    pdfFileName
};

try
{
    *// hangs here*
    processor.StartProcessing(switches.ToArray(), null /*new GsIoHandler(_logger)*/);
...

Ghostscript.NET内部挂起点

[UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet=CharSet.Ansi)]
public delegate int gsapi_init_with_args(IntPtr instance, Int32 argc, string[] argv);

...
*// hangs here*
int rc_init = _gs.gsapi_init_with_args(instance, args.Length, args);
...

可能的问题原因

  • 会话隔离限制:Windows服务默认运行在会话0,而mswinpr2打印设备依赖的部分打印机驱动组件仅在用户会话(如会话1及以上)中正常工作。控制台程序运行在用户会话,能访问这些组件,但服务在会话0中调用时会因等待用户态资源而挂起。
  • 依赖文件缺失:仅复制了gsdll64.dll,但缺少Ghostscript运行必需的附属文件(如字体库、配置文件gs_init.ps等)。本地机器因安装过完整Ghostscript环境包含这些文件,其他机器缺少后导致DLL初始化卡住。
  • 隐性权限差异:服务身份(如Local System)在不同机器上对打印机端口、临时目录的实际访问权限不同。例如某些机器的打印机端口需要特定用户权限,或Ghostscript生成临时文件的目录写入权限不足,导致进程挂起等待权限。
  • DLL加载路径问题:服务的工作目录并非gsdll64.dll所在目录,导致加载DLL时无法找到其依赖的系统组件或Ghostscript附属文件,进而初始化失败并挂起。
  • 打印机驱动兼容性:不同机器的打印机驱动版本或类型存在差异,部分驱动与mswinpr2设备交互时出现死锁。控制台程序可能因打印子系统的用户态处理逻辑不同而规避了该问题。
  • 线程模型冲突:Windows服务默认配置为单线程公寓(STA),而Ghostscript.NET调用非托管DLL时需要多线程公寓(MTA)环境,线程模型不匹配导致调用挂起。控制台程序默认使用MTA,因此无此问题。

内容的提问来源于stack exchange,提问作者Val Mat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 21:07:19