7
            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;
            }

I have googled on it, but got no solution, and no helpful documentation about the rasterizer.Open() function.

The Console.WriteLine(rasterizer.PageCount); always prints 0, regardless which pdf file I load.

txtStatusis a multiline TextBox in UI. txtOpenLocation is another TextBox in UI, non-editable by user, and its value is set by a OpenFileDialog.

I am using Visual Studio 2019 Community Edition.

Another observation I feel worth mentioning— for every pdf file on my machine, when I try to open any pdf file with either Adobe Acrobat DC or Foxit Reader, first the reader crashes, becomes 'not responsive' for about 10 to 15 seconds and then it opens the pdf file.

  • You haven't said what version of Ghostscript you are using, and you haven't provided the back channel output (stderr and stdout), my guess is that Ghostscript is throwing an error, and the only way to tell will be to look at what its trying to tell you. – KenS May 19 '19 at 08:15
  • Ghostscript Version is 9.27 . `gsdll32.dll` and `gsdll64.dll` are collected from the installation directory of Ghostscript apps. No error is thrown from Ghostscript. – Muhammad Rasel Parvej May 19 '19 at 08:27
  • And about `stderr`, I do not about it much. I will get back after knowing about it. – Muhammad Rasel Parvej May 19 '19 at 08:45
  • 1
    I downloaded `ghostscript.net.1.2.1.nupkg` from [here](https://www.nuget.org/packages/Ghostscript.NET/) . Then extracted it to get Ghostscript.NET.dll . – Muhammad Rasel Parvej May 19 '19 at 08:59
  • I am totally new in C# and .NET . I may be wrong, still I am expressing what I think. I believe, this is a bug in Ghostscript. I can send you my whole project if you want. It's a small project, won't take you much time to go through it once. (I see, you work in Artifex.) – Muhammad Rasel Parvej May 19 '19 at 10:46
  • See my answer... – KenS May 19 '19 at 15:25
  • 1
    It's a known issue in the GhostScript.net library when using 9.27 or newer: https://github.com/jhabjan/Ghostscript.NET/issues/62 – Aharon Ohayon Jan 16 '20 at 21:03

6 Answers6

20

I had the same problem yesterday, I downloaded version 9.26 from here https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs926/gs926aw32.exe, and works!

I think this is a bug of ghostscript 9.27 release.

  • 2
    This helped me. And you just helped me complete my first C#/.NET app. This was the only problem I am suffering from for 2 days. Thank you so much, brother. And as @KenS has stated in his answer, this might not be a Ghostscript bug. It's probably a problem of Ghostscript.NET, or a changed behavior defined by Ghostscript.NET. – Muhammad Rasel Parvej May 20 '19 at 06:05
  • Again thank you to all for your help. So much time spent to achieve something so simple. – Euan Gordon Aug 28 '19 at 13:05
  • @Oswaldo Cotes Solano, In my case, rollback to older versions of Ghostscript does not help. I tried with versions 26 and 25. Moreover, with version 27 I always have PageCount = 0, and if the version is lower than 27 then it gives an error "Ghostscript native library could not be found." – Vasiliy Aug 29 '19 at 10:14
  • For those who use 64bits, download this link: https://github-production-release-asset-2e65be.s3.amazonaws.com/50461376/3f68ff80-1f19-11e9-8526-c014004a72e7?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20200116%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20200116T203254Z&X-Amz-Expires=300&X-Amz-Signature=14a593b0b22488031c58705866738d2e4e8f659d56a35da01221ece462805f1a&X-Amz-SignedHeaders=host&actor_id=59134422&response-content-disposition=attachment%3B%20filename%3Dgs926aw64.exe&response-content-type=application%2Foctet-stream – Aharon Ohayon Jan 16 '20 at 20:54
4

This isn't a bug at all, I suspect, (I certainly do not believe its a Ghostscript bug) but its probably a change in behaviour. Due to reported security vulnerabilities the Ghostscript developers have been removing access to many non-standard PostScript extensions (unique to Ghostscript). Most recently access to the dictionary for processing PDF files has been secured.

My suspicion is that Ghostscript.NET (which is not maintained by the Ghostscript developers) is using one or more non-standard extensions to do the work of retrieving the count of pages. Without knowing what exactly is being used currently I can't be sure of course.

If the developer of Ghostscript.NET would like to contact us and confirm this is the problem then we can discuss the currently supported method for retrieving the count of pages in a PDF file.

It won't help at all to send me a project using Ghostscript.NET, since I don't know anything about it. I'm also not a C# or .NET developer, so the code would likely be meaningless to me.

Ghostscript returns considerable information on the back channel, stdout and/or stderr. These can be redirected to an application-defined data sink. I imagine that Ghostscript.NET will give you some means to retrieve these and if you plan to do any real development involving Ghostscript then I would very strongly reccomend that you find out how to get this information.

When you say 'no error is thrown from Ghostscript' I think you may be confusing Ghostscript and Ghostscript.NET. Without seeing the back channel from Ghostscript I don't see how you can tell if Ghostscript is generating an error.

NB if you plan to distribute your application you must abide by the terms of the AGPL version 3 (which is the license applying to Ghostscript), and that includes shipping a copy of the license, and some means for informing users where they can get the original.

KenS
  • 30,202
  • 3
  • 34
  • 51
3

As with the OP and the primary answer to this question, I too encountered this exact issue just yesterday.

I just want to add that for me the suggested version of ghostscript (9.26) wasn't working. It complained that I should be using a 64 bit version.

For those who need that, it's here: https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/gs926/gs926aw64.exe

I had to just guess at the URL. I'm amazed at how difficult it has been to find older versions.

Stuart Aitken
  • 949
  • 1
  • 13
  • 30
  • 1
    Try the official download site at https://www.ghostscript.com/download/gsdnld.html and from there the link at the bottom of the page takes you to older versions https://github.com/ArtifexSoftware/ghostpdl-downloads/releases That takes you all the way back to 9.18 which is 3 years old. As I've mentioned in my answer, someone needs to contact the author of the Ghostscript.NET wrapper, it needs updating. I do not recommend using old versions, they have security vulnerabilities. – KenS May 21 '19 at 19:09
  • 1
    Also, our git repository (http://git.ghostscript.com/?p=ghostpdl.git;a=tags) has tags for the sources to build versions back to version 6.0, 19 years ago. – KenS May 21 '19 at 19:13
  • @KenS I looked all over the ghostscript site and the related github pages but found nothing. Now that you've shown me, it is indeed obvious and I don't know how I missed it. My eyes were clearly not working properly on that day! Thanks – Stuart Aitken May 22 '19 at 02:27
  • 1
    It is a subtle link, perhaps we should make it more obvious, but to be honest, we gerneally suggest that people use the latest version. I understand that won't work for you without changes to Ghostscript.NET though. – KenS May 22 '19 at 07:27
  • the Ghostscript ecoysystem is a weird one for .NET folk in a small biz that can't afford to buy the Accusoft or Aspose packages for doing OCR.. and so we google around and are hoping to figure out a way to rasterize PDFs.. and hoping we can use a NuGet to neatly integrate a package into our existing project. Right now, the 9.26 version wrapped in Ghostscript.NET is saving our bacon on this intranet business app service I'm creating, but it sure wasn't easy arriving at this stackoverflow post. – bkwdesign Oct 28 '20 at 19:31
1

This issue has been fixed in the latest release v.1.2.2 of GhostScript.NET

The fix was to stop using pdfdict and GS_PDF_ProcSet if the version was over 9.26 as these two functions were made private by the Ghostscript team for security reasons.

  • Good to know. Would you maybe have a link for those of us who want a bit more detail? – Mouse On Mars Feb 05 '21 at 20:32
  • Sure [Link to Issue 62 in GhostScript.Net](https://github.com/jhabjan/Ghostscript.NET/issues/62#issuecomment-772917226) New to stack overflow as a poster and not sure what I am allowed to do with such low rep :) – Jeff Powell Feb 06 '21 at 21:27
0

I am not very familiar with GhostScript or PostScript, however, I have traced down the issue within the GhostScript.NET code, which uses the gsapi to execute functions. The function that is being executed and failing on gs is within file GhostscriptViewerPdfFormatHandler.cs on the GhostScript.NET Project.

Upon further testing through using both a gs9.26 as recommended by Oswaldo Cotes Solano and comparing the results with gs9.52 using a test script, I have found that GS_PDF_ProcSet is causing a Unrecoverable error, exit code 1 on gs 9.52.

This leads to failure while using the gs9.52 API, however, it is by design since gs9.27 to add security. While -dNOSAFER is not recommended for production ready applications, it will get us by.

An example of the intended execution and result that works in gs9.26 should be similar to:

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

While running 2.52 with -dNOSAFER and also adding the -dNOSAFER argument to CLI to avoid the file access error, and the GhostScript.NET source to allow for the same functionality. Although the -dNOSAFER option is not the ideal choice and may have vulnerabilities, to test without diving further in, I've used this method for testing.

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

Ultimately making a minor change 3 locations of the source has resulted in a working solution with 9.52. I'll do a pull-request with our changes and update the community when a pull request has been issued, otherwise, you can make a pull directly to our fork.

Stephan
  • 332
  • 5
  • 13
0

I've had the same problem. I was using c# (.NET) Ghostscript.NET (version 1.2.3). Problem was PDF file name. If it had parenthesis ) or (, then that problem occurs. I had to rename PDF file in order to escape those characters.

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
}
Marius D
  • 1
  • 3