使用Windows 7中的Winspool.drv从Windows XP 32位进行更改

Jay*_*den 5 c# 64-bit network-printers windows-7

我有一些C#代码(VS2010; fx2),用于执行打印机功能.此代码在Windows XP环境中正常工作.更改为Windows 7,它不再正常工作.

第一个不同的行为是GetPrinterNames()方法现在只返回本地打印机.如您所见,标志也设置为包括NETWORK打印机.我尝试过不同的旗帜,但没有成功.

我应该在Windows 7/64位版本中引用不同的库吗?

打印机助手类,代码如下所示:

internal class Printers
{

    ...

    [DllImport("winspool.drv", SetLastError = true)]
    static extern bool EnumPrintersW(Int32 flags, [MarshalAs(UnmanagedType.LPTStr)] string printerName,
         Int32 level, IntPtr buffer, Int32 bufferSize, out Int32 requiredBufferSize,
         out Int32 numPrintersReturned);

    [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool EnumPrinters(PrinterEnumFlags Flags, string Name, uint Level, IntPtr pPrinterEnum, uint cbBuf, ref uint pcbNeeded, ref uint pcReturned);

    ...

    ...

    public static string[] GetPrinterNames()
    {
        List<string> returnVal = new List<string>();
        foreach(PRINTER_INFO_2 info in enumPrinters(PrinterEnumFlags.PRINTER_ENUM_LOCAL | PrinterEnumFlags.PRINTER_ENUM_NETWORK))
        {
            returnVal.Add(info.pPrinterName);
        }
        return returnVal.ToArray();
    }

...

    private static PRINTER_INFO_2[] enumPrinters(PrinterEnumFlags Flags)
    {
        uint cbNeeded = 0;
        uint cReturned = 0;
        if (EnumPrinters(Flags, null, 2, IntPtr.Zero, 0, ref cbNeeded, ref cReturned))
        {
            return null;
        }
        int lastWin32Error = Marshal.GetLastWin32Error();
        if (lastWin32Error == ERROR_INSUFFICIENT_BUFFER)
        {
            IntPtr pAddr = Marshal.AllocHGlobal((int)cbNeeded);
            if (EnumPrinters(Flags, null, 2, pAddr, cbNeeded, ref cbNeeded, ref cReturned))
            {
                PRINTER_INFO_2[] printerInfo2 = new PRINTER_INFO_2[cReturned];
                int offset = pAddr.ToInt32();
                Type type = typeof(PRINTER_INFO_2);
                int increment = Marshal.SizeOf(type);
                for (int i = 0; i < cReturned; i++)
                {
                    printerInfo2[i] = (PRINTER_INFO_2)Marshal.PtrToStructure(new IntPtr(offset), type);
                    offset += increment;
                }
                Marshal.FreeHGlobal(pAddr);
                return printerInfo2;
            }
            lastWin32Error = Marshal.GetLastWin32Error();
        }
        throw new System.ComponentModel.Win32Exception(lastWin32Error);
    }

    ...

    [FlagsAttribute]
    enum PrinterEnumFlags
    {
        PRINTER_ENUM_DEFAULT = 0x00000001,
        PRINTER_ENUM_LOCAL = 0x00000002,
        PRINTER_ENUM_CONNECTIONS = 0x00000004,
        PRINTER_ENUM_FAVORITE = 0x00000004,
        PRINTER_ENUM_NAME = 0x00000008,
        PRINTER_ENUM_REMOTE = 0x00000010,
        PRINTER_ENUM_SHARED = 0x00000020,
        PRINTER_ENUM_NETWORK = 0x00000040,
        PRINTER_ENUM_EXPAND = 0x00004000,
        PRINTER_ENUM_CONTAINER = 0x00008000,
        PRINTER_ENUM_ICONMASK = 0x00ff0000,
        PRINTER_ENUM_ICON1 = 0x00010000,
        PRINTER_ENUM_ICON2 = 0x00020000,
        PRINTER_ENUM_ICON3 = 0x00040000,
        PRINTER_ENUM_ICON4 = 0x00080000,
        PRINTER_ENUM_ICON5 = 0x00100000,
        PRINTER_ENUM_ICON6 = 0x00200000,
        PRINTER_ENUM_ICON7 = 0x00400000,
        PRINTER_ENUM_ICON8 = 0x00800000,
        PRINTER_ENUM_HIDE = 0x01000000
    }
Run Code Online (Sandbox Code Playgroud)

编辑:编辑代码以减小尺寸(删除不太感兴趣的区域).

小智 1

根据 EnumPrinters 的 msdn 注释,您的代码仅在第三个参数为 1 时才有效

来自枚举打印机....

PRINTER_ENUM_NETWORK 该函数枚举计算机域中的网络打印机。仅当 Level 为 1 时该值才有效。