Toon posts:

[C#.NET] Hoe kun je een printer receive-buffer uitlezen?

Pagina: 1
Acties:

Onderwerpen


  • Mastermind
  • Registratie: februari 2000
  • Laatst online: 20-09 20:22
Wij hebben etikettenprinters bij de lopende banden die etiketten op de producten printen met Zebra printers. Nu willen wij dat het niet mogelijk is een nieuwe printopdracht te geven, als de printerbuffer nog niet leeg is. Dit om te voorkomen dat er etiketten van de verkeerde productieorder op een productieorder komen.

Als er op Printen geklikt wordt, en de printbuffer nog niet leeg is, dan komt er een waarschuwing dat de printbuffer eerst leeggemaakt moet worden. Dit kan dan door op een knop "Printbuffer leegmaken" te drukken. Deze knop stuurt de ZPL-code "~JA" naar de printer waardoor de printbuffer leeggemaakt wordt, en de printer stopt met printen. Het leegmaken van de buffer heb ik succesvol getest.

Dit heb ik mogelijk gemaakt door het aanspreken van winspool.drv unmanaged code.
C#:
1
2
[DllImport("winspool.drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        private static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);

Dit is niet alle code, ook OpenPrinterA, ClosePrinter, StartDocPrinterA, EndDocPrinter, StartPagePrinter, en EndPagePrinter gebruik ik. Deze code wordt door enkele methods aangeroepen die de unmanaged code bruikbaar maken voor managed code.

Nu moet het gedeelte nog komen dat de receivebuffer uitgelezen kan worden, om te kijken of deze leeg is, of er nog nummers in staan. Dit kan met het ZPL-commando "~HS" en dan de number of formats in de receive buffer uitlezen.
Dus lijkt het mij dat je ook "ReadPrinter" kan doen, dus zoiets als:
C#:
1
2
3
[DllImport("winspool.drv", EntryPoint = "ReadPrinter", SetLastError = true, CharSet = CharSet.Unicode, 
            ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        private static extern bool ReadPrinter(IntPtr hPrinter, ref IntPtr pBytes, Int32 dwCount, ref Int32 dwNReadBytes);


Ik kan echter nergens documentatie over "ReadPrinter" vinden (de parameters in bovenstaand voorbeeld heb ik gegokt). Het gaat om een netwerkprinter. Is het uberhaupt wel mogelijk de receive buffer in de printer uit te lezen? Weet iemand hoe ik dit kan doen, of wat de parameters zijn die ReadPrinter in winspool.drv verwacht zijn?

  • MTWZZ
  • Registratie: mei 2000
  • Laatst online: 13-08 14:33

MTWZZ

One life, live it!

Ik heb zelf nog nooit direct tegen printers hoeven communiceren vanuit C#/C++ maar misschien heb je iets aan EnumJobs?

Nu met Land Rover Series 3 en Defender 90


  • Niemand_Anders
  • Registratie: juli 2006
  • Laatst online: 12-06 11:06

Niemand_Anders

Dat was ik niet..

Waarom introduceer je gewoon niet een printer service voor je eigen applicatie? Applicaties zouden bijvoorbeeld via de MessageQueue print opdrachten in de queue kunnen zetten en de printer service is degene welke de etiketten print. Omdat er maar 1 computer is welke kan printen, kunnen dus ook de opdrachten niet door elkaar gaan lopen.

If it isn't broken, fix it until it is..


  • Mastermind
  • Registratie: februari 2000
  • Laatst online: 20-09 20:22
Bedankt voor het meedenken. Zo te zien kun je met deze functie gegevens van een set van jobs voor een gespecificeerde printer uitlezen. Echter, de printjob is al verdwenen als de printer nog bezig is met printen. Deze job staat dan in de receivebuffer van de zebra.

Nu kun je volgens de ZPL (zebra printer language)-documentatie met het commando ~HS de host status opvragen, waarin ook de "number of formats in receive buffer" aangegeven is. Ik moet dus eigenlijk die string hebben die de zebra terugstuurt.

Wat ik merkwaardig vind is dat je met winspool WritePrinter inderdaad een string naar de printer kunt toesturen, die hij ook netjes verwerkt, maar ik nergens kan vinden hoe je een eventuele return-string kunt afvangen.
Heeft iemand hier ervaring mee, of weet hij toevallig waar ik hier documentatie over kan vinden?
Niemand_Anders schreef op maandag 08 november 2010 @ 08:47:
Waarom introduceer je gewoon niet een printer service voor je eigen applicatie? Applicaties zouden bijvoorbeeld via de MessageQueue print opdrachten in de queue kunnen zetten en de printer service is degene welke de etiketten print. Omdat er maar 1 computer is welke kan printen, kunnen dus ook de opdrachten niet door elkaar gaan lopen.
Dit is niet nodig, omdat elke terminal naar zijn eigen printer een printcommando stuurt. Er is dus maar 1 computer die de printer aan de productielijn aanstuurt.
Het probleem zit het hem in het volgende: Stel er wordt een printopdracht voor 500 etiketten gedaan, maar er komen maar 490 verpakkingen over de band, dan staan er nog 10 etiketten in de receivebuffer van de zebra. Als er dan een printopdracht voor de volgende batch met nieuwe etiketten gedaan wordt, dan is het theoretisch mogelijk dat die overgebleven 10 etiketten op de verkeerde batch komen. Nu wordt het wel goed gecontroleerd allemaal, en wordt de buffer handmatig gecleared na elke batch, maar we willen zoveel mogelijk fouten kunnen voorkomen.

[Voor 41% gewijzigd door Mastermind op 08-11-2010 09:02]


  • MTWZZ
  • Registratie: mei 2000
  • Laatst online: 13-08 14:33

MTWZZ

One life, live it!

Mastermind schreef op maandag 08 november 2010 @ 08:55:
Dit is niet nodig, omdat elke terminal naar zijn eigen printer een printcommando stuurt. Er is dus maar 1 computer die de printer aan de productielijn aanstuurt.
De abstractielaag die Niemand Anders voorstelt is dan nog zeker bruikbaar ook al zit er maar 1 client aan.
Je kunt op die manier zelf de controle houden over wat er naar de printer wordt gestuurd.

Nu met Land Rover Series 3 en Defender 90


  • Mastermind
  • Registratie: februari 2000
  • Laatst online: 20-09 20:22
Zou je willen verduidelijken hoe dit het probleem voorkomt dat er etiketten uitgeprint worden die reeds in de receive-buffer van de Zebra printer zelf staan?

  • MTWZZ
  • Registratie: mei 2000
  • Laatst online: 13-08 14:33

MTWZZ

One life, live it!

Mastermind schreef op maandag 08 november 2010 @ 10:19:
Zou je willen verduidelijken hoe dit het probleem voorkomt dat er etiketten uitgeprint worden die reeds in de receive-buffer van de Zebra printer zelf staan?
Ongeveer als volgt:

- batch 1 wordt klaargezet om te printen
- servicelaag maakt de printbuffer leeg
- servicelaag verstuurt de printopdracht
- batch 1 loopt en wordt geprint
- batch 2 wordt klaargezet om te printen
- servicelaag maakt de printbuffer leeg
- servicelaag verstuurt de printopdracht

zoiets dus.

Nu met Land Rover Series 3 en Defender 90


  • CMG
  • Registratie: februari 2002
  • Laatst online: 30-03 23:19
Mastermind schreef op maandag 08 november 2010 @ 08:55:
Wat ik merkwaardig vind is dat je met winspool WritePrinter inderdaad een string naar de printer kunt toesturen, die hij ook netjes verwerkt, maar ik nergens kan vinden hoe je een eventuele return-string kunt afvangen.
Heeft iemand hier ervaring mee, of weet hij toevallig waar ik hier documentatie over kan vinden?
Moet je niet gewoon ReadPrinter aan roepen? Het lijkt me precies zo te werken als bij Socket programming.
http://msdn.microsoft.com/en-us/library/dd162895(VS.85).aspx

Note This is a blocking or synchronous function and might not return immediately. How quickly this function returns depends on run-time factors such as network status, print server configuration, and printer driver implementation—factors that are difficult to predict when writing an application. Calling this function from a thread that manages interaction with the user interface could make the application appear to be unresponsive.

[Voor 33% gewijzigd door CMG op 08-11-2010 19:00]

NKCSS - Projects - YouTube - Twitch


  • Fish
  • Registratie: juli 2002
  • Niet online

Fish

How much is the fish

Waarom download je de hele bups niet als een grapic. zodra die eenmaal ingeladen is spuit die er met een noodtempo uit. dan kun je met hele kleine printjobjes (1 per product)toch snel je labels reproduceren. zodat je ook geen label overhoud

Iperf


  • Mastermind
  • Registratie: februari 2000
  • Laatst online: 20-09 20:22
CMG schreef op maandag 08 november 2010 @ 18:59:
[...]
Moet je niet gewoon ReadPrinter aan roepen? Het lijkt me precies zo te werken als bij Socket programming.
[...]
_/-\o_ Dat is wat ik zocht!! :D Ik ga 't meteen proberen. Nu weet ik zeker of het werkt of niet.

@MTWZZ: Bedankt voor de verduidelijking. Maar dit komt in principe op hetzelfde neer als de receive-buffer leegmaken als er op de "Print"-knop gedrukt wordt, en daarna direct de nieuwe printopdracht sturen. Dit was in principe het 2e voorstel, maar heeft als nadeel dat er per ongeluk op die knop gedrukt kan worden en er dan verkeerde etiketten uitrollen.
Pagina: 1


Nintendo Switch (OLED model) Apple iPhone 13 LG G1 Google Pixel 6 Call of Duty: Vanguard Samsung Galaxy S21 5G Apple iPad Pro (2021) 11" Wi-Fi, 8GB ram Nintendo Switch Lite

Tweakers vormt samen met Hardware Info, AutoTrack, Gaspedaal.nl, Nationale Vacaturebank, Intermediair en Independer DPG Online Services B.V.
Alle rechten voorbehouden © 1998 - 2021 Hosting door True

Tweakers maakt gebruik van cookies

Bij het bezoeken van het forum plaatst Tweakers alleen functionele en analytische cookies voor optimalisatie en analyse om de website-ervaring te verbeteren. Op het forum worden geen trackingcookies geplaatst. Voor het bekijken van video's en grafieken van derden vragen we je toestemming, we gebruiken daarvoor externe tooling die mogelijk cookies kunnen plaatsen.

Meer informatie vind je in ons cookiebeleid.

Sluiten

Forum cookie-instellingen

Bekijk de onderstaande instellingen en maak je keuze. Meer informatie vind je in ons cookiebeleid.

Functionele en analytische cookies

Deze cookies helpen de website zijn functies uit te voeren en zijn verplicht. Meer details

janee

    Cookies van derden

    Deze cookies kunnen geplaatst worden door derde partijen via ingesloten content en om de gebruikerservaring van de website te verbeteren. Meer details

    janee