2017-03-05 21 views
0

Ghostcript(GS)を使用してWindows 10システムでPDFファイルを修正していますが、一般的な問題はあると思いますが、実際にはGSには関係しません。System.Diagnostics.Processの書き込みアクセス

GSをコマンドプロンプトから実行すると正常に動作します。 C#コードで作成されたプロセスから同じことをしようとすると、エラーが発生します。私は、問題は、私のプロセスが出力ファイルが作成されているフォルダへの書き込みアクセス権を持っていないことが原因であると思われる。

私の質問は以下のとおりです。

  1. はどのようにして、ターゲットフォルダのアクセス許可を開くのですか?書き込み権限を与えるには、誰に、または私に何を必要としますか?私はエクスプローラを使って "Everyone"に "フルコントロール"を許可しようとしましたが、それは助けになりませんでした。

  2. 私は自分のプロセスに何とか "スーパー"な力を与えて、どこにでも書くことができますか? (私はセキュリティ上の問題を心配していません)。ここで

はGSコマンド(作品)です:

gswin64c.exe -sDEVICE=pdfwrite –q -o outFile.pdf -c "[/CropBox [72 72 144 216] /PAGES pdfmark" -f inFile.pdf 

そして、ここでは(動作しない)、この同じコマンドを実行しようとしている私のC#のコードです:

using System; 
using System.Diagnostics; 

namespace pdfcropper 
{ 
    class Program 
    { 
     static void Main() 
     { 
     string gspath = @"D:\ciao\Documents\Visual Studio 2013\Projects\itextsharp\gswin64c.exe"; 

     ProcessStartInfo psi= new ProcessStartInfo(gspath); 
     psi.UseShellExecute = false; 
     psi.WorkingDirectory = @"D:\ciao\Documents\Visual Studio 2013\Projects\itextsharp"; 
     psi.Arguments = @" -sDEVICE=pdfwrite -dBATCH –q -o outFile.pdf -c ""[/CropBox [72 72 144 216] /PAGES pdfmark"" -f inFile.pdf"; 

     Process myProcess = new Process(); 
     myProcess.StartInfo = psi; 
     myProcess.Start(); 

     myProcess.Close(); 
     } 
    } 
} 

私が取得エラーメッセージは次のとおりです。

**** Unable to open the initial device, quitting. 
Unrecoverable error: undefinedfilename in setpagedevice 

これはかなりわかりにくいですが、出力ファイル(outFile.pdf)の作成に関連していると思われます。

+1

'outFile.pdf'の代わりに完全なpathspecを指定してください。すでに 'outFile.pdf'を開いている場合、GSがファイルを開いて書き込みできないため、コマンドは失敗します。おそらく入力ファイルも同様に指定する必要があります。私は問題が現在の作業ディレクトリが正しくないと思われると推測します。 – KenS

+0

@KenS:ご協力いただきありがとうございます。私は、異なる作業ディレクトリと完全なパス名で多数のバリエーションを試しました。私は最終的にitextsharp APIを呼び出すことにしましたが、それはうまくいきました。しかし、私はGSの使用に何が問題なのかを理解したいと思います。とにかくGSを呼び出す必要があります。 – bubba

+1

それを推測するのは難しいです。最初のことは、-qを削除することです。デバッグ時にメッセージを抑制したくはありません。私は、Ghostscriptプロセスがその親プロセス(つまりあなたのプロセス)の特権を継承することを期待していますが、C#を書いていないので、私は確信が持てません。おそらく、Processクラスのドキュメントにその情報があります。このエラーはPostScript環境から返され、指定されたデバイスを開くことができなかったことを意味します。 PostScriptはそれ以上の情報を与えることはできません。子のGhostscriptプロセスをデバッグできる場合は、Cコードでどこを停止するかを教えてください。 – KenS

答えて

0

ここにいくつかのコードがあります。これは進行中の作業ですが、私はプログラマーではありませんので、醜さ/欲望を許してください。しかし、GhostscriptではなくitextSharpを使ってトリミングを行います。私はまだGhostscriptと呼んでいる方法に何が問題なのかを知りたいです。

using System; 
using System.Diagnostics; 
using System.IO; 
using iTextSharp.text.pdf; 
using iTextSharp.text; 

namespace pdfcropper 
{ 
    class Program 
    { 
     public static void Main(string[] args) 
     { 
     string[] config = System.IO.File.ReadAllLines(@"D:\public\pdfcropperConfig.txt"); 

     float d = float.Parse(config[0]);   // border size (n points) 
     int show = int.Parse(config[1]);   // >0 to view after cropping; =0 to not 
     string gspath = config[2];     // path of Ghostscript executable 

     string inFile = args[0]; 

     float[] b = GetBounds(gspath, inFile); 
     PdfRectangle rect = new PdfRectangle(b[0] - d, b[1] - d, b[2] + d, b[3] + d); 

     PdfReader reader = new PdfReader(inFile); 
     PdfDictionary pageDict = reader.GetPageN(1); 
     pageDict.Put(PdfName.CROPBOX, rect); 

     string tempPath = System.IO.Path.GetTempPath(); 
     string tempOutFile = Path.Combine(tempPath, "tempPDF.pdf"); 
     FileStream fs = new FileStream(tempOutFile, FileMode.Create, FileAccess.Write); 

     // The "stamper" actually does the copying, when closed 
     PdfStamper stamper = new PdfStamper(reader, fs); 
     stamper.Close(); 

     reader.Close(); 

     // Replace original file by cropped one 
     File.Copy(tempOutFile, inFile, true); 
     File.Delete(tempOutFile); 

     // Start Acrobat reader to view the output file 
     if (show > 0) Process.Start(inFile); 
     } 

     private static float[] GetBounds(string gspath, string infilePath) 
     { 
     //string gspath = @"C:\Program Files\gs\gs9.15\bin\gswin64c.exe"; 

     ProcessStartInfo psi = new ProcessStartInfo(); 
     psi.FileName = gspath; 
     psi.UseShellExecute = false; 
     psi.RedirectStandardError = true; 
     psi.RedirectStandardOutput = true; 
     psi.WorkingDirectory = System.IO.Path.GetDirectoryName(infilePath); 
     psi.Arguments = @" -sDEVICE=bbox -dBATCH -dNOPAUSE -q " + infilePath; 

     Process proc = new Process(); 
     proc.StartInfo = psi; 
     proc.Start(); 

     StreamReader myStreamReader = proc.StandardError; 
     string output = myStreamReader.ReadToEnd(); 
     char sep = ' '; 
     string output2 = output.Replace('\n', sep); 
     string[] words = output2.Split(sep); 

     float[] bounds = new float[4]; 

     bounds[0] = float.Parse(words[6]); // xmin 
     bounds[1] = float.Parse(words[7]); // ymin 
     bounds[2] = float.Parse(words[8]); // xmax 
     bounds[3] = float.Parse(words[9]); // ymax 

     proc.Close(); 

     return bounds; 
     } 

    } 
} 
関連する問題