- Thread Author
- #1
Hello, my application has a feature that shows printers details as tree node and I use EnumPrinters API to fill nodes of this tree. i.e., the provider name, domain names and printer names etc. We have used Lazy loading concept in this tree formation. EnumPrinters API is called for any node level details and count on output records is used to fetch next inner level detail for any node. when EnumPrinters is called for any printername given it works fine on all platforms except VISTA. I have also attached sample code to give idea on APIs used. Below code words fine on all platforms, but on vista it returns error code 87. Does Vista needs special changes in code to handle the scenario? Whats wrong is going on here for Vista?//Code Starts from here. This is C# console application. Enumprinters gives error in second call to GetPrinters() when called for printer names on Vista.usingSystem; usingSystem.Runtime.InteropServices;usingSystem.Runtime.Serialization;classPlatformInvokeTest{[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] private class PRINTER_INFO_1{ public int flags; public IntPtr pDescription; public IntPtr pName; public IntPtr pComment; }[StructLayout(LayoutKind.Sequential)] private struct PRINTER_INFO_2{ public IntPtr pServerName; public IntPtr pPrinterName; public IntPtr pShareName; public IntPtr pPortName; public IntPtr pDriverName; public IntPtr pComment; public IntPtr pLocation; public IntPtr pDevMode; public IntPtr pSepFile; public IntPtr pPrintProcessor; public IntPtr pDatatype; public IntPtr pParameters; public IntPtr pSecurityDescriptor; public Int32 Attributes; public Int32 Priority; public Int32 DefaultPriority; public Int32 StartTime; public Int32 UntilTime; public Int32 Status; public Int32 cJobs; public Int32 AveragePPM; } public struct PrinterInfo_1{ public int flags; public string Name; public string Description; public string Comment; } public struct PrinterInfo_2{ public string ServerName; public string PrinterName; public string ShareName; public string PortName; public string DriverName; public string Comment; public string Location; public int Status; }[DllImport("winspool.drv", SetLastError = true, CharSet = CharSet.Auto)] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool EnumPrinters( [MarshalAs(UnmanagedType.U4)] PRINTER_ENUM flags, [MarshalAs(UnmanagedType.LPTStr)] string sName, uint iLevel, IntPtr pPrinterDesc, uint iSize, [MarshalAs(UnmanagedType.U4)] ref uint iNeeded, [MarshalAs(UnmanagedType.U4)] ref uint iReturned ); public enum PRINTER_ENUM{DEFAULT = 0x00000001,LOCAL = 0x00000002,CONNECTIONS = 0x00000004,NAME = 0x00000008,REMOTE = 0x00000010,SHARED = 0x00000020,NETWORK = 0x00000040} public enum DETAIL_TYPE{Providername = 0x00000001,Printername = 0x00000002,printerdetail = 0x00000004,None = 0x00000008,} public sealed class Win32Error{ private Win32Error() { } public const int ERROR_INSUFFICIENT_BUFFER = 122; } static PrinterInfo_1[] GetPrinterInfoFromMemory( IntPtr prInfo,uint numPrinters, DETAIL_TYPE type) { PRINTER_INFO_1 pi = new PRINTER_INFO_1(); PrinterInfo_1[] pInfo = new PrinterInfo_1[numPrinters]; for (int i = 0; i < numPrinters; i++) { Marshal.PtrToStructure(prInfo, pi); pInfo.flags = pi.flags;pInfo.Name =Marshal.PtrToStringAuto(pi.pName); pInfo.Description =Marshal.PtrToStringAuto(pi.pDescription); pInfo.Comment =Marshal.PtrToStringAuto(pi.pComment); prInfo =new IntPtr(prInfo.ToInt32() + Marshal.SizeOf(typeof(PRINTER_INFO_1))); if (type == DETAIL_TYPE.Printername) {printerArray.Add(pInfo.Name);}} return pInfo; } static PrinterInfo_1[] GetPrinters(PRINTER_ENUM printerKind, string strName, DETAIL_TYPE type) { PrinterInfo_1[] pInfo = new PrinterInfo_1[0]; uint iNeeded = 0, iReturned = 0, iSize = 0; IntPtr printers = IntPtr.Zero; if (!EnumPrinters(printerKind, strName,1,printers,0, ref iNeeded, ref iReturned) ){ int err = Marshal.GetLastWin32Error(); if (err != Win32Error.ERROR_INSUFFICIENT_BUFFER) {} // ThrowEnumPrinterException();}iSize = iNeeded; if (iNeeded != 0) { try{printers =Marshal.AllocHGlobal(new IntPtr(iSize)); if (!EnumPrinters(printerKind, strName,1,printers,iSize, ref iNeeded, ref iReturned) ){ // ThrowEnumPrinterException();} else{pInfo = GetPrinterInfoFromMemory(printers, iReturned, type);}} finally{ if (printers != IntPtr.Zero) Marshal.FreeHGlobal(printers); }} return pInfo; } static System.Collections.ArrayList printerArray; public static void Main() {printerArray =new System.Collections.ArrayList(); string printerName = "Microsoft Office Document Image Writer"; GetPrinters(PRINTER_ENUM.LOCAL, null, DETAIL_TYPE.Printername); for (int i = 0; i < printerArray.Count; i++) {GetPrinters(PRINTER_ENUM.NAME, printerArray.ToString(), DETAIL_TYPE.None); }}}