So, I am using Matthew Ephraim's GhostscriptSharp, which is a simple C# wrapper for the unmanaged Win32 Ghostscript DLL in my ASP.Net MVC project. Some background:
What I am attempting to do is have a user upload a PDF, and then convert that document into an image that I can then save off into whatever directory I choose (as well as do some other OOP to tie that new image to my site).
I decided to use Mr. Ephraim's wrapper class (GhostscriptSharp) because it was simple enough to use, and it gives me relatively clean access to the DLL's API.
To test it, I created a dummy C# console application to make sure I could load the DLL, access it, hand it a PDF file on the local disk and then have it write a JPG to the same local disk. After a few learning experiences, I had success. I would hand it C:\INPUT.pdf, it would hand me C:\OUTPUT.jpg.
However, after integrating the GhostScriptSharp code that I had in the console application into my ASP.NET MVC project to the point of where I was calling the DLL with P/invoke, Ghostscript is returning with the int/error code -100
, which is a fatal error (is called E_Fatal
in the GhostScript source code). I get the same result with both the file that is uploaded through the HTML form, and if I hand it the exact same hard-coded paths that I used in my working console application.
For reference, the lines which the exception is thrown are 93-97 in GhostScriptSharp.cs (which is in the CallApi
function):
int result = InitAPI(gsInstancePtr, args.Length, args);
if (result < 0) {
throw new ExternalException("Ghostscript conversion error", result);
}
Obviously the exception is thrown because result
is -100
.
When InitAPI is called, the instance ptr is a valid int
(though I don't know if the instance of GS is correct or not), args has a length of 20 (is a string[]
) of valid GhostScript options (including the correctly-escaped paths to my input & output files).
Long story short, what am I doing wrong? The error code -100
seems like a catch-all because there is no documentation that states what could possibly be going wrong here.
Any help is much appreciated, thank you in advance.
GhostScript is installed, but IrfanView can't seem to find it. I think it might have something to do with the fact that there are two program files directories, one for 64-bit and one for 32-bit. Since IrfanView is 32-bit, it's looking in the 32-bit program files directory for GhostScript.
The command line option ' -sDEVICE= device ' selects which output device Ghostscript should use. If this option isn't given the default device (usually a display device) is used.
Ghostscript tends to expect files to conform to the standard. For example, even though valid PDF files must begin with %PDF, Acrobat will scan the first 1000 bytes or so for this string, and ignore any preceding garbage. In the past, Ghostscript's policy has been to simply fail with an error message when confronted with these files.
How Ghostscript finds files. When looking for initialization files (gs_*.ps, pdf_*.ps), font files, the Fontmap file, files named on the command line, and resource files, Ghostscript first tests whether the file name specifies an absolute path.
The -100 error is a generic "fatal error" in GhostScript.
A few things to check:
1) Permissions (al operations require file access)
2) Scope, you want to add the GS bin folder to the PATH variables
3) Consider not calling GhostScript directly from asp.net, GS can be very CPU intensive, rather process files in a separate service
I have also created a wrapper, send me an email (address on profile) and I will send it you. It allows one to pass in the GS bin folder which helps.
So, ended up being an ID10T error that was derailing me here in this specific instance.
In Matthew Ephraim's GhostscriptSharp code, he uses a couple of enums to define the options set forth for Ghostscript, and two in particular were the GhostscriptDevices
and GhostscriptPageSizes
enums. Problem is, the way they're written Resharper (Jetbrains Visual Studio plugin) has default rules for naming Enum members. Not thinking, I fixed all of these definitions to please Resharper not realizing that these are passed directly to Ghostscript, so instead of getting a7
for -sPAPERSIZE
GS was getting A7
, and for -sDEVICE
it was getting Jpeg
instead of jpeg
.
For the time being permissions weren't a problem on my end, but only because I run the Cassini web dev test server in Visual Studio.
Thanks to @MarkRedman and @tvanfosson for their helpful suggestions!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With