2

Our web application has a flow where in the on click of print button on a page, raw data from the server is printed on the client's machine on a user selected printer (Zebra label printer). Following sequence of interactions are involved between the browser and the server:
1)User clicks on print on a page
2)Server sends back an applet
3)This applet makes url connection to the server to retrieve the print data
4)The applet then looks up the list of printers installed on the client's machine and shows the printer selection dialog. All the printer lookup is done using javax.print
5)Once the user selects the label printer, the applet creates a print job and sends it to the selected printer. The label gets printed

Now since google has removed NPAPI from chrome, we were looking at what alternatives do we have to get the same functionality on chrome and specifically on windows. Initially going though Google native client docs, we thought that we could realize the above use case using PNACL. Following code is from MSDN which is routine for printing raw data to the default printer using winspool.h

BOOL RawDataToPrinter(LPBYTE lpData, DWORD dwCount) {

   HANDLE       hPrinter;
   DOC_INFO_1       DocInfo;
   DWORD      dwJob;
   DWORD      dwBytesWritten;

               TCHAR result[ MAX_PATH ] = {'\0'};
                            DWORD length = MAX_PATH;
                            GetDefaultPrinter( result, &length );


    // Need a handle to the printer.
    if( ! OpenPrinter(result, &hPrinter, NULL ) )
      return FALSE;

    // Fill in the structure with info about this "document."
    DocInfo.pDocName = L"Demo Page";
    DocInfo.pOutputFile = NULL;
    DocInfo.pDatatype = L"RAW";
    // Inform the spooler the document is beginning.
    if( (dwJob = StartDocPrinter( hPrinter, 1, (BYTE *)&DocInfo )) == 0 )
    {
      ClosePrinter( hPrinter );
      return FALSE;
    }
    // Start a page.
    if( ! StartPagePrinter( hPrinter ) )
    {
      EndDocPrinter( hPrinter );
      ClosePrinter( hPrinter );
      return FALSE;
    }
    // Send the data to the printer.
    if( !WritePrinter( hPrinter, lpData, dwCount, &dwBytesWritten ) )
    {
      EndPagePrinter( hPrinter );
      EndDocPrinter( hPrinter );
      ClosePrinter( hPrinter );
      return FALSE;
    }
    // End the page.
    if( ! EndPagePrinter( hPrinter ) )
    {
      EndDocPrinter( hPrinter );
      ClosePrinter( hPrinter );
      return FALSE;
    }
    // Inform the spooler that the document is ending.
    if( ! EndDocPrinter( hPrinter ) )
    {
      ClosePrinter( hPrinter );
      return FALSE;
    }
    // Tidy up the printer handle.
    ClosePrinter( hPrinter );
    // Check to see if correct number of bytes were written.
    if( dwBytesWritten != dwCount )
      return FALSE;
    return TRUE;
  }

Initially we thought that we would be able to call the above routine from a pepper plugin. The javascript on page would retreive the label data and pass it to the native client instance, and this would call the RawDataToPrinter(..) routine.
However from what we understood from the forums out here is that Native client won't be able to access/lookup the printers and spool the raw data to the selected printer.it wont allow you to call anything outside the api ports that they provide
Is this understanding correct? If yes then is there any alternative to realize the above mentioned use case on chrome? if no and the above is possible, are there any available ports which allow access to printers installed on client's machine and allow us to print the data to the selected printer?

Jitesh
  • 51
  • 1
  • 5
  • how did you solove this problem? i have similar requirement. Thanks! – Sibi John Dec 19 '17 at 06:59
  • we solved this using chrome extension runtime api. https://developer.chrome.com/apps/nativeMessaging – Jitesh Dec 21 '17 at 18:26
  • we solved this using chrome extension runtime api. https://developer.chrome.com/apps/nativeMessaging. We developed a chrome extension that would act as a bridge between our application web page and the native application(developed using VC++) . The webpage would connect to the chrome extension send the print job information as json to the extension. The extension in turn would connect to the native exe application and pass on the json data it recieved from the web page. the native exe application would be responsible for reading the json data from the standard i/O and then lookup the printer – Jitesh Dec 21 '17 at 18:33
  • https://chromium.googlesource.com/chromium/src/+/master/chrome/common/extensions/docs/examples/api/nativeMessaging – Jitesh Dec 21 '17 at 18:34
  • Thanks! We are going to do something similar but with JNLP. – Sibi John Jan 03 '18 at 05:24
  • we did try this using JNLP, since JNLP would be running as a seperate process outside the browser, we thought we could try this apporach, but we soon faced a problem. When the JNLP application is accessed, chrome simply downloads the jar and puts it in the downloads directory. It no longer triggers the application (using javaws). So this would mean that the user would have to click on the downloaded jws application to trigger "java web start". This was not something which was correct from a usability point of view. It was then that we went for the chrome extension + native exe solution – Jitesh Jan 21 '18 at 10:23
  • I guess it won't help now but when we faced the same problem we were able to overcome it by changing the protocol on the jnlp download link from http to jnlp. Something like jnlp://. That solves the problem for us. Now we are stuck at code signing. Java doesn't allow such file to run if they aren't code signed :D Once it is code signed, it works beautifully though :) – Sibi John Jan 22 '18 at 06:22

1 Answers1

0

The short answer is no, this is not possible from Native Client, because its security sandbox is designed to keep web sites from using system APIs. You can install a native Windows application on the client and use Native Messaging with Javascript to communicate with it, passing it whatever data you want from your web page.

Derek
  • 783
  • 1
  • 4
  • 8
  • Thanks for your answer Derek. However i feel this would defeat the purpose of a web application, when we ask users to install more and more software, for achieving the application functionality. We would try out Native Messaging. Another option would be to have IE-tab extension for chrome. Thanks again – Jitesh Mar 17 '16 at 09:15