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 文件,当我尝试使用 Adobe 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
}
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 文件,当我尝试使用 Adobe 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
}