本文介绍了SetJob() 方法总是返回 122的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个 C# 程序来更改打印作业的方向.这是我的做法

I am writing a C# program to change the orientation of print job.Here is how I am doing it

• 使用 OpenPrinter() 打开打印机

• Open Printer using OpenPrinter()

• 使用 GetJob() 使用 JOB_INFO_2 结构获取作业详细信息

• Get the job details with JOB_INFO_2 structure using GetJob()

• 更改 JOB_INFO_2 结构中的方向

• Change the orientation in JOB_INFO_2 structure

• 使用 SetJob() 设置 JOB_INFO_2 结构

• Set the JOB_INFO_2 structure using SetJob()

但是当我调用 SetJob() 方法时,它总是失败并返回代码 122.我正在用 PRINTER_ALL_ACCESS 打开打印机.(我也试过 PRINTER_ACCESS_ADMINISTER 但没有运气).我使用的打印机是本地打印机.

But when I call SetJob() method it always fails with the return code 122.I am opening printer with PRINTER_ALL_ACCESS. (I have also tried with PRINTER_ACCESS_ADMINISTER but no luck). The printer I am using is local printer.

我做错了什么?

这是我的代码

public class PrintJob
{
    #region Native Method Imports
    [DllImport("winspool.drv", EntryPoint = "OpenPrinter", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
    public static extern bool OpenPrinter(string pPrinterName, out IntPtr phPrinter, ref PRINTER_DEFAULTS pDefault);

    [DllImport("winspool.drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
    public static extern bool ClosePrinter(IntPtr hPrinter);

    [DllImport("winspool.drv", EntryPoint = "GetJob", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
    public static extern bool GetJob(IntPtr hPrinter, Int32 dwJobId, Int32 Level, IntPtr lpJob, Int32 cbBuf, ref Int32 lpbSizeNeeded);

    [DllImport("winspool.drv", EntryPoint = "GetJob", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
    public static extern bool GetJob(Int32 hPrinter, Int32 dwJobId, Int32 Level, IntPtr lpJob, Int32 cbBuf, ref Int32 lpbSizeNeeded);

    [DllImport("winspool.drv", EntryPoint = "SetJobA")]
    public static extern bool SetJob(IntPtr hPrinter, int JobId, int Level, IntPtr pJob, int Command_Renamed);

    [StructLayout(LayoutKind.Sequential)]
    internal struct PRINTER_DEFAULTS
    {
        public int pDatatype;
        public int pDevMode;
        public uint DesiredAccess;
    }

    private const int DM_ORIENTATION = 0x1;
    #endregion

    public void ChangePrintOrientation(string printerName, int jobId)
    {
        IntPtr _printerHandle = IntPtr.Zero;
        PRINTER_DEFAULTS pDefaults = new PRINTER_DEFAULTS();
        pDefaults.DesiredAccess = 0xf000c; // PRINTER_ALL_ACCESS;
        pDefaults.pDatatype = 0;
        pDefaults.pDevMode = 0;

        //Open the printer
        OpenPrinter(printerName, out _printerHandle, ref pDefaults);
        if (_printerHandle == IntPtr.Zero)
        {
            throw new Exception("OpenPrinter() Failed with error code " + Marshal.GetLastWin32Error());
        }

        //Get the JOB details from GetJob()
        JOB_INFO_2 jobInfo = GetJobInfo2(_printerHandle, jobId);
        if(jobInfo == null)
        {
            throw new Exception("Could not get job details"); 
        }

        //Set the orientation
        jobInfo.DeviceMode.dmFields = DM_ORIENTATION;
        jobInfo.DeviceMode.dmOrientation = 2;//LANDSCAPE

        IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(jobInfo));
        Marshal.StructureToPtr(jobInfo, ptr, false);

        //Set the job
        if(!SetJob(_printerHandle, jobId, 2, ptr, 0)) //Here i always get 122 from the function
        {
            throw new Exception("SetJob() Failed with error code " + Marshal.GetLastWin32Error());
        }

        //Finally close the printer
        ClosePrinter(_printerHandle);

    }

    private JOB_INFO_2 GetJobInfo2(IntPtr _printerHandle, int jobId)
    {
        JOB_INFO_2 info = null;
        Int32 BytesWritten = default(Int32);
        IntPtr ptBuf = default(IntPtr);

        //Get the required buffer size
        if (!GetJob(_printerHandle, jobId, 2, ptBuf, 0, ref BytesWritten))
        {
            if (BytesWritten == 0)
            {
                throw new Exception("GetJob for JOB_INFO_2 failed on handle: " + _printerHandle.ToString() + " for job: " + jobId);
            }
        }

        //Allocate a buffer the right size
        if (BytesWritten > 0)
        {
            ptBuf = Marshal.AllocHGlobal(BytesWritten * 2);
        }

        if (!GetJob(_printerHandle, jobId, 2, ptBuf, BytesWritten, ref BytesWritten))
        {
            throw new Exception("GetJob for JOB_INFO_2 failed on handle: " + _printerHandle.ToString() + " for job: " + jobId);
        }
        else
        {
            info = new JOB_INFO_2();
            Marshal.PtrToStructure(ptBuf, info);

            //Fill the devmode structure
            IntPtr ptrDevMode = new IntPtr(info.LPDeviceMode);
            Marshal.PtrToStructure(ptrDevMode, info.dmOut);
        }

        //\\ Free the allocated memory
        Marshal.FreeHGlobal(ptBuf);
        return info;
    }
}

我从这里获取了 DEVMODE 结构.

I have taken DEVMODE structure from here.

推荐答案

返回值基于以下规则:如果函数成功,则返回值是一个非零值.如果函数失败,则返回值为零.

the return value is based the following rule: If the function succeeds, the return value is a nonzero value.If the function fails, the return value is zero.

而您的代码是:if(!SetJob(_printerHandle, jobId, 2, ptr, 0))//这里我总是从函数中得到122{throw new Exception("SetJob() Failed with error code " + Marshal.GetLastWin32Error());}

while your code is :if(!SetJob(_printerHandle, jobId, 2, ptr, 0)) //Here i always get 122 from the function { throw new Exception("SetJob() Failed with error code " + Marshal.GetLastWin32Error()); }

表示当SetJob ruturn成功时,代码抛出异常

it means when SetJob ruturn sucess, code throw exception

这篇关于SetJob() 方法总是返回 122的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-01 17:16