title: Ghostscript.NET - no output file when run as Windows service
body: <p>I'm writing a Windows Service to scan a set of directories for new PDF files and convert them to TIFF with Ghostscript.NET. When I'd compiled and ran the code as a normal program it functioned perfectly, but when I used the same code as a Service the output TIFF never appears. I've set the destination directory to allow writing for Everyone, and the original PDF is being removed as it's supposed to, so it shouldn't be a permissions issue for the "Local System" user. Auditing the directory for access Failures and Successes just shows a list of Successes.</p>
  
  <p>There is a function that reads the color population of the PDF to determine if it's a color document, or B&amp;W scanned as color. That part works, so there isn't an issue accessing and reading the PDF.</p>
  
  <p>I've also tried removing '-q' from the Ghostscript switches and I don't have any errors reported, and "-dDEBUG" outputs so much garbage I don't know what it's saying - but nothing is tagged as an error.</p>
  
  <pre><code>public static void ConvertPDF(string file, GSvalues gsVals)
  {
  
      gsProc = new Ghostscript.NET.Processor.GhostscriptProcessor();
      System.Collections.Generic.List&lt;string&gt; switches = new System.Collections.Generic.List&lt;string&gt;();
      switches.Add("-empty"); // GS.NET ignores the first switch
      switches.Add("-r" + gsVals.Resolution); // dpi
      switches.Add("-dDownScaleFactor=" + gsVals.ScaleFactor); // Scale the image back down
      switches.Add("-sCompression=lzw"); // Compression
      switches.Add("-dNumRenderingThreads=" + Environment.ProcessorCount);
      switches.Add("-c \"30000000 setvmthreshold\"");
      switches.Add("-dNOGC");
  
      string device;
      if (_checkPdf(file, gsVals.InkColorLevels, gsVals))
      {
          gsVals.WriteLog("Color PDF");
          device = "-sDEVICE=tiffscaled24"; // 24bit Color TIFF
      }
      else
      {
          gsVals.WriteLog("Grayscale PDF");
          device = "-sDEVICE=tiffgray"; // grayscale TIFF
      }    
      switches.Add(device);
  
      // Strip the filename out of the full path to the file
      string filename = System.IO.Path.GetFileNameWithoutExtension(file);
      // Set the output file tag
      string oFileName = _setFileName(oPath + "\\" + filename.Trim(), GSvalues.Extension);
      string oFileTag = "-sOutputFile=" + oFileName;
      switches.Add(oFileTag);
      switches.Add(file);
  
      // Process the PDF file
      try
      {
          string s = string.Empty;
          foreach (string sw in switches) s += sw + ' ';
              gsVals.DebugLog("Switches:\n\t" + s);
  
          gsProc.StartProcessing(switches.ToArray(), new GsStdio());
          while (gsProc.IsRunning) System.Threading.Thread.Sleep(1000);
      }
      catch (Exception e)
      {
           gsVals.WriteLog("Exception caught: " + e.Message);
           Console.Read();
      }
  
      gsVals.DebugLog("Archiving PDF");
      try
      {
          System.IO.File.Move(file, _setFileName(gsVals.ArchiveDir + "\\" + filename, ".pdf"));
      }
      catch (Exception e)
      {
          gsVals.WriteLog("Error moving PDF: " + e.Message);
      }
  }
  
  
  private static string _setFileName(string path, string tifExt)
      {
          if (System.IO.File.Exists(path + tifExt)) return _setFileName(path, 1, tifExt);
          else return path + tifExt;
      }
  
  private static string _setFileName(string path, int ctr, string tifExt)
      {
          // Test the proposed altered filename. It it exists, move to the next iteration
          if(System.IO.File.Exists(path + '(' + ctr.ToString() + ')' + tifExt)) return _setFileName(path, ++ctr, tifExt);
          else return path + '(' + ctr.ToString() + ')' + tifExt;
      }
  </code></pre>
  
  <p>This is a sample output of the generated switches (pulled from the output log):</p>
  
  <pre><code>Switches: -empty -r220 -dDownScaleFactor=1 -sCompression=lzw -dNumRenderingThreads=4 -c "30000000 setvmthreshold" -dNOGC -sDEVICE=tiffscaled24 -sOutputFile=\\[servername]\amb_ops_scanning$\Test.tiff \\[servername]\amb_ops_scanning$\Test.pdf 
  </code></pre>
  
  <p>Settings are read in an XML file and stored in a class, GSVals. The class also handles writing to the System log for output, or to a text file in the normal Program version. GSSTDIO is a class for handling GS input and output, which just redirects all the output to the same logs as GSVals. The only code changes between the Program version and the Service version is the Service handling code, and the output is changed from a text file to the system logs. Nothing about the Ghostscript processing was changed.</p>
  
  <p>This is being compiled as x86 for portability, but is being run on x64. GS 9.15 is installed, both x86 and x64 versions. GS.NET is version 4.0.30319 installed via NuGet into VS 2012. ILMerge 2.13.0307 is being used to package the GS.NET dll into the exe, also for portability. None of these things changed between the normal EXE and the Windows Service versions, and as I said the normal EXE works without any issues.</p>