2017-12-14 74 views
0

私はGhostscript.Netを使用してPostScript to PDF Converterを構築しようとしています。 GetArgsが返すArgsは、私が通常gswin32c.exeを呼び出すのに使うもので、正常に動作します。gsapi_init_with_argsが作成されました:-100

しかし、私がプロセスを呼び出すたびに、「gsapi_init_with_args 'を呼び出したときにエラーが発生しました:-100」とエラーが表示されます。そのエラーをグーグルで調べても何も起きなかったので、私はここで尋ねるかもしれないと思った。

Ghostscript.netで直接.dllを呼び出す際に考慮すべき異なる引数がありますか?それとも私は別の場所でミスをしたのですか?

public class PdfConverter 
{ 
    #region Private Fields 
    private List<GhostscriptVersionInfo> _Versions = GhostscriptVersionInfo.GetInstalledVersions(GhostscriptLicense.GPL | GhostscriptLicense.AFPL | GhostscriptLicense.Artifex); 
    #endregion 


    #region Private Properties 
    private GhostscriptVersionInfo Version { get; set; } 
    #endregion 


    #region Construction 
    public PdfConverter() 
    { 
     Version = GhostscriptVersionInfo.GetLastInstalledVersion(); 
    } 
    #endregion 


    #region Public Members 
    public bool ConvertToPdf(DirectoryInfo dir) 
    { 
     var d = dir; 
     if(!d.Exists) 
      return false; 

     var postScriptFiles = d.GetFiles("*.ps"); 
     var pdfFiles  = postScriptFiles.Select(psf => new FileInfo(Path.ChangeExtension(psf.FullName, ".pdf"))); 

     foreach(var file in postScriptFiles) { 
      //ThreadPool.QueueUserWorkItem(new WaitCallback((o) => { 
       Process(file, new FileInfo(Path.ChangeExtension(file.FullName, ".pdf"))); 
      //})); 
     } 

     pdfFiles.ForEach(pdf => pdf?.Refresh()); 
     return pdfFiles.All(pdf => pdf.Exists); 
    } 
    #endregion 


    #region Private Helpers 
    private void Process(FileInfo inputFile, FileInfo outputFile) 
    { 
     Console.WriteLine($"Converting {inputFile} to {outputFile}"); 
     var proc = new GhostscriptProcessor(Version, true); 
     proc.Process(GetArgs(inputFile, outputFile).ToArray(), new ConsoleStdIO(true, true, true)); 
    } 


    private IEnumerable<string> GetArgs(FileInfo inputFile, FileInfo outputFile) 
    { 
     return new [] { 
      $"-q ", 
      $"-sDEVICE=pdfwrite", 
      $"-dSAFER", 
      $"-dNOPAUSE", 
      $"-dBATCH", 
      $"-sPAPERSIZE=a4", 
      $"-dEmbedAllFonts=true", 
      $"-dAutoRotatePages=/None", 
      $"-sOutputFile=\"{outputFile.FullName}\"", 
      $"-dCompatibilityLevel#1.4", 
      $"-c .setpdfwrite", 
      $"-f \"{inputFile.FullName}\"" 
     }; 
    } 
    #endregion 
} 

編集:

はここに私のクラスだ 私が言及するのを忘れてしまった:私は私自身のGhostsdcriptStdIOクラスをしなければならなかったことを実現するために。私はこのことを正しければ、私は完全にはわからないと認めます。それは例外なしでインスタンス化され、StdOut(...)getをオーバーライドしますが、出力は期待通りにコンソールに書き込まれます。 override void StdError(...)getも呼び出されます。また、駆除されてコンソールに書き込まれます。 エラーbtwの出力は:

"****" c:\ temp \ test.pdf "ファイルを開くことができませんでした。" "****初期デバイスを開くことができません。

はここに私のConsoleStdIOクラスです:

再び
public class ConsoleStdIO : Ghostscript.NET.GhostscriptStdIO 
{ 
    #region Construction 
    public ConsoleStdIO(bool handleStdIn, bool handleStdOut, bool handleStdError) : base(handleStdIn, handleStdOut, handleStdError) { } 
    #endregion 


    #region Overrides 
    public override void StdError(string error) 
    { 
     var foo = Encoding.Default.GetBytes(error); 
     var lenght = foo.Length; 

     using (var err = Console.OpenStandardError()) { 
      if(err.CanWrite) 
       err.Write(foo, 0, lenght); 
     } 
    } 

    public override void StdIn(out string input, int count) 
    { 
     byte[] bytes = new byte[0]; 
     using(var stdInput = Console.OpenStandardInput()) { 
      stdInput.Read(bytes, 0, count); 
     } 
     input = Encoding.Default.GetString(bytes); 
    } 

    public override void StdOut(string output) 
    { 
     var foo = Encoding.Default.GetBytes(output); 
     var lenght = foo.Length; 

     using (var err = Console.OpenStandardError()) { 
      if(err.CanWrite) 
       err.Write(foo, 0, lenght); 
     }   
    } 
    #endregion 
} 

:gswin32c.exeを使用して、まったく同じファイルと引数を使用して同じ操作を行うと、正常に動作します。 ハッピーハッキング

答えて

2

エラー-100はgs_error_Fatalです。これは「何か大惨事が起こった」という意味です。そのプログラムが正常に起動しなかったことを示し、理由を伝えることができません。バックチャネルにはさらに多くの情報が含まれている場合があります。

そして実際、バックチャネルが間違っているかを表示します:

****ファイルを開くことができませんでした「C:\一時\のtest.pdfという ****初期デバイスを開くことができません、終了。

Ghostscriptが(その出力ファイルを必要とするため)、それはpdfwrite装置を開くことができないので、操作を中止手段の出力ファイルを開くことができない。

の数があるかもしれませんGhostscriptが出力ファイルを開くことができない理由。私がやるべき最初のことは、トリム引数の数を減らす。

-q(quiet)問題をデバッグしようとしているときに取得できるすべての情報が必要です。

Ghostscriptが現在の作業ディレクトリと特定の「特別な」ディレクトリ以外のディレクトリにアクセスするのを防ぐため、少なくとも私は-dSAFERを削除します。 tempディレクトリへのアクセスを妨げる可能性があります。

EmbedAllFontsをデフォルトと同じ値に設定する必要はありません。

CompatibilityLevel(と=)スイッチの代わりに#を使用したことに注意してください。AutoRotatePagesを有効にしてください。

文字列「-c .setpdfwrite -f」は何年も無意味でしたが、人々は引き続き使用しています。最近では、処理の開始が遅くなっています。

最後に、文字列の処理がうまくいかない場合や、二重バックスラッシュを使用する場合は、スラッシュ( '/')文字をスラッシュ( '/')に変更してみてください。

また、c:\ test \ temp.pdfが存在しないこと、または存在しないことが読み取り専用でないか、別のアプリケーションですでに開いていることを確認する必要があります。

+0

をしかし、その間にfreenodeの上#chsarpでユーザーがGhostscript.NETのソースコードでのバグに私を指摘します。https:// github.com/jhabjan/Ghostscript.NET/blob/6c74b1e416dea215754c8679fcc1f3caf0b085c3/Ghostscript.NET/Processor/GhostscriptProcessor.cs#L282 システムのデフォルトではargsをエンコードしますが、UTF8である必要があります。とにかく、Ghostscript.NETのソースコードをダウンロードして変更しました。しかし、それは動作しませんでした。 そして、未定義のファイル名であるというエラーはあまり意味がありません。ファイルが存在し、私の一時フォルダは確かに特別なものではないので、私はそれを作成しました。 – Mathew

+0

最初のコメント:あなたが言ったようにすべてのスイッチを削除しましたが、次のエラーが表示されます:/ undefinedfilename in( "C:\\ temp \\ pdftest \\ temp1.ps") – Mathew

+0

3番目のコメント: ://pastebin.com/n9efzBRa – Mathew

0

私は問題を解決しました...
KenSのアドバイスを受けた後、私はGhostscript(Ghostscript.NETではなく)を実行してエラーを表示することができました。しかし、それは実際のPDFファイルを生成しませんでした。

KenSの答えでは問題は解決しませんでしたが、「less is more」と私のargs自体が正しかったことをIRCの担当者に話す時間があったので、にもかかわらず。 #csharpでここに
私の元GetArgs(...)

private IEnumerable<string> GetArgs(FileInfo inputFile, FileInfo outputFile) 
    { 
     return new [] { 
      $"-sDEVICE=pdfwrite", 
      $"-dNOPAUSE", 
      $"-dBATCH", 
      $"-sPAPERSIZE=a4", 
      @"-sFONTPATH=" + System.Environment.GetFolderPath(System.Environment.SpecialFolder.Fonts), 
      $"-sOutputFile={outputFile.FullName}", 
      $"{inputFile.FullName}", 
     }; 
    } 

誰かがCで、最初の引数は常に名前であることを、私に指摘:実際に私は次のように解決された何

コマンドのだから彼は最初の議論として(ダミーとして) "gs"を入れて試してみることを提案しました...そしてそれが私の問題を実際に解決しました。

だから、これは作業GetArgs(...)がどのように見えるかです:

private IEnumerable<string> GetArgs(FileInfo inputFile, FileInfo outputFile) 
    { 
     return new [] { 
      $"gs", 
      $"-sDEVICE=pdfwrite", 
      $"-dNOPAUSE", 
      $"-dBATCH", 
      $"-sPAPERSIZE=a4", 
      @"-sFONTPATH=" + System.Environment.GetFolderPath(System.Environment.SpecialFolder.Fonts), 
      $"-sOutputFile={outputFile.FullName}", 
      $"{inputFile.FullName}", 
     }; 
    } 
関連する問題