System.Diagnostics.Process

时间:2017-03-05 01:20:44

标签: .net process file-permissions ghostscript

我正在使用Ghostcript(GS)来修改Windows 10系统上的PDF文件,不过我觉得我有一个普遍的问题,与GS没有关系。

当我从命令提示符运行GS时,它工作正常。当我尝试从C#代码创建的进程中执行相同的操作时,我收到错误。我怀疑问题是由我的进程没有对创建输出文件的文件夹的写访问权引起的。

我的问题是:

  1. 如何在目标文件夹上打开权限?我需要向谁或我提供写访问权限?我尝试使用资源管理器向“所有人”授予“完全控制权”,但这没有帮助。

  2. 我可以以某种方式为我的进程赋予“超级”能力,以便它可以在任何地方写入吗? (我不担心安全问题)。

  3. 这是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 个答案:

答案 0 :(得分:0)

以下是一些有效的代码。这是一项正在进行中的工作,无论如何我都不是程序员,所以请原谅丑陋/愚蠢。但它使用itextSharp而不是Ghostscript进行裁剪。我仍然想知道我调用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;
      }

   }
}