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

时间:2014-09-12 11:18:46

标签: c# printing

我正在使用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文章。这里说:

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

         
        
    • 如果设置了标志,请使用'XPS_PASS'
    •   
    • 如果未设置标志,请使用“RAW”
    •   
  6.   

我不熟悉非托管代码,但我尝试了以下内容:

[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)是空的。

我做错了吗?

Output of the method

2 个答案:

答案 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文件等待(我的名字)。无论我是打印文件还是文本(使用课堂上的方法)。可以帮助我解决问题

由于