ArtifexSoftware / Ghostscript.NET

Ghostscript.NET - managed wrapper around the Ghostscript library (32-bit & 64-bit). Tested with Ghostscript versions < 10.
https://ghostscript.com
GNU Affero General Public License v3.0
405 stars 155 forks source link

gsapi_init_with_args returns -100 #127

Open stephanstapel opened 1 month ago

stephanstapel commented 1 month ago

Hello,

I am trying the code from this pull request: https://github.com/ArtifexSoftware/Ghostscript.NET/pull/126

which is basically a wrapper around Ghostscript.net, not adding additional behavior to the core of the library.

I am initializing Ghostscript here

https://github.com/ArtifexSoftware/Ghostscript.NET/blob/1e27dc0ae704023f321bfed61c1ca4973c8619f7/Ghostscript.NET/Processor/GhostscriptProcessor.cs#L334

with these parameters:

grafik

I have simplified all paths as good as possible, tried it with 32 bit and 64 bit Ghostscript (adopting compilation target as well). I have tried both gs9.56.1 and gs10.03.1. Unfortunately I have no idea what else I could try. As I guess it is hard to guess from a distance what the reason might be, is there any chance to get further insights on what might happen here?

Thanks a lot in advance!

hh-it-co commented 1 month ago

+1

jamie-lemon commented 1 month ago

Can you describe the exact error a bit more ?

stephanstapel commented 1 month ago

Hi @jamie-lemon ,

this is the setup that I am using: gsnet-error.zip

It is basically the code from the PR: https://github.com/ArtifexSoftware/Ghostscript.NET/pull/126

I have just added a bit to FacturXWriteSample.cs that was added here: https://github.com/ArtifexSoftware/Ghostscript.NET/blob/f1e9a4672a9b33646390732f6629c90642f6bce0/Ghostscript.NET.Samples/Samples/FacturXWriteSample.cs

 public void Start()
{

    Invoice i = (new Invoice()).setDueDate(DateTime.Now).setIssueDate(DateTime.Now).setDeliveryDate(DateTime.Now).setSender((new TradeParty("Test company", "teststr", "55232", "teststadt", "DE")).addTaxID("DE4711").addVATID("DE0815").setContact(new Contact("Hans Test", "+49123456789", "test@example.org")).addBankDetails(new BankDetails("DE12500105170648489890", "COBADEFXXX"))).setRecipient(new TradeParty("Franz Müller", "teststr.12", "55232", "Entenhausen", "DE")).setReferenceNumber("991-01484-64").setNumber("123").
            addItem(new Item(new Product("Testprodukt", "", "C62", new BigDecimal(19)), new BigDecimal("1.0"), new BigDecimal("1.0")));

    ZUGFeRD2PullProvider zf2p = new ZUGFeRD2PullProvider();
    zf2p.setProfile(Profiles.getByName("XRechnung"));
    zf2p.generateXML(i);
    System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();

    string outfilename = "xrechnung.xml";
    File.WriteAllBytes(outfilename, zf2p.getXML());

    PDFConverter converter = new PDFConverter(@"e:\in.pdf", @"e:\out.pdf");
    converter.EmbedXMLForZF(outfilename, "2.1");
    converter.ConvertToPDFA3(@"d:\gs\gs9.56.1\bin\gsdll64.dll");
}

Nothing else was changed, all files exist. The last line invokes ConvertToPDFA3() which was also added in the PR: https://github.com/ArtifexSoftware/Ghostscript.NET/blob/f1e9a4672a9b33646390732f6629c90642f6bce0/Ghostscript.NET/FacturX/PDFConverter.cs

It basically checks for file availability like

 if (!File.Exists(file_GSDLL_DLL))
{
    throw new Exception("Ghostscript DLL " + file_GSDLL_DLL + " bitte ins Verzeichnis " + Directory.GetCurrentDirectory() + " kopieren");

}
...

then compiles the command line parameters

List<string> switches = new List<string>();
// works : "C:\Program Files (x86)\gs\gs9.52\bin\gswin32c.exe" -dPDFA=1 -dNOOUTERSAVE -sProcessColorModel=DeviceRGB -sDEVICE=pdfwrite -o RG_10690-pdfa.pdf -dPDFACompatibilityPolicy=1 "C:\Program Files (x86)\gs\gs9.52\lib\PDFA_def.ps" RG_10690.pdf
// "C:\Program Files (x86)\gs\gs9.52\bin\gswin64c.exe" -dPDFA=1 -dNOOUTERSAVE -sProcessColorModel=DeviceRGB -sDEVICE=pdfwrite -o RG_10690-pdfa.pdf -dPDFACompatibilityPolicy=1 "C:\Program Files (x86)\gs\gs9.52\lib\PDFA_def.ps" RG_10690.pdf
switches.Add(""); // ' Der allererste Parameter wird mitunter ignoriert weil EXEs da ihren eigenen Namen bergeben bekommen
switches.Add("-P"); // Zugriff auf Ressourcen unterhalb des aktuellen Verzeichnisses erlauben
switches.Add("-dPDFA=3"
...

then it starts processing:

using (GhostscriptProcessor gsProcessor = new GhostscriptProcessor(gsL))
{
    VerboseMsgBoxOutput stdio = new VerboseMsgBoxOutput();
    // gsProcessor.StartProcessing(switches.ToArray(), stdio)
    gsProcessor.StartProcessing(switches.ToArray(), null/* TODO Change to default(_) if this is not a reference type */);

    // (erfolglose) Versuche, das Hngen zu vermeiden...
    gsProcessor.Dispose();
}

which is part of existing Ghostscript.net, nothing was changed here afaik, so you find everything here:

https://github.com/ArtifexSoftware/Ghostscript.NET/blob/f1e9a4672a9b33646390732f6629c90642f6bce0/Ghostscript.NET/Processor/GhostscriptProcessor.cs#L268

at this point:

https://github.com/ArtifexSoftware/Ghostscript.NET/blob/f1e9a4672a9b33646390732f6629c90642f6bce0/Ghostscript.NET/Processor/GhostscriptProcessor.cs#L334

the error is thrown. Parameters of the call are the ones already listed above:

grafik

Any thoughts?

jamie-lemon commented 1 month ago

@green0317 Will take a look into this and get back to you as he speaks .NET.

Only one thing I thought you could try is -dColorConversionStrategy=/DeviceRGB on line 459 of PDFConverter.cs ( I have no idea if this makes a difference, I was just reading https://ghostscript.com/blog/zugferd.html and noticed another way of defining the ColorConversionStrategy ) Obviously I am just clutching at straws here and there is no doubt a deeper reason.

The only other sanity check I have for you right now is to ask: "does it work before you added your bit to FacturXWriteSample.cs"?

Sorry I'm not much help here!

jamie-lemon commented 1 month ago

Other info regarding your -100 code. -100 is a "gs_error_Fatal" error code. It usually means the interpreter cannot initialise. Like the initialisation files can't be found, or the requested initial device is invalid/not found. It could also be too little memory, but that would be surprising. Normally, it would print something to stdout/stderr to give a hint at the problem.

CPlusPlus17 commented 1 month ago

Nothing related directly to the PR but I also getting this error on a new installation and minimal setup:

Running by hand:

 .\gswin64c.exe -dBATCH -dNOPAUSE -dSAFER -dNOPROMPT -sDEVICE=pdfwrite -sOutputFile="test.pdf" -f D:\19597f35-b144-4a98-b00c-3b05c7305418.ps
GPL Ghostscript 10.03.1 (2024-05-02)
Copyright (C) 2024 Artifex Software, Inc.  All rights reserved.
This software is supplied under the GNU AGPLv3 and comes with NO WARRANTY:
see the file COPYING for details.
Loading NimbusMonoPS-Regular font from %rom%Resource/Font/NimbusMonoPS-Regular... 4104992 2739049 1807376 524064 1 done.
%%[ ProductName: GPL Ghostscript ]%%
Loading NimbusSans-Regular font from %rom%Resource/Font/NimbusSans-Regular... 4245608 2931811 2467432 1128751 2 done.
Loading NimbusSans-Bold font from %rom%Resource/Font/NimbusSans-Bold... 4446824 3132694 2487632 1147805 2 done.
%%[Page: 1]%%
Loading StandardSymbolsPS font from %rom%Resource/Font/StandardSymbolsPS... 4574328 3257129 3060136 1627403 2 done.
%%[Page: 2]%%
%%[Page: 3]%%
%%[Page: 4]%%
%%[LastPage]%%

But with ghostscript.net:

Ghostscript Path: D:\Program Files\gs\gs10.03.1\bin\gsdll64.dll
Ghostscript Is64Bit: D:\Program Files\gs\gs10.03.1\bin;D:\Program Files\gs\gs10.03.1\lib;D:\Program Files\gs\gs10.03.1\fonts

PS FILE: D:\tmp\720d3408-837a-4669-9500-4a42e923d1b7\8453e4a5-ff28-4d91-960b-c72882897c0e.ps
An error occured when call to 'gsapi_init_with_args' is made: -100

Code:

GhostscriptProcessor gsproc = new GhostscriptProcessor();
                List<string> gsArgs = new List<string>
                    {
                        "gs",
                        "-dBATCH",
                        "-dNOPAUSE",
                        "-dQUIET",
                        "-dSAFER",
                        "-dNOPROMPT",
                        "-sDEVICE=pdfwrite",
                        String.Format("-sOutputFile=\"{0}\"", string.Join(@"\\", outputFilename.Split(new string[] { @"\" }, StringSplitOptions.None))),
                        @"-f",
                        postscriptFile
                    };
                gsproc.Process(gsArgs.ToArray());

I have zero indications what is not good, all files are there, accessible and the installation is good. Maybe a problem with gs10.03.1?

jamie-lemon commented 1 month ago

@CPlusPlus17 Thanks for this - this is very likely the underlying issue. I think this project has not been supported properly for GS 10+.

@stephanstapel Perhaps if you are willing you could install 9.56 and give it another spin, https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/tag/gs9560

Again, apologies, I am on a Mac so cannot try this .NET stuff out myself. However if we can identify the underlying issue at the very least I can update the README for this project with "doesn't operate with GS 10+" and then look into trying to get someone with knowledge to fix it up.

jhabjan commented 1 month ago

jh-568

The "input" paths doesn't look a same. Can you please make sure you are testing with exactly a same file?

jhabjan commented 1 month ago

@stephanstapel , can you try this: gsnet-error.rev1.zip

Just make sure you change this line and point it to your native gs dll path:

converter.ConvertToPDFA3(@"C:\Program Files\gs\gs9.56.1\bin\gsdll64.dll");

stephanstapel commented 1 month ago

@jhabjan ,

thanks a lot! It works now with version 9.x (which didn't work before). It doesn't yet work with version 10 though.

stephanstapel commented 1 month ago

@jamie-lemon , thanks a lot for taking care of this. I will now proceed and refactor the existing code.

jhabjan commented 1 month ago

@stephanstapel

There were 3 problems in FacturX part of the code.

icc file was not set as "Embedded resource"

jh-569

file_AdobeRGB1988_ICC was pointing to a wrong filename

jh-571

GetFileInfo was missing FacturX\ bit

jh-570

Cheers, Josip

CPlusPlus17 commented 1 month ago

jh-568

The "input" paths doesn't look a same. Can you please make sure you are testing with exactly a same file?

Ah sorry, I was testing with multiple files. But I can confirm, that every tested file works directly with gswin64c.exe but not with the .net library. Is there any chance to get more verbose output instead of -100? I'm compiled it with 4.8 and 4.8.1.

CPlusPlus17 commented 1 month ago

@CPlusPlus17 Thanks for this - this is very likely the underlying issue. I think this project has not been supported properly for GS 10+.

@stephanstapel Perhaps if you are willing you could install 9.56 and give it another spin, https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/tag/gs9560

Again, apologies, I am on a Mac so cannot try this .NET stuff out myself. However if we can identify the underlying issue at the very least I can update the README for this project with "doesn't operate with GS 10+" and then look into trying to get someone with knowledge to fix it up.

Sorry, I oversaw this answer. Thanks for the information. I'll try with GS 9.

Same error:

An error occured when call to 'gsapi_init_with_args' is made: -100

Command line works without problems.

CPlusPlus17 commented 1 month ago

Some more news, this time good news:

I got it working with with gs9 and gs10, I had a non debuggable environment and that caused some troubles to find the problem. I used an example from officeToPdf and they did some strange things with \. I now replaced this and set -sOutputFile=D:\tmp\test2.pdf instead of -sOutputFile="D:\\tmp\\test2.pdf". Sorry for the troubles, but I think some error handling and detailed messages about why the runtime can't be started should be provided. It was my bad to blindly trust the sample code from another project.