Tôi có một số mã C# (VS2010; fx2) được sử dụng để thực hiện các chức năng của máy in. Mã này hoạt động tốt trong môi trường Windows XP. Thay đổi sang Windows 7, nó không còn hoạt động chính xác nữa.Thay đổi sử dụng Winspool.drv trong Windows 7 64 bit từ Windows XP 32 bit
Hành vi khác nhau đầu tiên là phương thức GetPrinterNames() hiện chỉ trả về máy in cục bộ. Như bạn có thể thấy, các cờ được thiết lập để bao gồm cả máy in NETWORK. Tôi đã thử các cờ khác nhau, nhưng không thành công.
Có thư viện nào khác mà tôi nên tham khảo trong phiên bản Windows 7/64 bit không?
Printer lớp helper với mã hiển thị dưới đây:
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
}
EDIT: Mã sửa để giảm kích thước (lĩnh vực quan tâm ít bị loại bỏ).
Bạn nghĩ bạn có thể thu hẹp lại một chút? Đó là rất nhiều mã bạn muốn chúng tôi xem xét. –
Xin chào John. Tôi đã xóa những gì tôi nghĩ là các phần không liên quan của mã. Phương thức quan tâm là GetPrinterNames() - dựa trên enumPrinters(). Các chức năng khác cũng không hoạt động - nhưng tôi nghi ngờ nó sẽ là nguyên nhân tương tự. Cảm ơn trước. – Jayden