Using OpenPrinter/SetPrinter in Win2K3
-
Pardon the big post... I am using the code below to set my printer into Duplex mode, which has to be done via the driver as I sometimes want duplex printing in word, and sometimes I dont. Anyway, regardless of whether you think this can be done with System.Drawing.Printing or not, I want to limit this purely to "why do my API calls not work" as a worthwhile excercise in unmanaged code and interop... Based on many articles I have seen on the web I came up with the class below, but it seems I am also suffering the same woes that every user who ever tried to switch duplex printing on, has suffered, and that it is hard to get it to work. Why am I getting access denied as commented below? Why do the docs say that OpenPrinter has to take a PRINTER_DEFAULTS byref, and when I pass it by ref, every thing breaks at runt time, like, I don't get a printer handle and OpenPrinter causes an Err.LastDllError of 5 (access denied). I think you either know the answer to this one or not. I don't want speculcation and supposition, just hard tested solutions, coz the web is littered with suggestions that dont seem to work. The fundamental problem seems to be that my code doesn't have the right security descriptior to use SetPrinter, even if I log on to my Windows 2003 server as an administrator. Thanks guys, in advance for your patience and efforts! ''' TEST CODE FOR CLASS - put this in a form or module Private Sub Test() Dim lPrinter As New APIPrinter Dim lName As String = lPrinter.DefaultPrinterName lPrinter.Open(lName) lPrinter.DuplexMode = APIPrinter.DuplexOption.LongEdge lPrinter.Close() End Sub ''' CODE FOR CLASS - put this in a spearate class VB file Imports System.Runtime.InteropServices Imports System.Text Public Class APIPrinter Implements IDisposable #Region "WinApi" #Region "Structures" Public Structure PRINTER_DEFAULTS Public pDatatype As String Public pDevMode As IntPtr Public DesiredAccess As Int32 End Structure Public Structure PRINTER_INFO_2 Public pServerName As String Public pPrinterName As String Public pShareName As String Public pPortName As String Public
-
Pardon the big post... I am using the code below to set my printer into Duplex mode, which has to be done via the driver as I sometimes want duplex printing in word, and sometimes I dont. Anyway, regardless of whether you think this can be done with System.Drawing.Printing or not, I want to limit this purely to "why do my API calls not work" as a worthwhile excercise in unmanaged code and interop... Based on many articles I have seen on the web I came up with the class below, but it seems I am also suffering the same woes that every user who ever tried to switch duplex printing on, has suffered, and that it is hard to get it to work. Why am I getting access denied as commented below? Why do the docs say that OpenPrinter has to take a PRINTER_DEFAULTS byref, and when I pass it by ref, every thing breaks at runt time, like, I don't get a printer handle and OpenPrinter causes an Err.LastDllError of 5 (access denied). I think you either know the answer to this one or not. I don't want speculcation and supposition, just hard tested solutions, coz the web is littered with suggestions that dont seem to work. The fundamental problem seems to be that my code doesn't have the right security descriptior to use SetPrinter, even if I log on to my Windows 2003 server as an administrator. Thanks guys, in advance for your patience and efforts! ''' TEST CODE FOR CLASS - put this in a form or module Private Sub Test() Dim lPrinter As New APIPrinter Dim lName As String = lPrinter.DefaultPrinterName lPrinter.Open(lName) lPrinter.DuplexMode = APIPrinter.DuplexOption.LongEdge lPrinter.Close() End Sub ''' CODE FOR CLASS - put this in a spearate class VB file Imports System.Runtime.InteropServices Imports System.Text Public Class APIPrinter Implements IDisposable #Region "WinApi" #Region "Structures" Public Structure PRINTER_DEFAULTS Public pDatatype As String Public pDevMode As IntPtr Public DesiredAccess As Int32 End Structure Public Structure PRINTER_INFO_2 Public pServerName As String Public pPrinterName As String Public pShareName As String Public pPortName As String Public
"I think you either know the answer to this one or not. I don't want speculcation and supposition" hmmm... I'm not sure how to respond to that but, here goes. I built your software using vs.net 2003, just as it is listed, on my win2k3 server, as Administrator, I tested it against my HP LaserJet 4100 DTN (with Duplex Mode), I had no permission errors, nor any errors of any kind, but your software also doesn't set the duplex mode for it either. It does however, bring up the printer settings dialog box where I can set it to duplex.
-
"I think you either know the answer to this one or not. I don't want speculcation and supposition" hmmm... I'm not sure how to respond to that but, here goes. I built your software using vs.net 2003, just as it is listed, on my win2k3 server, as Administrator, I tested it against my HP LaserJet 4100 DTN (with Duplex Mode), I had no permission errors, nor any errors of any kind, but your software also doesn't set the duplex mode for it either. It does however, bring up the printer settings dialog box where I can set it to duplex.
Thank you so much for going to all that effort. However, if y ou find these two lines of kludge... mDeviceMode.dmOrientation = 2 mDeviceMode.dmDuplex = 2 You'll see that I do 'try' to set some properties, BUT, and this is where I have to thank you again. I didn't set the field mDeviceMode.dmFields, to tell the driver it needs to reset those two values, duplex and orientation. So you certainly helped me find a bug in my test case. I am not sure why I get the problem of Access Denied and you don't though. I wonder if its anything to do with the way we setup Win2k3 here. Win2k3 is my box and I guess that's subject to the SOE setup used at work. Perhaps I can do a fix and send you some more code to test, would that be ok. Again, thanks a bunch!:) Nursey
-
"I think you either know the answer to this one or not. I don't want speculcation and supposition" hmmm... I'm not sure how to respond to that but, here goes. I built your software using vs.net 2003, just as it is listed, on my win2k3 server, as Administrator, I tested it against my HP LaserJet 4100 DTN (with Duplex Mode), I had no permission errors, nor any errors of any kind, but your software also doesn't set the duplex mode for it either. It does however, bring up the printer settings dialog box where I can set it to duplex.
-
Thank you so much for going to all that effort. However, if y ou find these two lines of kludge... mDeviceMode.dmOrientation = 2 mDeviceMode.dmDuplex = 2 You'll see that I do 'try' to set some properties, BUT, and this is where I have to thank you again. I didn't set the field mDeviceMode.dmFields, to tell the driver it needs to reset those two values, duplex and orientation. So you certainly helped me find a bug in my test case. I am not sure why I get the problem of Access Denied and you don't though. I wonder if its anything to do with the way we setup Win2k3 here. Win2k3 is my box and I guess that's subject to the SOE setup used at work. Perhaps I can do a fix and send you some more code to test, would that be ok. Again, thanks a bunch!:) Nursey
Yes I will be Happy to test it again, also I Do happen to know or at least have a good probable "Idea" of why yours is failing with error 5. 1) OpenPrinter will not connect directly to a network print queue device or driver. 2) If your's is set that way and I suspect it is, (and it does fail with error 5, on mine here also, from a networked windows XP machine.) you need to create a local device that points to the network printer, then create a local print queue by performing the following steps: From a command prompt, type NET USE LPT2: \\\ /persistent:yes to map the local LPT device to the network printer. Add a local printer in the usual way (go to Start, Settings, Printers, and click Add Printer). Specify a local device you made above (LPT2), and configure the new printer. You Must have a local printer device for it to work at all. 3) It will not work at all on any LPT Device above LPT2.(At Least not on my equipment.) and I go up to LPT4 so it must have a problem with High Irq's also. Glad to help.
-
Can I just ask, did you actually step the code and look at all the dll last error codes? If so are you saying you didn't get any occurences of error 5 anywhere? Ta! Nursey
Yes I stepped through the code, And No I got No error 5's except in the situation of the XP machine on the network in previous message. Also, The last meassage was supposed to read: From a command prompt, type NET USE LPT2: \\\ /persistent:yes to map the local LPT device to the network printer.
-
Yes I will be Happy to test it again, also I Do happen to know or at least have a good probable "Idea" of why yours is failing with error 5. 1) OpenPrinter will not connect directly to a network print queue device or driver. 2) If your's is set that way and I suspect it is, (and it does fail with error 5, on mine here also, from a networked windows XP machine.) you need to create a local device that points to the network printer, then create a local print queue by performing the following steps: From a command prompt, type NET USE LPT2: \\\ /persistent:yes to map the local LPT device to the network printer. Add a local printer in the usual way (go to Start, Settings, Printers, and click Add Printer). Specify a local device you made above (LPT2), and configure the new printer. You Must have a local printer device for it to work at all. 3) It will not work at all on any LPT Device above LPT2.(At Least not on my equipment.) and I go up to LPT4 so it must have a problem with High Irq's also. Glad to help.
This is why I put things like "don't answer unless you know the answer", because every so often then it reduces the clutter and gives a guru a chance to get through! 8-) I will try and map the local port and give it another spin. I would never have found this information other than by your gratious efforts. Many thanks. Nursey
-
Yes I will be Happy to test it again, also I Do happen to know or at least have a good probable "Idea" of why yours is failing with error 5. 1) OpenPrinter will not connect directly to a network print queue device or driver. 2) If your's is set that way and I suspect it is, (and it does fail with error 5, on mine here also, from a networked windows XP machine.) you need to create a local device that points to the network printer, then create a local print queue by performing the following steps: From a command prompt, type NET USE LPT2: \\\ /persistent:yes to map the local LPT device to the network printer. Add a local printer in the usual way (go to Start, Settings, Printers, and click Add Printer). Specify a local device you made above (LPT2), and configure the new printer. You Must have a local printer device for it to work at all. 3) It will not work at all on any LPT Device above LPT2.(At Least not on my equipment.) and I go up to LPT4 so it must have a problem with High Irq's also. Glad to help.
I captured LPT2, having added a local printer using the same driver, but I get the same result...return code 5 when calling SetPrinter. You said >>OpenPrinter will not connect directly to a network print queue device or driver But everything works really well in terms of reading things about the printer, i.e. its name, location, capabilities etc. Any other thoughts? Could there be some kind of policy enforced by our network people that could affect this. Sorry I don't know too much about domains and server configs. My machine is a Win2K3 box, but it log into a corporate domain. I wotk for the ministry of justice in Perth, Australia, so I reckon you can guess that things are pretty well tightened up in terms of security policies and the like. It doens't change anything if I login into my box as an administrator. I normally log in to the domain and develop. Thanks again. Nursey
-
I captured LPT2, having added a local printer using the same driver, but I get the same result...return code 5 when calling SetPrinter. You said >>OpenPrinter will not connect directly to a network print queue device or driver But everything works really well in terms of reading things about the printer, i.e. its name, location, capabilities etc. Any other thoughts? Could there be some kind of policy enforced by our network people that could affect this. Sorry I don't know too much about domains and server configs. My machine is a Win2K3 box, but it log into a corporate domain. I wotk for the ministry of justice in Perth, Australia, so I reckon you can guess that things are pretty well tightened up in terms of security policies and the like. It doens't change anything if I login into my box as an administrator. I normally log in to the domain and develop. Thanks again. Nursey
-
Yes, I'm sure they would be Inforcing a group policy on the printers, and when you log into the domain the policy automaticly set's your computer also. Before I go on... Where is the physical printer at, your place or at work?
The printer is at my workplace, I just add printer, it's shared from an old server, I looked it up and added it. I can obviously print ok. I can set duplex printing from Word, and print in the normal way. I just have to be able to set duplex on and off from code for some special cases. BTW, would you rather email me to save time on here? chris.nurse@justice.wa.gov.au Thx. Nursey
-
The printer is at my workplace, I just add printer, it's shared from an old server, I looked it up and added it. I can obviously print ok. I can set duplex printing from Word, and print in the normal way. I just have to be able to set duplex on and off from code for some special cases. BTW, would you rather email me to save time on here? chris.nurse@justice.wa.gov.au Thx. Nursey