GhostscriptRasterizer 对象 Returns 0 作为 PageCount 值

GhostscriptRasterizer Objects Returns 0 as PageCount value

            txtStatus.Text = "";
            if (!File.Exists(txtOpenLocation.Text))
            {
                txtStatus.Text = "File Not Found";
                return;
            }

            txtStatus.Text = "File Found";



            const string DLL_32BITS = "gsdll32.dll";
            const string DLL_64BITS = "gsdll64.dll";

            //select DLL based on arch
            string NomeGhostscriptDLL;
            if (Environment.Is64BitProcess)
            {
                NomeGhostscriptDLL = DLL_64BITS;
            }
            else
            {
                NomeGhostscriptDLL = DLL_32BITS;
            }




            GhostscriptVersionInfo gvi = new GhostscriptVersionInfo(NomeGhostscriptDLL);
            var rasterizer = new GhostscriptRasterizer();
            try
            {              
                rasterizer.Open(txtOpenLocation.Text, gvi, true);

                Console.WriteLine(rasterizer.PageCount); //This line always prints 0
            } catch(Exception er)
            {
                txtStatus.AppendText("\r\nUnable to Load the File: "+ er.ToString());
                return;
            }

我用谷歌搜索了它,但没有找到解决方案,也没有关于 rasterizer.Open() 函数的有用文档。

无论我加载哪个 pdf 文件,Console.WriteLine(rasterizer.PageCount); 总是打印 0

txtStatus是UI中的多行文本框。 txtOpenLocation 是 UI 中的另一个文本框,用户不可编辑,其值由 OpenFileDialog.

设置

我正在使用 Visual Studio 2019 社区版。

另一个我觉得值得一提的观察——对于我机器上的每个 pdf 文件,当我尝试使用 Adob​​e Acrobat DC 或 Foxit Reader 打开任何 pdf 文件时,首先 reader 崩溃,变成 'not responsive' 大约 10 到 15 秒,然后打开 pdf 文件。

我昨天遇到了同样的问题,我从这里 https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs926/gs926aw32.exe 下载了 9.26 版,并且有效!

我认为这是 ghostscript 9.27 版本的一个错误。

我怀疑这根本不是错误(我当然不相信它是 Ghostscript 错误),但它可能是行为上的改变。由于报告的安全漏洞,Ghostscript 开发人员已经删除了对 many non-standard PostScript 扩展(Ghostscript 独有)的访问权限。最近访问用于处理 PDF 文件的词典已被保护。

我怀疑 Ghostscript.NET(不是由 Ghostscript 开发人员维护)正在使用一个或多个 non-standard 扩展来完成检索页数的工作。在不知道当前正在使用什么的情况下,我当然不能确定。

如果 Ghostscript.NET 的开发者想联系我们并确认这是问题所在,那么我们可以讨论当前支持的检索 PDF 文件页数的方法。

使用 Ghostscript.NET 向我发送一个项目完全没有帮助,因为我对此一无所知。我也不是 C# 或 .NET 开发人员,因此代码对我来说可能毫无意义。

Ghostscript returns 关于后台通道的大量信息,stdout and/or stderr。这些可以重定向到 application-defined 数据接收器。我想 Ghostscript.NET 会给你一些检索这些信息的方法,如果你打算进行任何涉及 Ghostscript 的真正开发,那么我强烈建议你了解如何获取这些信息。

当您说 'no error is thrown from Ghostscript' 时,我认为您可能混淆了 Ghostscript 和 Ghostscript.NET。没有看到来自 Ghostscript 的反向通道,我不知道如何判断 Ghostscript 是否正在生成错误。

注意,如果您打算分发您的应用程序,则必须遵守 AGPL 第 3 版(适用于 Ghostscript 的许可证)的条款,这包括发送许可证副本,以及一些通知用户的方式他们在哪里可以获得原件。

与 OP 和这个问题的主要答案一样,我昨天也遇到了这个确切的问题。

我只想补充一点,建议的 ghostscript (9.26) 版本无法正常工作。它抱怨说我应该使用 64 位版本。

对于那些需要它的人,它在这里:https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs926/gs926aw64.exe

我不得不猜测 URL。我很惊讶找到旧版本是多么困难。

我对 GhostScript 或 PostScript 不是很熟悉,但是,我已经在 GhostScript.NET 代码中找到了问题,该代码使用 gsapi 来执行函数。正在执行但在 gs 上失败的函数位于 GhostScript.NET 项目的文件 GhostscriptViewerPdfFormatHandler.cs 中。

根据 Oswaldo Cotes Solano 的建议,使用 gs9.26 进行进一步测试,并使用测试脚本将结果与 gs9.52 进行比较,我发现 GS_PDF_ProcSet 导致不可恢复的错误,退出gs 9.52 上的代码 1。

这会导致在使用 gs9.52 时失败 API,但是,自 gs9.27 以来,它是设计来增加安全性的。虽然不建议将 -dNOSAFER 用于生产就绪的应用程序,但它可以帮助我们。

在 gs9.26 中有效的预期执行和结果示例应类似于:

gswin32c.exe -q -dNOSAFER -sPDFname=c:/pdfs/test.pdf c:/pdfs/pdfpagecount.ps
Executing:
/GSNETViewer_PDFpage {
(%GSNET_VIEWER_PDF_PAGE: ) print dup == flush
pdfgetpage /Page exch store
Page /MediaBox pget
{ (%GSNET_VIEWER_PDF_MEDIA: ) print == flush  }
if
Page /CropBox pget
{ (%GSNET_VIEWER_PDF_CROP: ) print == flush }
if
Page /Rotate pget not { 0 } if
(%GSNET_VIEWER_PDF_ROTATE: ) print == flush
} def
Executing:
/Page null def
/Page# 0 def
/PDFSave null def
/DSCPageCount 0 def
Executing:
GS_PDF_ProcSet begin
pdfdict begin
Executing: (C:/pdfs/Output.pdf) (r) file runpdfbegin
Executing: /FirstPage where { pop FirstPage } { 1 } ifelse
Executing: /LastPage where { pop LastPage } { pdfpagecount } ifelse
Executing: flush (%GSNET_VIEWER_PDF_PAGES: ) print exch =only ( ) print =only (
) print flush
%GSNET_VIEWER_PDF_PAGES: 1 1
Executing: process_trailer_attrs

Executing: 1 GSNETViewer_PDFpage
%GSNET_VIEWER_PDF_PAGE: 1
%GSNET_VIEWER_PDF_MEDIA: [0.0 0.0 612.0 792.0]
%GSNET_VIEWER_PDF_CROP: [0.0 0.0 612.0 792.0]
%GSNET_VIEWER_PDF_ROTATE: 0
Executing: Page pdfshowpage_init pdfshowpage_finish
Loading NimbusSans-Regular font from %rom%Resource/Font/NimbusSans-Regular... 4124032 2548352 5183568 3818848 3 done.
showpage, press <return> to continue

虽然 运行 2.52 带有 -dNOSAFER 并且还在 CLI 中添加了 -dNOSAFER 参数以避免文件访问错误,并且 GhostScript.NET 源允许相同的功能。虽然 -dNOSAFER 选项不是理想的选择并且可能存在漏洞,但为了测试而不深入,我已经使用这种方法进行测试。

C:\Program Files\gs\-\bin>gswin64c.exe -q -dNOSAFER -sPDFname=test.pdf c:/pdfs/pdfpagecount.ps
Error: /undefined in GS_PDF_ProcSet
Operand stack:
Execution stack:
%interp_exit   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push   --nostringval--   --nostringval--   --nostringval--   false   1   %stopped_push   1990   1   3   %oparray_pop   1989   1   3   %oparray_pop   1977   1   3   %oparray_pop   1833   1   3   %oparray_pop   --nostringval--   %errorexec_pop   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push   --nostringval--
Dictionary stack:
--dict:738/1123(ro)(G)--   --dict:0/20(G)--   --dict:84/200(L)--
Current allocation mode is local
Current file position is 992
GPL Ghostscript 9.52: Unrecoverable error, exit code 1

最终对源的 3 个位置进行了微小的更改,得到了 9.52 的有效解决方案。我将对我们的更改进行 pull-request 并在发出拉取请求后更新社区,否则,您可以直接拉取我们的分支。

此问题已在 GhostScript.NET

的最新版本 v.1.2.2 中修复

解决方法是停止使用 pdfdict 和 GS_PDF_ProcSet 如果版本超过 9.26,因为出于安全原因 Ghostscript 团队将这两个函数设为私有。

我遇到了同样的问题。我使用的是 c# (.NET) Ghostscript.NET(版本 1.2.3)。问题是 PDF 文件名。如果它有括号 ) 或 (,则会出现该问题。 我不得不重命名 PDF 文件以转义这些字符。

using Ghostscript.NET.Rasterizer;
var strFilePath = "C:\PdfFile(.pdf";

using (var rasterizer = new GhostscriptRasterizer())
{
    rasterizer.Open(strFilePath);
    var strPageCount = rasterizer.PageCount; //return 0
}

var pattern = "[^A-Za-z0-9 .-]+";
var regEx = new Regex(pattern);
strFilePath = regEx.Replace(strFilePath, "");

using (var rasterizer = new GhostscriptRasterizer())
{
    rasterizer.Open(strFilePath);
    var strPageCount1 = rasterizer.PageCount; //return number of pages
}