[OpenJDK 2D-Dev] RFR: 8263311: Watch registry changes for remote printers update instead of polling
aivanov at openjdk.java.net
Sat Mar 13 12:02:06 UTC 2021
On Sat, 13 Mar 2021 00:18:25 GMT, Sergey Bylokhov <serb at openjdk.org> wrote:
> Any idea why RegistryValueChange was rejected as a solution?
I've no idea. I read that comment, it's exactly the comment that was in the code above `RemotePrinterChangeListener` class in `PrintServiceLookupProvider.java`.
> 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).
It's very vague. I don't know what it really means. Neither do I know if a prototype was even tried.
If fact, this comment cites portions of the article [How to listen for Printer Connections?](https://docs.microsoft.com/en-gb/archive/blogs/hmahrt/how-to-listen-for-printer-connections). The link to this article is in the description of [JDK-8153732](https://bugs.openjdk.java.net/browse/JDK-8153732).
The article discusses the subject with WMI and WQL. This is what it says:
> There is no equivalent to `FindFirstPrinterChangeNotification`, which listens for new/changed Printer Connections – and a polling mechanism was not an option. However, there is another way, using WMI.
Note: _polling mechanism was not an option_. Yet it is what was implemented in Java.
Then the articles describes the steps needed to monitor for printer changes.
Close to the end, there's the quoted sentence:
> Unfortunately, we cannot use the `RegistryValueChangeEvent` (because the scope of the query would be too big (we’d receive an error message), so we can only know **when** something changed below the `Printers\Connections` key, but not **what**. This is why we have to rely on **`EnumPrinters`**.
This statement is a bit confusing. It says they cannot use `RegistryValueChangeEvent` (it's not a Windows API function, it's another WMI class) but the WQL query above _uses it_.
I interpret the following statement this way: Registry notifications do not provide information on **what** changed under `Printers\Connections`, only that a change occurred. So `EnumPrinters` is used to enumerate the remote printers and update the stored list of printers after the change to the registry occurs.
I used this article as the inspiration and the implementation I'm proposing in this PR is purely based on this article. Yet I'm using Windows API function [RegNotifyChangeKeyValue](https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regnotifychangekeyvalue) to watch for registry updates and to get notified as soon as a change under `HKCU\Printers\Connections` occurs. Then the list of printers is updated by the `refreshServices` upcall into Java which refreshes both _local_ and _remote_ printers.
More information about the 2d-dev