我正在使用RawPrinterHelper进行打印。它适用于Windows 7和以前的版本。 当我们使用安装在Windows 8 pc上的打印机进行尝试时,它无效。
阅读此post后,我了解到我必须将dataType变量设置为“XPS_PASS”而不是“RAW”。顺便说一下,将它设置为“XPS_PASS”在Windows 8上运行正常。
但在我的环境中,还有Windows 8s和Windows 7s以及XP。
是否可以通过编程方式进行此切换?
如何为Windows 7和更低版本的操作系统将pDataType变量设置为“RAW”,如何将“XPS_PASS”设置为Windows 8?
编辑:经过几个小时挖谷歌后,我发现了this文章。这里说:
- 调用GetPrinterDriver以检索DRIVER_INFO_8结构。
- 检查PRINTER_DRIVER_XPS标志的DRIVER_INFO_8 :: dwPrinterDriverAttributes。
- 醇>
根据是否存在,选择您的数据类型 标志:
- 如果设置了标志,请使用'XPS_PASS'
- 如果未设置标志,请使用“RAW”
我不熟悉非托管代码,但我尝试了以下内容:
[DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
public static extern int GetPrinterDriver(IntPtr hPrinter, string pEnvironment, uint Level, IntPtr pDriverInfo, int cbBuf, out int pcbNeeded);
private static void GetPrinterDataType(IntPtr hPrinter )
{
IntPtr driverInfo = new IntPtr();
driverInfo = IntPtr.Zero;
int buf_len = 0;
int IntPtrSize = Marshal.SizeOf(typeof(IntPtr));
int a = GetPrinterDriver(hPrinter, "", 8, driverInfo, 0, out buf_len);
driverInfo = Marshal.AllocHGlobal(buf_len);
a = GetPrinterDriver(hPrinter, "", 8, driverInfo, buf_len, out buf_len);
for (int i = 0; i <= 24; i++)
{
if (i == 12 || i == 15 || i == 11 || i == 14)
continue;
IntPtr ptr = Marshal.ReadIntPtr(driverInfo, IntPtrSize * i);
Console.WriteLine("DRIVER INFO {0}: {1}", i, Marshal.PtrToStringUni(ptr));
}
}
我在RawPrinterHelper类的OpenPrinter()方法之后调用此方法。但是dwPrinterDriverAttributes(数字21)是空的。
我做错了吗?
答案 0 :(得分:2)
好的,我已经设法找出如何获取dwPrinterDriverAttributes字段的值。
我将DRIVER_INFO_8结构的这个定义添加到我的解决方案中(找到here)。
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct DRIVER_INFO_8
{
public uint cVersion;
[MarshalAs(UnmanagedType.LPTStr)]
public string pName;
[MarshalAs(UnmanagedType.LPTStr)]
public string pEnvironment;
[MarshalAs(UnmanagedType.LPTStr)]
public string pDriverPath;
[MarshalAs(UnmanagedType.LPTStr)]
public string pDataFile;
[MarshalAs(UnmanagedType.LPTStr)]
public string pConfigFile;
[MarshalAs(UnmanagedType.LPTStr)]
public string pHelpFile;
[MarshalAs(UnmanagedType.LPTStr)]
public string pDependentFiles;
[MarshalAs(UnmanagedType.LPTStr)]
public string pMonitorName;
[MarshalAs(UnmanagedType.LPTStr)]
public string pDefaultDataType;
[MarshalAs(UnmanagedType.LPTStr)]
public string pszzPreviousNames;
FILETIME ftDriverDate;
UInt64 dwlDriverVersion;
[MarshalAs(UnmanagedType.LPTStr)]
public string pszMfgName;
[MarshalAs(UnmanagedType.LPTStr)]
public string pszOEMUrl;
[MarshalAs(UnmanagedType.LPTStr)]
public string pszHardwareID;
[MarshalAs(UnmanagedType.LPTStr)]
public string pszProvider;
[MarshalAs(UnmanagedType.LPTStr)]
public string pszPrintProcessor;
[MarshalAs(UnmanagedType.LPTStr)]
public string pszVendorSetup;
[MarshalAs(UnmanagedType.LPTStr)]
public string pszzColorProfiles;
[MarshalAs(UnmanagedType.LPTStr)]
public string pszInfPath;
public uint dwPrinterDriverAttributes;
[MarshalAs(UnmanagedType.LPTStr)]
public string pszzCoreDriverDependencies;
FILETIME ftMinInboxDriverVerDate;
UInt64 dwlMinInboxDriverVerVersion;
}
然后我在GetPrinterDriverDataType()方法中添加了这行代码:
var info = (DRIVER_INFO_8)Marshal.PtrToStructure(driverInfo, typeof(DRIVER_INFO_8));
现在,您将能够看到填充了dwPrinterDriverAttributes字段的内容。
编辑:将dwPrinterDriverAttributes的保护级别更新为公共,以便可以访问/查看。
另外值得注意的是(找到here):
dwPrinterDriverAttributes: A bit field that specifies attributes of the printer driver.
所以我将uint转换为BitArray并检查PRINTER_DRIVER_XPS标志/位是否已设置。
即
PRINTER_DRIVER_XPS flag = 0x00000002
所以我们需要检查第二位。我这样做有以下几点:
var value = (int)info.dwPrinterDriverAttributes;
BitArray b = new BitArray(new int[] { value } );
bool[] bits = new bool[b.Count];
b.CopyTo(bits, 0);
if (bits[1])
Console.WriteLine("flag set");
else
Console.WriteLine("flag not set");
答案 1 :(得分:-1)
很抱歉把它添加为答案,但实际上我有问题RawPrinterHelper用于引用我的pdf它在打印时没有显示任何异常,但仍然没有为我打印pdf。当我试图打印时总是说0文件等待(我的名字)。无论我是打印文件还是文本(使用课堂上的方法)。可以帮助我解决问题
由于