Search code examples
c#printingsystem.printingprintqueue

PrintSystemJobInfo.JobStream deletes the job from the printer once the stream is closed and before printing anything


I'm trying to print a file in C# using System.Printing and I can get the Queue, create the PrintTicket to set some specific properties and also create a printing job to write the contents of the file using a StreamReader. The thing is that it stays stuck in "Spooling" state until the print job's JobStream is closed, then changes for a little moment to "Printing" and before the printer starts doing anything, the job is deleted immediately, so nothing is actually printed.

After hours looking at the documentation I tried different ways too, like PrintQueueStream (stays stuck in spooling state). Here's a code snipet of what I'm doing (without the PrintTicket part to keep it simple)

 if (!File.Exists(filePath))
 {
      Console.WriteLine("File doesn't exist");
      return false;
 }

 //string fileName = Path.GetFileName(filePath);
            
 try
 {
       PrintSystemJobInfo printJob = queue.AddJob();
       using (StreamReader streamReader = new StreamReader(filePath))
       {
            Stream jobStream = printJob.JobStream;
            Byte[] byteBuffer = UnicodeEncoding.Unicode.GetBytes(streamReader.ReadToEnd());
            jobStream.Write(byteBuffer, 0, byteBuffer.Length);
            jobStream.Close();

         }

  }
  catch (PrintJobException e)
  {
        Console.WriteLine(e.Message);
        Console.WriteLine(e.StackTrace);
        return false;
  }

I know I could use PrintDocument to print that file, however it has to be printed with photographic quality (not just High) in photographic paper (basically glossy) and without margins, and these are things that can't be done that way (or at least I couldn't find how to do it). Also it has to be without showing any kind of dialog, so that's why I'm trying to do it this way. Actually I'm trying even with a text file or writting text to the Byte[] buffer directly as shown in the documentation and the result is the same. I know there's an option to create a PrintJob with an XPS file instead of adding a JobStream, but I couldn't find how can I get that file to print the picture file with the specific paper properties (from the PrintTicket) and without showing any dialog to the user, or if it can be done.

I've been looking even apparently similar questions here but their solutions (if they have it) doesn't work for my particular case.

Any help would be appreciated.


Solution

  • For those interested, I've found a solution doing it in a total different way. Basically using irfanview (first you have to download it) since it not allows only to print by command line but also keeps the previous/saved print configuration. So everything needed is to start the process like "C:\Program Files\IrfanView\i_view64.exe" %file_path% /print

    So basically in C# I coded something like this, tried it with both my printer and another photographic printer and works like a charm.

      ProcessStartInfo cmdStartInfo = new ProcessStartInfo();
      cmdStartInfo.FileName = @"C:\Windows\System32\cmd.exe";
      cmdStartInfo.RedirectStandardOutput = true;
      cmdStartInfo.RedirectStandardError = true;
      cmdStartInfo.RedirectStandardInput = true;
      cmdStartInfo.UseShellExecute = false;
      cmdStartInfo.CreateNoWindow = true;
    
      Process cmdProcess = new Process();
      cmdProcess.StartInfo = cmdStartInfo;
      cmdProcess.EnableRaisingEvents = true;
      cmdProcess.Start();
          
      cmdProcess.StandardInput.WriteLine("\"C:\\Program Files\\IrfanView\\i_view64.exe\" " + file_path + " /print"); 
    
      cmdProcess.StandardInput.WriteLine("exit");                  
      cmdProcess.WaitForExit();