/* System.Printing.dll
         * MS.Internal.PrintWin32Thunk.PrinterThunkHandler.ThunkEnumPrinters();
         *
         * System.Drawing.dll:
         * System.Drawing.Printing.PrinterSettings.InstalledPrinters.Get;
         */
        internal static object[] ThunkEnumPrinters(PrinterFlags flags, string name, int level)
        {
            Type type = null;

            switch (level)
            {
            case 1:
                type = typeof(PrinterInfo1);
                break;

            case 2:
                type = typeof(PrinterInfo2);
                break;

            case 4:
                type = typeof(PrinterInfo4);
                break;

            case 5:
                type = typeof(PrinterInfo5);
                break;

            default:
                throw Error.ArgumentOutOfRange("level");
            }

            // 所需缓存字节数量
            int pcbNeeded;
            // 数据条目数量
            int pcReturned;

            // 首次调用 为了获知: 所需缓存字节数量
            if (!EnumPrinters(flags, name, level, IntPtr.Zero, 0, out pcbNeeded, out pcReturned))
            {
                Error.ThrowIfLastErrorIsNotInsufficientBuffer();
            }

            if (pcbNeeded > 0)
            {
                var pBuffer = IntPtr.Zero;
                try
                {
                    // 分配本地内存
                    pBuffer = Marshal.AllocHGlobal(pcbNeeded);
                    if (!EnumPrinters(flags, name, level, pBuffer, pcbNeeded, out pcbNeeded, out pcReturned))
                    {
                        Error.ThrowLastError();
                    }

                    var p     = pBuffer;              // 当前数据起始指针
                    var size  = Marshal.SizeOf(type); // 单个数据指针增量
                    var infos = new object[pcReturned];
                    for (int i = 0; i < pcReturned; i++)
                    {
                        infos[i] = Marshal.PtrToStructure(p, type);
                        p       += size;
                    }
                    return(infos);
                }
                finally
                {
                    // 释放本地内存
                    if (pBuffer != IntPtr.Zero)
                    {
                        Marshal.FreeHGlobal(pBuffer);
                    }
                }
            }
            return(new object[0]);
        }
示例#2
0
 static extern bool EnumPrinters(PrinterFlags Flags, string Name, int Level, IntPtr pPrinterEnum, int cbBuf, out int pcbNeeded, out int pcReturned);