none
プリンタジョブの割り込み RRS feed

  • 質問

  • Visual studio で作成したプログラムでプリンタドライバ経由で印刷しています。

    プリンタジョブがまだ残っている時に(プリンタ印刷中)、新たにジョブを追加する

    際に、ジョブの先頭に割り込んで印刷することはできないのでしょうか?

    以上、宜しくお願いします。

    OS:Windows10 pro

    2020年12月14日 7:09

回答

  • 対象のプリンタを管理する権限があるなら、ジョブの優先度を高くしてみる

    namespace WpfApp14
    {
        using System;
        using System.Linq;
        using System.Windows;
    
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                System.Printing.PrintSystemJobInfo job=null;
                try
                {
                    var lserver = new System.Printing.LocalPrintServer();
                    var queue = lserver.DefaultPrintQueue;
    
                    job = queue.AddJob(DateTime.Now.ToString("HH:mm:ss"));//テストだけで印刷しないジョブ(終了すると消える)
                    Win32.Printer.SetPrinterJobPriority(job, System.Printing.PrintJobPriority.Minimum + 1);
                }
                catch (Exception ex)
                {
                    job?.Cancel();
                    MessageBox.Show(ex.Message);
                }
            }
        }
    }
    
    namespace Win32
    {
        using System;
        using System.Runtime.InteropServices;
        using System.Printing; //System.Printing参照
    
        public static class Printer
        {
            public static void SetPrinterJobPriority(System.Printing.PrintSystemJobInfo job, System.Printing.PrintJobPriority priority)
            {
                if (priority < System.Printing.PrintJobPriority.Minimum || System.Printing.PrintJobPriority.Maximum < priority)
                {
                    throw new ArgumentOutOfRangeException(nameof(priority));
                }
    
                PRINTER_DEFAULTS pd = new PRINTER_DEFAULTS();
                pd.DesiredAccess = PRINTER_DEFAULTS.PRINTER_ALL_ACCESS;
    
                IntPtr hPrinter;
                if (!OpenPrinter(job.HostingPrintQueue.Name, out hPrinter, pd))
                {
                    var ex = new System.ComponentModel.Win32Exception();
                    if (ex.NativeErrorCode == 5)
                    {
                        throw new ApplicationException("プリンタのジョブを操作する権限がありません", ex);
                    }
                    throw ex;
                }
    
                try
                {
                    int numberOfBytes = 0;
    
                    JOB_INFO_1 j1 = new JOB_INFO_1();
                    GetJob(hPrinter, job.JobIdentifier, 1, IntPtr.Zero, 0, out numberOfBytes);
                    if (System.Runtime.InteropServices.Marshal.GetLastWin32Error() != 122)
                    {
                        throw new System.ComponentModel.Win32Exception();
                    }
    
                    var pmem = System.Runtime.InteropServices.Marshal.AllocHGlobal(numberOfBytes);
                    try
                    {
                        if (!GetJob(hPrinter, job.JobIdentifier, 1, pmem, numberOfBytes, out numberOfBytes))
                        {
                            throw new System.ComponentModel.Win32Exception();
                        }
    
                        var job1 = System.Runtime.InteropServices.Marshal.PtrToStructure<JOB_INFO_1>(pmem);
                        job1.Priority = (uint)priority;
                        Marshal.StructureToPtr<JOB_INFO_1>(job1, pmem, true);
    
                        if (!SetJob(hPrinter, job.JobIdentifier, 1, pmem, 0))
                        {
                            throw new System.ComponentModel.Win32Exception();
                        }
                    }
                    finally
                    {
                        System.Runtime.InteropServices.Marshal.FreeHGlobal(pmem);
                    }
                }
                finally
                {
                    ClosePrinter(hPrinter);
                }
            }
    
            [System.Runtime.InteropServices.DllImport("winspool.drv", EntryPoint = "SetJobW", SetLastError = true)]
            private static extern bool SetJob(IntPtr hPrinter, int JobId, int Level, IntPtr pJob, int Command);
    
            [System.Runtime.InteropServices.DllImport("winspool.drv", EntryPoint = "GetJobW", SetLastError = true)]
            private static extern bool GetJob(IntPtr hPrinter, int JobId, int Level, IntPtr pJob, int cbBuf, out int pcbNeeded);
    
            [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
            private class JOB_INFO_1
            {
                public UInt32 JobId;
                public IntPtr pPrinterName;
                public IntPtr pMachineName;
                public IntPtr pUserName;
                public IntPtr pDocument;
                public IntPtr pDatatype;
                public IntPtr pStatus;
                public UInt32 Status;
                public UInt32 Priority;
                public UInt32 Position;
                public UInt32 TotalPages;
                public UInt32 PagesPrinted;
                public UInt64 Submitted1;
                public UInt64 Submitted2;
            }
    
            [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern bool OpenPrinter(string pPrinterName, out IntPtr phPrinter, [In] PRINTER_DEFAULTS pDefault);
    
            [DllImport("winspool.drv", SetLastError = true)]
            private static extern bool ClosePrinter(IntPtr hPrinter);
    
            [StructLayout(LayoutKind.Sequential)]
            private class PRINTER_DEFAULTS
            {
                public IntPtr pDatatype = IntPtr.Zero;
                public IntPtr pDevMode = IntPtr.Zero;
                public int DesiredAccess = PRINTER_ALL_ACCESS;
    
                public const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
                public const int PRINTER_ACCESS_ADMINISTER = 0x4;
                public const int PRINTER_ACCESS_USE = 0x8;
                public const int PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE);
            }
    
        }
    }

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2020年12月15日 10:35

すべての返信

  • 対象のプリンタを管理する権限があるなら、ジョブの優先度を高くしてみる

    namespace WpfApp14
    {
        using System;
        using System.Linq;
        using System.Windows;
    
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                System.Printing.PrintSystemJobInfo job=null;
                try
                {
                    var lserver = new System.Printing.LocalPrintServer();
                    var queue = lserver.DefaultPrintQueue;
    
                    job = queue.AddJob(DateTime.Now.ToString("HH:mm:ss"));//テストだけで印刷しないジョブ(終了すると消える)
                    Win32.Printer.SetPrinterJobPriority(job, System.Printing.PrintJobPriority.Minimum + 1);
                }
                catch (Exception ex)
                {
                    job?.Cancel();
                    MessageBox.Show(ex.Message);
                }
            }
        }
    }
    
    namespace Win32
    {
        using System;
        using System.Runtime.InteropServices;
        using System.Printing; //System.Printing参照
    
        public static class Printer
        {
            public static void SetPrinterJobPriority(System.Printing.PrintSystemJobInfo job, System.Printing.PrintJobPriority priority)
            {
                if (priority < System.Printing.PrintJobPriority.Minimum || System.Printing.PrintJobPriority.Maximum < priority)
                {
                    throw new ArgumentOutOfRangeException(nameof(priority));
                }
    
                PRINTER_DEFAULTS pd = new PRINTER_DEFAULTS();
                pd.DesiredAccess = PRINTER_DEFAULTS.PRINTER_ALL_ACCESS;
    
                IntPtr hPrinter;
                if (!OpenPrinter(job.HostingPrintQueue.Name, out hPrinter, pd))
                {
                    var ex = new System.ComponentModel.Win32Exception();
                    if (ex.NativeErrorCode == 5)
                    {
                        throw new ApplicationException("プリンタのジョブを操作する権限がありません", ex);
                    }
                    throw ex;
                }
    
                try
                {
                    int numberOfBytes = 0;
    
                    JOB_INFO_1 j1 = new JOB_INFO_1();
                    GetJob(hPrinter, job.JobIdentifier, 1, IntPtr.Zero, 0, out numberOfBytes);
                    if (System.Runtime.InteropServices.Marshal.GetLastWin32Error() != 122)
                    {
                        throw new System.ComponentModel.Win32Exception();
                    }
    
                    var pmem = System.Runtime.InteropServices.Marshal.AllocHGlobal(numberOfBytes);
                    try
                    {
                        if (!GetJob(hPrinter, job.JobIdentifier, 1, pmem, numberOfBytes, out numberOfBytes))
                        {
                            throw new System.ComponentModel.Win32Exception();
                        }
    
                        var job1 = System.Runtime.InteropServices.Marshal.PtrToStructure<JOB_INFO_1>(pmem);
                        job1.Priority = (uint)priority;
                        Marshal.StructureToPtr<JOB_INFO_1>(job1, pmem, true);
    
                        if (!SetJob(hPrinter, job.JobIdentifier, 1, pmem, 0))
                        {
                            throw new System.ComponentModel.Win32Exception();
                        }
                    }
                    finally
                    {
                        System.Runtime.InteropServices.Marshal.FreeHGlobal(pmem);
                    }
                }
                finally
                {
                    ClosePrinter(hPrinter);
                }
            }
    
            [System.Runtime.InteropServices.DllImport("winspool.drv", EntryPoint = "SetJobW", SetLastError = true)]
            private static extern bool SetJob(IntPtr hPrinter, int JobId, int Level, IntPtr pJob, int Command);
    
            [System.Runtime.InteropServices.DllImport("winspool.drv", EntryPoint = "GetJobW", SetLastError = true)]
            private static extern bool GetJob(IntPtr hPrinter, int JobId, int Level, IntPtr pJob, int cbBuf, out int pcbNeeded);
    
            [System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
            private class JOB_INFO_1
            {
                public UInt32 JobId;
                public IntPtr pPrinterName;
                public IntPtr pMachineName;
                public IntPtr pUserName;
                public IntPtr pDocument;
                public IntPtr pDatatype;
                public IntPtr pStatus;
                public UInt32 Status;
                public UInt32 Priority;
                public UInt32 Position;
                public UInt32 TotalPages;
                public UInt32 PagesPrinted;
                public UInt64 Submitted1;
                public UInt64 Submitted2;
            }
    
            [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern bool OpenPrinter(string pPrinterName, out IntPtr phPrinter, [In] PRINTER_DEFAULTS pDefault);
    
            [DllImport("winspool.drv", SetLastError = true)]
            private static extern bool ClosePrinter(IntPtr hPrinter);
    
            [StructLayout(LayoutKind.Sequential)]
            private class PRINTER_DEFAULTS
            {
                public IntPtr pDatatype = IntPtr.Zero;
                public IntPtr pDevMode = IntPtr.Zero;
                public int DesiredAccess = PRINTER_ALL_ACCESS;
    
                public const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
                public const int PRINTER_ACCESS_ADMINISTER = 0x4;
                public const int PRINTER_ACCESS_USE = 0x8;
                public const int PRINTER_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | PRINTER_ACCESS_ADMINISTER | PRINTER_ACCESS_USE);
            }
    
        }
    }

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2020年12月15日 10:35
  • lfast05250510さん、こんにちは。フォーラムオペレーターのKumoです。 
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    ご質問いただいた件ですが、その後いかがでしょうか。
    gekkaさんから寄せられた投稿はお役に立ちましたか。

    参考になった投稿には [回答としてマーク] をお願い致します。

    設定いただくことで、
    他のユーザーもお役に立つ回答を見つけやすくなります。

    お手数ですが、ご協力の程どうかよろしくお願いいたします。

    MSDN/ TechNet Community Support Kumo ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、 ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~

    2020年12月17日 6:15
    モデレータ