How to get RawPrinterHelper to work in both XPS_PATH and RAW types?

I am using RawPrinterHelper for printing. And it works great with Windows 7 and previous versions. When we tried it with a printer installed on a computer with Windows 8, it did not work.

After reading this post, I found out that I need to set the dataType variable to "XPS_PASS" instead of "RAW". By the way, installing it on "XPS_PASS" works fine on Windows 8.

But in my environment there are windows 8s and windows 7s and XP.

Is it possible to make this switch programmatically?

How to set the pDataType variable to "RAW" for Windows 7 and lower operating systems and "XPS_PASS" for Windows 8?

Edit: After a couple of hours of google digging, I found this article . It says here:

  • Call GetPrinterDriver to retrieve the DRIVER_INFO_8 structure.
  • Check DRIVER_INFO_8 :: dwPrinterDriverAttributes for the flag PRINTER_DRIVER_XPS.
  • Select a data type based on the presence or absence of a Flag:

    • If the flag is set, use 'XPS_PASS
    • If the flag is not set, use 'RAW

I am not familiar with unmanaged code, but I tried followig:

[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)); } } 

I call this method after the OpenPrinter () method of the RawPrinterHelper class. But dwPrinterDriverAttributes (number 21) is empty.

Am I doing something wrong?

Output of the method

+1
source share
2 answers

Well, I was able to figure out how to get the value displayed for the dwPrinterDriverAttributes field.

I added this DRIVER_INFO_8 structure definition to my solution (found 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; } 

Then I added this line of code to what you specified above in the GetPrinterDriverDataType () method:

 var info = (DRIVER_INFO_8)Marshal.PtrToStructure(driverInfo, typeof(DRIVER_INFO_8)); 

Now you can see how the dwPrinterDriverAttributes field is populated.

EDIT: The dwPrinterDriverAttributes security level update will be publicly available so that it can be viewed / viewed.

Also worth noting is (found here ):

 dwPrinterDriverAttributes: A bit field that specifies attributes of the printer driver. 

So, I converted uint to BitArray and checked if the flag / bit is set to PRINTER_DRIVER_XPS.

i.e.

 PRINTER_DRIVER_XPS flag = 0x00000002 

So, we need to check the second bit. I do this with the following:

 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"); 
+2
source

Sorry to add it as an answer, but actually I have a problem with RawPrinterHelper for attracting my pdf file, it does not show any exceptions while printing, but still does not print the PDF for me. When I try to print, it always says 0 pending document (my name). Regardless of whether I print a file or text (using the method in the class). Can anyone help me solve it.

thanks

-1
source

Source: https://habr.com/ru/post/1215656/


All Articles