添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
近视的金鱼  ·  如何在flutter ...·  1 年前    · 
卖萌的充电器  ·  Python ...·  2 年前    · 
失恋的汽水  ·  mysql : show ...·  2 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams Printer printer = new Printer(); IntPtr printerHandle = printer.getPrinterHandle("TASKalfa 2551ci"); UInt32 jobId = printer.getJobId(); Console.WriteLine(printerHandle+","+jobId); printer.getJob(printerHandle, jobId); Console.ReadLine();

I got the following error message from VS 2015 Community Edition, when I call printer.getJob Method, even I have catched the System.NullReferenceException.

System.NullReferenceException was unhandled
Message: An unhandled exception of type 'System.NullReferenceException' occurred in mscorlib.dll
Additional information: Object reference not set to an instance of an object.

I have checked that both variable printerHandle and jobId are not null, so I cannot figure out what is problem.

However the value of printerHandle is not a constant, is it correct?

Here is my printer object source code:

using System;
using System.Collections;
using System.Management;
using System.Runtime.InteropServices;
class Printer
    public Printer()
    public ArrayList getPrinterNameList()
        ArrayList result = new ArrayList();
        var printerQuery = new ManagementObjectSearcher("SELECT * from Win32_Printer");
        foreach (var printer in printerQuery.Get())
            result.Add(printer.GetPropertyValue("Name"));
        return result;
    public UInt32 getJobId()
        UInt32 jobId=0;
        var printJobQuery = new ManagementObjectSearcher("select * from Win32_PrintJob");
        foreach (var printJob in printJobQuery.Get())
            jobId= (UInt32)printJob.Properties["JobId"].Value;
        return jobId;
    public IntPtr getPrinterHandle(String printerName)
        IntPtr result=new IntPtr(0);
        Console.WriteLine ("OpenPrinter="+OpenPrinter(printerName,out result, result));
        return result;
    public void getJob(IntPtr printerHandle,UInt32 jobId)
        int BUFFER_SIZE = 250;
        IntPtr pcbNeeed = new IntPtr(0);
        byte[] byteBuffer = new byte[BUFFER_SIZE];
            Console.WriteLine("GetJob="+GetJob(printerHandle, (Int32)jobId, 1, out byteBuffer, BUFFER_SIZE, out pcbNeeed));
        catch (System.NullReferenceException err)
            Console.WriteLine(err.Message);
    [DllImport("winspool.drv", SetLastError = true)]
    static extern int OpenPrinter(string pPrinterName, out IntPtr phPrinter, IntPtr pDefault);
     [DllImport(
        "winspool.drv",
        EntryPoint = "GetJobW",
        SetLastError = true,
        CharSet = CharSet.Ansi,
        ExactSpelling = false,
        CallingConvention = CallingConvention.StdCall)]
            private static extern bool GetJob
        ([InAttribute()] IntPtr hPrinter,
        [InAttribute()] Int32 JobId,
        [InAttribute()] Int32 Level,
        [OutAttribute()] out byte[] pJob,
        [InAttribute()] Int32 cbBuf,
        [OutAttribute()] out IntPtr pcbNeeded);
                string msg = null;
                var hPrinter = new IntPtr();
                bool open = NativeMethods.OpenPrinterW("TASKalfa 2551ci", ref hPrinter, IntPtr.Zero);
                Debug.Assert(open);
                /* Query for 99 jobs */
                const uint firstJob = 0u;
                const uint noJobs = 99u;
                const uint level = 1u;
                // Get byte size required for the function
                uint needed;
                uint returned;
                IntPtr tempptr = IntPtr.Zero;
                bool b1 = NativeMethods.EnumJobsW(
                    hPrinter, firstJob, noJobs, level, IntPtr.Zero, 0, out needed, out returned);
                uint lastError = NativeMethods.GetLastError();
                Console.WriteLine("b1="+b1);
                //Debug.Assert(lastError == NativeConstants.ERROR_INSUFFICIENT_BUFFER);
                NativeMethods.FormatMessage(0x1300, ref tempptr, lastError, 0, ref msg, 255, ref tempptr);
                Console.WriteLine("lastError=" + msg);
                // Populate the structs
                IntPtr pJob = Marshal.AllocHGlobal((int)needed);
                uint bytesCopied;
                uint structsCopied;
                bool b2 = NativeMethods.EnumJobsW(
                    hPrinter, firstJob, noJobs, level, pJob, needed, out bytesCopied, out structsCopied);
                lastError = NativeMethods.GetLastError();
                Console.WriteLine("b2="+b2);
                NativeMethods.FormatMessage(0x1300, ref tempptr, lastError, 0, ref msg, 255, ref tempptr);
                Console.WriteLine("lastError="+ msg);
                var jobInfos = new JOB_INFO_1W[structsCopied];
                int sizeOf = Marshal.SizeOf(typeof(JOB_INFO_1W));
                IntPtr pStruct = pJob;
                for (int i = 0; i < structsCopied; i++)
                    var jobInfo_1W = (JOB_INFO_1W)Marshal.PtrToStructure(pStruct, typeof(JOB_INFO_1W));
                    jobInfos[i] = jobInfo_1W;
                    pStruct += sizeOf;
                Marshal.FreeHGlobal(pJob);
                Console.WriteLine("structsCopied="+structsCopied);
                Console.ReadLine();
            public class NativeConstants
                public const int ERROR_INSUFFICIENT_BUFFER = 122;
            public partial class NativeMethods
                [DllImport("kernel32.dll", EntryPoint = "GetLastError")]
                public static extern uint GetLastError();
                [System.Runtime.InteropServices.DllImport("Kernel32.dll")]
                public extern static int FormatMessage(int flag, ref IntPtr source, uint msgid, int langid, ref string buf, int size, ref IntPtr args);
            public partial class NativeMethods
                [DllImport("Winspool.drv", EntryPoint = "OpenPrinterW")]
                [return: MarshalAs(UnmanagedType.Bool)]
                public static extern bool OpenPrinterW([In] [MarshalAs(UnmanagedType.LPWStr)] string pPrinterName,
                    ref IntPtr phPrinter, [In] IntPtr pDefault);
                [DllImport("Winspool.drv", EntryPoint = "EnumJobsW")]
                [return: MarshalAs(UnmanagedType.Bool)]
                public static extern bool EnumJobsW([In] IntPtr hPrinter, uint FirstJob, uint NoJobs, uint Level, IntPtr pJob,
                    uint cbBuf, [Out] out uint pcbNeeded, [Out] out uint pcReturned);
            [StructLayout(LayoutKind.Sequential)]
            public struct JOB_INFO_1W
                public uint JobId;
                [MarshalAs(UnmanagedType.LPWStr)]
                public string pPrinterName;
                [MarshalAs(UnmanagedType.LPWStr)]
                public string pMachineName;
                [MarshalAs(UnmanagedType.LPWStr)]
                public string pUserName;
                [MarshalAs(UnmanagedType.LPWStr)]
                public string pDocument;
                [MarshalAs(UnmanagedType.LPWStr)]
                public string pDatatype;
                [MarshalAs(UnmanagedType.LPWStr)]
                public string pStatus;
                public uint Status;
                public uint Priority;
                public uint Position;
                public uint TotalPages;
                public uint PagesPrinted;
                public SYSTEMTIME Submitted;
            [StructLayout(LayoutKind.Sequential)]
            public struct SYSTEMTIME
                public ushort wYear;
                public ushort wMonth;
                public ushort wDayOfWeek;
                public ushort wDay;
                public ushort wHour;
                public ushort wMinute;
                public ushort wSecond;
                public ushort wMilliseconds;

I am using Windows 10.

Make your life simple and replace all the System.Management nonsense with Win32 API. It works at half the price. – Carey Gregory Aug 30, 2017 at 20:23 string sql = "select * from Win32_PrintJob"; var printJobQuery = new ManagementObjectSearcher(sql); foreach (ManagementObject printJob in printJobQuery.Get()) getJobDetail(printJob); Console.WriteLine("===================="); private void getJobDetail(ManagementObject thePrintJob) UInt32 jobId = 0, needed = 0; String printerName; bool result; IntPtr printerHandle = new IntPtr(0); jobId = (UInt32)thePrintJob.Properties["JobId"].Value; printerName = (String)thePrintJob.Properties["DriverName"].Value; Console.WriteLine("Job Id=" + jobId + ",Printer Name=" + printerName); result=OpenPrinter(printerName,out printerHandle, IntPtr.Zero); Console.Write("Open Printer " + printerName); if (result) Console.WriteLine(" success."); result = GetJob(printerHandle, jobId, 2, IntPtr.Zero,0,out needed); if (Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER) Console.WriteLine("Get Job 1 failure, error code=" + Marshal.GetLastWin32Error()); Console.WriteLine("buffer size required=" + needed); IntPtr buffer = Marshal.AllocHGlobal((int)needed); result = GetJob(printerHandle, jobId, 2, buffer, needed, out needed); JOB_INFO_2 jobInfo=(JOB_INFO_2)Marshal.PtrToStructure(buffer, typeof(JOB_INFO_2)); DEVMODE dMode = (DEVMODE)Marshal.PtrToStructure(jobInfo.pDevMode, typeof(DEVMODE)); Console.WriteLine("Job Id=" + jobInfo.JobId + ",Printer Name=" + Marshal.PtrToStringAnsi(jobInfo.pDriverName) + ",Copies=" + dMode.dmCopies); Marshal.FreeHGlobal(buffer); ClosePrinter(printerHandle); Console.WriteLine("Printer " + printerName+" is closed"); Console.WriteLine(" failed."); [DllImport("winspool.drv", SetLastError = true)] static extern bool OpenPrinter(string pPrinterName, out IntPtr phPrinter, IntPtr pDefault); [DllImport("winspool.drv", CharSet = CharSet.Auto)] static extern bool ClosePrinter(IntPtr hPrinter); [DllImport( "winspool.drv", EntryPoint = "GetJob", SetLastError = true, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)] private static extern bool GetJob ([InAttribute()] IntPtr hPrinter, [InAttribute()] UInt32 JobId, [InAttribute()] UInt32 Level, [OutAttribute()] IntPtr pJob, [InAttribute()] UInt32 cbBuf, [OutAttribute()] out UInt32 pcbNeeded); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] private struct JOB_INFO_2 public UInt32 JobId; public IntPtr pPrinterName; public IntPtr pMachineName; public IntPtr pUserName; public IntPtr pDocument; public IntPtr pNotifyName; public IntPtr pDatatype; public IntPtr pPrintProcessor; public IntPtr pParameters; public IntPtr pDriverName; public IntPtr pDevMode; public IntPtr pStatus; public IntPtr pSecurityDescriptor; public UInt32 Status; public UInt32 Priority; public UInt32 Position; public UInt32 StartTime; public UInt32 UntilTime; public UInt32 TotalPages; public UInt32 Size; public SYSTEMTIME Submitted; public UInt32 Time; public UInt32 PagesPrinted; [StructLayout(LayoutKind.Sequential)] public struct SYSTEMTIME public short wYear; public short wMonth; public short wDayOfWeek; public short wDay; public short wHour; public short wMinute; public short wSecond; public short wMilliseconds; [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct DEVMODE [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string dmDeviceName; public short dmSpecVersion; public short dmDriverVersion; public short dmSize; public short dmDriverExtra; public int dmFields; public short dmOrientation; public short dmPaperSize; public short dmPaperLength; public short dmPaperWidth; public short dmScale; public short dmCopies; public short dmDefaultSource; public short dmPrintQuality; public short dmColor; public short dmDuplex; public short dmYResolution; public short dmTTOption; public short dmCollate; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string dmFormName; public short dmLogPixels; public int dmBitsPerPel; public int dmPelsWidth; public int dmPelsHeight; public int dmDisplayFlags; public int dmDisplayFrequency; I need to save the document that was send to the printer. Can I do that using the print job? – jNewbie Oct 20, 2017 at 2:43

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.