Hi Everyone,
-- Happy Holidays! I'm using CwPrinterPrompter (inspect CwPrinterPrompter new and you can see the list) to prompt the user to select a printer. In the development environment it finds all the printers but in runtime the list is short. I'm 99% sure this was working. My guess is a missing or more likely old DLL. They all seem find but there are so many it is easy to miss something. Can anyone point me in the right direction? Lou You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
Hi Again,
-- Playing around some more during runtime I have seen that the first time I open the printer list it is short, the second time it is complete. If I restart the program, sometimes the first time I open the printer list it is short, sometimes it isn't. This is very odd. It probably means it is not a missing or old DLL. Any ideas? Lou On Friday, December 23, 2016 at 10:43:57 AM UTC-5, Louis LaBrunda wrote:
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
I see what you mean by "CwPrinterPrompter new" seems to know about all the printers in its displayInfo instVar. I didn't know about that before. My applications had always asked for the list of printers via "CgWinPrinterServer allPrinterScreenInfos." and I don't remember a problem with a shortened list.
-- You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
In reply to this post by Louis LaBrunda
I am also trying to get access to my printers from within Smalltalk. However, I seem to be having worse results than anybody else seems to be reporting. When I try to get the list of printers via "CgWinPrinterServer allPrinterScreenInfos" like Wayne did, my list is not only shortened; it always comes back completely empty. Now, I put some Transcript show messages in the CgPrinterScreenInfo class>>#driverName:deviceName:outputMedium: method that gets called inside the loop once for each printer detected. Basically, the show messages are just to list the values of the arguments coming in to the method. Here is an example of what I get: driverName: winspool deviceName: WebEx Document Loader outputMedium: WebEx Document Loader Port driverName: winspool deviceName: Send To OneNote 2013 outputMedium: nul: driverName: winspool deviceName: PDF Printer outputMedium: NVP7: driverName: winspool deviceName: Microsoft XPS Document Writer outputMedium: XPSPort: driverName: winspool deviceName: LEADTOOLS 19 PrintToPACS 64-bit outputMedium: LEADTOOLS 19 PrintToPACS 64-bit driverName: winspool deviceName: LEADTOOLS 19 PrintToPACS 32-bit outputMedium: LEADTOOLS 19 PrintToPACS 32-bit driverName: winspool deviceName: outputMedium: driverName: winspool deviceName: outputMedium: driverName: winspool deviceName: outputMedium: driverName: winspool deviceName: outputMedium: driverName: winspool deviceName: outputMedium: driverName: winspool deviceName: ready destroyed outputMedium: in children tree of Form driverName: winspool deviceName: outputMedium: Í You can see that it detected 13 printers but by the time it gets half way through, it stops being able to get the device name or output medium from any of the remaining printers. Of course, the actual printers I am looking for are in that second half. And, in no case is it ever able to actually initialize the printer so it can get added to the collection of "updatedPrinters". Repeated attempts yield similar results. Anybody have any thoughts on why this is not working? I thought it might have something to do with this driver name of "winspool". I am not familiar with any of the driver names so I don't know if I should be using that or something different. Joel You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
CgWinPrinterServer allPrinterScreenInfos is wrong i think. Look older editions for this method, you will find changes at handling updatedPrinters/currentPrinters in the method from
info := currentPrinters at: longName ifAbsent: [self createPrinterScreenInfo: driverName deviceName: deviceName outputMedium: medium]. info notNil ifTrue: [updatedPrinters at: longName put: info]. to outputMedium: printerInfo pPortName asString) ifNotNil: [:printerScreenInfo | updatedPrinters at: (printerScreenInfo deviceName, ',winspool,', printerScreenInfo outputMedium) "$NON-NLS$" put: printerScreenInfo]. this will not work correctly. I have make a copy to my own method and changed back the older behavior, my method looks like: allLevel2PrinterScreenInfos: aDict "Answer a dictionary whose keys are the three part concatenated names for all available printer servers in the following order: deviceName, driverName, and outputMedium (each of the parts is separated by the comma ($,) character), and whose values are instance of CgPrinterScreenInfo." | buf resultSize numBuffers res bufSize numberPrinters printerInfo updatedPrinters level s flag currentPrinters | updatedPrinters := aDict. level := 2. flag := PrinterEnumLocal | PrinterEnumConnections "| PrinterEnumNetwork | PrinterEnumName". s := Null "'Print Provider!Domain'". currentPrinters := self printerScreenInfo. OS enumPrinters: flag name: s level: level pPrinterEnum: Null cbBuf: 0 "Call to get the buffer size" pcbNeeded: (resultSize := ByteArray new: 4) pcReturned: (numBuffers := ByteArray new: 4). bufSize := resultSize int32At: 0. res := OS enumPrinters: flag name: s level: level pPrinterEnum: (buf := ByteArray new: bufSize) cbBuf: bufSize pcbNeeded: resultSize pcReturned: numBuffers. res ifFalse: [^updatedPrinters]. numberPrinters := numBuffers int32At: 0. printerInfo := OSPrinterInfo2 reference: buf. 1 to: numberPrinters do: [:indx | | info | " longName := printerInfo pPrinterName asString, ',winspool,', printerInfo pPortName asString." info := self createPrinterScreenInfo: 'winspool'"@CMNO" deviceName: printerInfo pPrinterName asString outputMedium: printerInfo pPortName asString. info notNil:[info := currentPrinters at: info deviceName, ',winspool,', info outputMedium ifAbsent:[info]. updatedPrinters at: info deviceName, ',winspool,', info outputMedium put: info]. printerInfo increment]. self printerScreenInfo: updatedPrinters. ^updatedPrinters I call this method with an empty Dictionary. To CwPrinterPrompter I have written month ago here. This class is absolutly bad implemented, i have written my own class. Am Donnerstag, 19. Januar 2017 19:48:09 UTC+1 schrieb Joel Zecher:
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
Hi Ralf,
-- Thanks for your work on this. I am away from this project for the moment. If Instantiations hasn't fixed this by the time I get back to the project, I would be interested in seeing your replacement class if you are willing to share. Lou On Friday, January 27, 2017 at 8:00:33 AM UTC-5, Ralf wrote: CgWinPrinterServer allPrinterScreenInfos is wrong i think. Look older editions for this method, you will find changes at handling updatedPrinters/ You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
In reply to this post by Instantiations mailing list
Awesome Ralf. Thank you very much for the post. Unfortunately, I don't have any versions of the class older than V8.0.0 so I can't look at the older implementations as you suggest. I am assuming that is why I don't see an implementation of #createPrinterScreenInfo:deviceName:outputMedium: which you reference in your code. Could you please post the implementation of that method so I can give this a try? Again, my thanks. Joel You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
In reply to this post by Louis LaBrunda
Hi All,
-- I have had occasion to look into this again. I don't think the problem has anything to do with DLLs. Also, I don't think it is the same problem Ralf talks about. The changes Ralf talks about are after the code that gets the list from Windows. It is this list from Windows that is missing some of the printers. Repeated calls get differing numbers of printers returned from Windows. Subsequent calls sometimes get more printers, sometimes less. I haven't looked into what might be up with Windows but I don't think the current VS Smalltalk version 8.6.3 is the problem. Lou On Friday, December 23, 2016 at 10:43:57 AM UTC-5, Louis LaBrunda wrote:
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
In reply to this post by Louis LaBrunda
Louis:
-- I have a new case open with Instantiations on what sure seems to be related - INST62448. My impression is that the list of printers (from #allPrinterScreenInfos) can increase or decrease for no apparent reason, and I also think it's happened more since we upgraded from 8.5.2 to 8.6.3. Do you have any experience like the latter? You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
HI Wayne,
-- It sounds like the same problem. I think there is more than one path through Smalltalk code to obtain a list of printers, so that may account for why the problem may look a little different. My guess is the list of printers is obtained from windows and that for whatever reason that request doesn't always answer the full list. When I try this in the development environment, if I'm remembering correctly, I alway get the full list, that may just be luck. But when the code is run in a packaged image, partial list show up. If this turns out to be a windows problem, I can't think of much that could be done to circumvent it. Please keep us informed. Lou On Friday, July 21, 2017 at 5:20:32 PM UTC-4, Wayne Johnston wrote:
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
Hi Lou, Thanks to Wayne finding a repeatable test case for this issue, we have been able to find a solution to his problem. What we found is that the cache of printer info created by Windows in external memory has a rather short lifespan and can be overwritten by other window events taking place during the call. The solution is to gather all the necessary printer info from the cache as quickly as possible (see new critical block in method below), then iterate over the printers to create the CgPrinterScreenInfo instances. The following version of the method CgWinPrinterServer class >>#allPrinterScreenInfos will be released in the upcoming 9.0 release. You should be able to use it/adapt it to older versions as well: allPrinterScreenInfos "Answer a dictionary whose keys are the three part concatenated names for all available printer servers in the following order: deviceName, driverName, and outputMedium (each of the parts is separated by the comma ($,) character), and whose values are instance of CgPrinterScreenInfo." | printerNames printerPortNames resultSize numBuffers bufSize numberPrinters updatedPrinters | updatedPrinters := Dictionary new. OS enumPrinters: PrinterEnumLocal | PrinterEnumConnections name: Null level: 2 pPrinterEnum: Null cbBuf: 0 "Call to get the buffer size" pcbNeeded: (resultSize := ByteArray new: System vmPointerSize) pcReturned: (numBuffers := ByteArray new: System vmPointerSize). bufSize := resultSize uint32At: 0. [ | buf res printerInfo | res := OS enumPrinters: PrinterEnumLocal | PrinterEnumConnections name: Null level: 2 pPrinterEnum: (buf := ByteArray new: bufSize) cbBuf: bufSize pcbNeeded: resultSize pcReturned: numBuffers. res ifFalse: [ ^updatedPrinters ]. numberPrinters := numBuffers uint32At: 0. printerInfo := OSPrinterInfo2 reference: buf. " Pull the printer names and associated port names from OS memory before making other calls which may clobber the OS memory. case #62448" printerNames := Array new: numberPrinters. printerPortNames := Array new: numberPrinters. 1 to: numberPrinters do: [ :indx | printerNames at: indx put: printerInfo pPrinterName asString. printerPortNames at: indx put: printerInfo pPortName asString. printerInfo increment ] ] critical. 1 to: numberPrinters do: [:indx | (CgPrinterScreenInfo driverName: 'winspool' "$NON-NLS$" deviceName: (printerNames at: indx) outputMedium: (printerPortNames at: indx)) ifNotNil: ([:printerScreenInfo | updatedPrinters at: (printerScreenInfo deviceName, ',winspool,', printerScreenInfo outputMedium) "$NON-NLS$" put: printerScreenInfo] ifNil: [ Transcript cr; show: 'Printer named ',(printerNames at: indx), ' not found']) ]. self printerScreenInfo: updatedPrinters. ^updatedPrinters Bob On Saturday, July 22, 2017 at 9:06:19 AM UTC-4, Louis LaBrunda wrote:
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
In reply to this post by Louis LaBrunda
Hi Bob,
-- Great news. Thanks to you and everyone for working on this. Lou On Friday, December 23, 2016 at 10:43:57 AM UTC-5, Louis LaBrunda wrote:
You received this message because you are subscribed to the Google Groups "VA Smalltalk" group. To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email]. To post to this group, send email to [hidden email]. Visit this group at https://groups.google.com/group/va-smalltalk. For more options, visit https://groups.google.com/d/optout. |
Free forum by Nabble | Edit this page |