The other day, a customer wanted to listen (in C++) for newly added printers. He was trying to use FindFirstPrinterChangeNotification but was never notified.
It turned out that he was adding network printers, which belonged to a different print server (effectively creating a “Printer Connection”) and that FindFirstPrinterChangeNotification only works for printers belonging to the local print server (i.e. to the local machine):
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.
First of all, here is an overview of the necessary steps. I will explain the why and the how in more detail later.
Using the function EnumPrinters, supplying the PRINTER_ENUM_CONNECTIONS constant, we can get a list of all currently connected printers and their details.
Please refer to the following article to see how to get the SID of the currently logged in user: Getting the Logon SID in C++
The following article describes how to receive WMI event notifications: Example: Receiving Event Notifications Through WMI
By using the RegistryKeyChangeEvent class we can apply this to our problem. For each Printer Connection, a new registry key is created below HKEY_CURRENT_USER\Printers\Connections. However, due to the following limitation we cannot use this path, but have to use HKEY_USERS\<SID>\Printers\Connetionsinstead:
The WQL query to use in this case would look like this:
"SELECT * FROM RegistryKeyChangeEvent WHERE KeyPath='<SID>\\\\Printers\\\\Connections' AND Hive='HKEY_USERS'"
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.
I hope this information helps you to implement your own notification mechanism for Printer Connections.