views:

354

answers:

2

I need to, preferably in C# - but c++ will do, find a way to filter the list of printers in the windows print dialog for any windows printing.

I have come across WinAPIOverride and have figured I am going to have to write my own dll which overrides the method to get the printers list, then filter it and return it. I would then have to inject the dll into all running processes.

Can anybody assist me with something that is already developed or perhaps an easier way of accomplishing this? The only way the list of printers comes out is from the API method call and I have even considered modifying the registry, but this will slow down the response of the print dialog box to the point that it would be annoying to the user.

+1  A: 

I don't think that (re)writing a DLL is the easiest method. Why not use WMI to retrieve the wanted information (printers in this case)?

The following code is for retrieving all the locally installed printers:
(code samples borrowed from here)

    ManagementScope objScope = new ManagementScope(ManagementPath.DefaultPath); //For the local Access
    objScope.Connect();

    SelectQuery selectQuery = new SelectQuery();
    selectQuery.QueryString = "Select * from win32_Printer";
    ManagementObjectSearcher MOS = new ManagementObjectSearcher(objScope, selectQuery);
    ManagementObjectCollection MOC = MOS.Get();
    foreach (ManagementObject mo in MOC) {
      listBox1.Items.Add(mo["Name"].ToString().ToUpper());
    }

To get the printers known accross a domain use this:

ConnectionOptions objConnection = new ConnectionOptions();
objConnection.Username = "USERNAME";
objConnection.Password = "PASSWORD";
objConnection.Authority = "ntlmdomain:DDI"; //Where DDI is the name of my domain
// Make sure the user you specified have enough permission to access the resource. 

ManagementScope objScope = new ManagementScope(@"\\10.0.0.4\root\cimv2",objConnection); //For the local Access
objScope.Connect();

SelectQuery selectQuery = new SelectQuery();
selectQuery.QueryString = "Select * from win32_Printer";
ManagementObjectSearcher MOS = new ManagementObjectSearcher(objScope, selectQuery);
ManagementObjectCollection MOC = MOS.Get();
foreach (ManagementObject mo in MOC) {
  listBox1.Items.Add(mo["Name"].ToString().ToUpper());
}

Of course, the list is not "filtered" as you would like as you didn't specify any criteria. But I'm sure you can manage from here on by yourself.

Sven
A: 

Thanks for the interesting code.

The idea is to apply a filtered printer list to the system as globally as possible without interfering with the user. This means the filtered list has to apply to the standard windows print dialogs unfortunately...

So your WMI code, albeit kind of cool, would not be appropriate. If I were building my own print dialogs, it could come in pretty handy ;)