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

huangapple go评论71阅读模式
英文:

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 snippet 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;
 }

 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 writing 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.

英文:

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.

答案1

得分: 0

以下是您提供的代码的中文翻译:

我不是专家,但这对我来说在尝试在使用.NET Framework 4.8的控制台应用程序上使用文件流打印文档时起作用。

using System;
using System.IO;
using System.Printing;

namespace ConsoleApp18
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string filePath = @"c:\temp\file.pdf";
            if (!File.Exists(filePath))
            {
                Console.WriteLine("文件不存在");
            }

            try
            {
                PrintQueue queue = new PrintQueue(new PrintServer(), "打印机");
                PrintSystemJobInfo printJob = queue.AddJob();

                using (Stream jobStream = printJob.JobStream)
                {
                    byte[] fileContents = File.ReadAllBytes(filePath);
                    jobStream.Write(fileContents, 0, fileContents.Length);
                    jobStream.Close();
                }
                queue.Commit();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(e.StackTrace);
            }
        }
    }
}

请注意,我只提供了代码的翻译部分,没有包括问题或其他内容。

英文:

I am not an expert but this worked for me trying to print a document using a file stream on a console app using net framework 4.8.

using System;
using System.IO;
using System.Printing;

namespace ConsoleApp18
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string filePath = @"c:\\temp\file.pdf";
            if (!File.Exists(filePath))
            {
                Console.WriteLine("File doesn't exist");
            }

            try
            {
                PrintQueue queue = new PrintQueue(new PrintServer(), "Printer");
                PrintSystemJobInfo printJob = queue.AddJob();

                using (Stream jobStream = printJob.JobStream)
                {
                    byte[] fileContents = File.ReadAllBytes(filePath);
                    jobStream.Write(fileContents, 0, fileContents.Length);
                    jobStream.Close();
                }
                queue.Commit();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(e.StackTrace);
            }
        }
    }
}

答案2

得分: 0

对于那些感兴趣的人,我找到了一种完全不同的解决方案。基本上使用IrfanView(首先您必须下载它),因为它不仅允许通过命令行打印,还保留了先前/保存的打印配置。所以一切需要的就是启动像这样的过程:“C:\Program Files\IrfanView\i_view64.exe” %file_path% /print

所以基本上在C#中,我编写了类似这样的代码,用我的打印机和另一台照片打印机都试过,效果非常好。

  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();
英文:

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();

huangapple
  • 本文由 发表于 2023年5月11日 04:28:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76222324.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定