我正在编写一个 Windows 服务来扫描一组目录以查找新的 PDF 文件,并使用 Ghostscript.NET 将它们转换为 TIFF。当我将代码作为普通程序编译并运行时,它运行良好,但是当我将相同的代码用作服务时,输出 TIFF 永远不会出现。我已将目标目录设置为允许为每个人编写,并且原始 PDF 已按预期删除,因此对于“本地系统”用户而言,这不应该是权限问题。审核访问失败和成功的目录仅显示成功列表。
有一个功能可以读取 PDF 的颜色填充,以确定它是彩色文档还是彩色扫描的黑白文档。该部分有效,因此访问和阅读 PDF 没有问题。
我还尝试从 Ghostscript 开关中删除“-q”,但没有报告任何错误,“-dDEBUG”输出了太多垃圾,我不知道它在说什么——但没有任何东西被标记为错误。
public static void ConvertPDF(string file, GSvalues gsVals)
{
gsProc = new Ghostscript.NET.Processor.GhostscriptProcessor();
System.Collections.Generic.List<string> switches = new System.Collections.Generic.List<string>();
switches.Add("-empty"); // GS.NET ignores the first switch
switches.Add("-r" + gsVals.Resolution); // dpi
switches.Add("-dDownScaleFactor=" + gsVals.ScaleFactor); // Scale the image back down
switches.Add("-sCompression=lzw"); // Compression
switches.Add("-dNumRenderingThreads=" + Environment.ProcessorCount);
switches.Add("-c \"30000000 setvmthreshold\"");
switches.Add("-dNOGC");
string device;
if (_checkPdf(file, gsVals.InkColorLevels, gsVals))
{
gsVals.WriteLog("Color PDF");
device = "-sDEVICE=tiffscaled24"; // 24bit Color TIFF
}
else
{
gsVals.WriteLog("Grayscale PDF");
device = "-sDEVICE=tiffgray"; // grayscale TIFF
}
switches.Add(device);
// Strip the filename out of the full path to the file
string filename = System.IO.Path.GetFileNameWithoutExtension(file);
// Set the output file tag
string oFileName = _setFileName(oPath + "\\" + filename.Trim(), GSvalues.Extension);
string oFileTag = "-sOutputFile=" + oFileName;
switches.Add(oFileTag);
switches.Add(file);
// Process the PDF file
try
{
string s = string.Empty;
foreach (string sw in switches) s += sw + ' ';
gsVals.DebugLog("Switches:\n\t" + s);
gsProc.StartProcessing(switches.ToArray(), new GsStdio());
while (gsProc.IsRunning) System.Threading.Thread.Sleep(1000);
}
catch (Exception e)
{
gsVals.WriteLog("Exception caught: " + e.Message);
Console.Read();
}
gsVals.DebugLog("Archiving PDF");
try
{
System.IO.File.Move(file, _setFileName(gsVals.ArchiveDir + "\\" + filename, ".pdf"));
}
catch (Exception e)
{
gsVals.WriteLog("Error moving PDF: " + e.Message);
}
}
private static string _setFileName(string path, string tifExt)
{
if (System.IO.File.Exists(path + tifExt)) return _setFileName(path, 1, tifExt);
else return path + tifExt;
}
private static string _setFileName(string path, int ctr, string tifExt)
{
// Test the proposed altered filename. It it exists, move to the next iteration
if(System.IO.File.Exists(path + '(' + ctr.ToString() + ')' + tifExt)) return _setFileName(path, ++ctr, tifExt);
else return path + '(' + ctr.ToString() + ')' + tifExt;
}
这是生成的开关的示例输出(从输出日志中提取):
Switches: -empty -r220 -dDownScaleFactor=1 -sCompression=lzw -dNumRenderingThreads=4 -c "30000000 setvmthreshold" -dNOGC -sDEVICE=tiffscaled24 -sOutputFile=\\[servername]\amb_ops_scanning$\Test.tiff \\[servername]\amb_ops_scanning$\Test.pdf
设置在 XML 文件中读取并存储在 GSVals 类中。该类还处理写入系统日志以进行输出,或写入普通程序版本中的文本文件。GSSTDIO 是一个用于处理 GS 输入和输出的类,它只是将所有输出重定向到与 GSVals 相同的日志。程序版本和服务版本之间的唯一代码更改是服务处理代码,输出从文本文件更改为系统日志。Ghostscript 处理没有任何改变。
为了可移植性,它被编译为 x86,但正在 x64 上运行。已安装 GS 9.15,包括 x86 和 x64 版本。GS.NET 是通过 NuGet 安装到 VS 2012 中的版本 4.0.30319。ILMerge 2.13.0307 用于将 GS.NET dll 打包到 exe 中,也是为了便于移植。这些东西在正常的 EXE 和 Windows 服务版本之间都没有改变,正如我所说的,正常的 EXE 没有任何问题。