< prev index next >

src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java

Print this page

        

@@ -315,37 +315,51 @@
             defaultPrintService = new Win32PrintService(defaultPrinter);
         }
         return defaultPrintService;
     }
 
+    /* Windows provides *PrinterChangeNotification* functions that provides 
+       information about printer status changes of the local printers but not
+       network printers.
+       Alternatively, Windows provides a way thro' which one can get the
+       network printer status changes by using WMI, RegistryKeyChange combination,
+       which is a slightly complex mechanism. 
+       The Windows WMI offers an async and sync method to read thro' registry 
+       via the WQL query. The async method is considered dangerous as it leaves 
+       open a channel until we close it. But the async method has the advantage of 
+       being notified of a change in registry by calling callback without polling for it.
+       The sync method uses the polling mechanism to notify.
+       RegistryValueChange cannot be used in combination with WMI to get registry
+       value change notification because of an error that may be generated because the
+       scope of the query would be too big to handle(at times).
+       Hence an alternative mechanism is choosen via the EnumPrinters by polling for the
+       count of printer status changes(add\remove) and based on it update the printers
+       list.
+    */
     class PrinterChangeListener implements Runnable {
-        long chgObj;
+        long prevRemotePrintersCount = 0;
+
         PrinterChangeListener() {
-            chgObj = notifyFirstPrinterChange(null);
+            prevRemotePrintersCount = GetRemotePrintersCount();
         }
 
         @Override
         public void run() {
-            if (chgObj != -1) {
-                while (true) {
-                    // wait for configuration to change
-                    if (notifyPrinterChange(chgObj) != 0) {
-                        try {
+            while(true) {
+                long currentRemotePrintersCount = GetRemotePrintersCount();
+                if(prevRemotePrintersCount != currentRemotePrintersCount) {
+
+                    // updated the printers data
+                    // printers list now contains both local and network printer data
                             refreshServices();
-                        } catch (SecurityException se) {
-                            break;
-                        }
-                    } else {
-                        notifyClosePrinterChange(chgObj);
-                        break;
-                    }
+
+                    // store the current data for next comparison
+                    prevRemotePrintersCount = currentRemotePrintersCount;
                 }
             }
         }
     }
 
     private native String getDefaultPrinterName();
     private native String[] getAllPrinterNames();
-    private native long notifyFirstPrinterChange(String printer);
-    private native void notifyClosePrinterChange(long chgObj);
-    private native int notifyPrinterChange(long chgObj);
+    private native long GetRemotePrintersCount();
 }
< prev index next >