如何使RawPrinterHelper在XPS_PATH和RAW数据类型中都有效?

我正在使用RawPrinterHelper进行打印。 它适用于Windows 7和以前的版本。 当我们使用安装在Windows 8 pc上的打印机进行尝试时,它无效。

阅读这篇文章后,我了解到我必须将dataType变量设置为“XPS_PASS”而不是“RAW”。 顺便说一下,将它设置为“XPS_PASS”在Windows 8上运行正常。

但在我的环境中,还有Windows 8s和Windows 7s以及XP。

是否可以通过编程方式进行此切换?

如何为Windows 7和更低版本的操作系统将pDataType变量设置为“RAW”,如何将“XPS_PASS”设置为Windows 8?

编辑:经过几个小时挖谷歌我发现这篇文章。 这里说:

  1. 调用GetPrinterDriver以检索DRIVER_INFO_8结构。
  2. 检查PRINTER_DRIVER_XPS标志的DRIVER_INFO_8 :: dwPrinterDriverAttributes。
  3. 根据是否存在标志选择数据类型:

    • 如果设置了标志,请使用’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)是空的。

难道我做错了什么?

输出方法

好的,我已经设法弄清楚如何获取dwPrinterDriverAttributes字段的值。

我将DRIVER_INFO_8结构的这个定义添加到我的解决方案中(在此处找到)。

 [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的保护级别更新为公共,以便可以访问/查看。

另外值得注意的是(在这里找到):

 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"); 

很抱歉添加它作为答案,但实际上我有RawPrinterHelper的问题,为了引用我的pdf它没有显示任何exception打印但仍然不打印pdf为我。当我试图打印它总是说0文档待定对于(我的名字)。无论我是打印文件还是文本(使用课堂上的方法)。任何人都可以帮我解决

谢谢