Is there a possibility to differ virtual printer from physical one?
Asked Answered
E

4

16

I have a list of all printers available in WinXP. I need the code (ideally .NET) to filter out all the virtual printers from this list. Is it possible to do? I analyzed all the properties of Win32_Printer wmi class but can't see any suitable one.

Erdmann answered 24/2, 2010 at 16:49 Comment(0)
P
6

I don't think it's possible, at least with any certainty. The whole point of a virtual printer is to imitate a real one as closely as possible, so any differences you can identify are basically just bugs in the virtual printer.

That said, you can make some guesses based on the PortName. Just for a couple of examples, a PortName that includes an IP address or starts with "USB" is likely to refer to a physical connection.

Phytobiology answered 24/2, 2010 at 20:20 Comment(1)
Great answer, Jerry. Pulled several examples and found it is not possible. Regarding your guessing suggestion there's one caveat: faxes. One of our PC's has a direct-connect fax/printer, with each one listed as a separate printer (e.g., HPFAX1, USB001). However, the built-in MS Fax is listed as SHRFAX. I imagine other virtual faxes will be listed similarly. Also, even finding this info without using WMI may not be possible, from the research I've done.Hubie
I
5

I know this is an old question but this answer may be helpful to someone with the same problem.

If my understanding of a "virtual printer" is correct. You could check the WMI property "PrintProcessor" and ignore "winprint". To my knowledge this will ignore all of Windows 7 software based printer options. Here is some sample code to demonstrate that. Returns the printer name.

using System.Management;

try
{
    ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_Printer");

    foreach (ManagementObject obj in searcher.Get())
    {
        if(obj != null)
        {
            if(obj["PrintProcessor"].ToString().ToUpper() != "WINPRINT")
            {
                Console.WriteLine(obj["Name"]);
            }
        }
    }
}
catch (ManagementException e)
{
    MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
}
Introduction answered 14/11, 2014 at 20:45 Comment(0)
F
2

I have a project to collect hardware information and after testing the HiTech answer I see some of old printers (for example HP 2014 on Windows 10) that connect with LPT have WINPRINT PrintProcessor and these printers are connected diectly to computer and not virtual. So I combined the Local, Network and PortName properties (on offer Jerry Coffin answer) to find more accurate local and network printers(not virtual printers).

using System.Management;

class Printer
{
    public string Name { get; set; }
    public string Status { get; set; }
    public bool Default { get; set; }
    public bool Local { get; set; }  
    public bool Network { get; set; }        
    public string PrintProcessor { get; set; }
    public string PortName { get; set; }
}

private void btnGetPrinters_Click(object sender, EventArgs e)
{          
    List<Printer> printers = new List<Models.Printer>();
    var query = new ManagementObjectSearcher("SELECT * from Win32_Printer");
    foreach (var item in query.Get())
    {
        string portName = item["PortName"].ToString().ToUpper();
        if (((bool)item["Local"]==true || (bool)item["Network"]==true) &&  (portName.StartsWith("USB") || portName.StartsWith("LPT")))
        {
            Printer p = new Models.Printer();
            p.Name = (string)item.GetPropertyValue("Name");
            p.Status = (string)item.GetPropertyValue("Status");
            p.Default = (bool)item.GetPropertyValue("Default");
            p.Local = (bool)item.GetPropertyValue("Local");
            p.Network = (bool)item.GetPropertyValue("Network");                    
            p.PrintProcessor = (string)item.GetPropertyValue("PrintProcessor");
            p.PortName = (string)item.GetPropertyValue("PortName");
            printers.Add(p);
        }
    }

    // Show on GridView 
    gv.DataSource = printers;
}

This method works for the printers that connect with USB and LPT. I don't have any idea about other ports (like some faxes port).

Forras answered 3/10, 2019 at 6:18 Comment(0)
U
1

What I found so far is that the property MaxCopies (from Win32_Printer wmi class) seems to be a suitable differentiator.

All the virtual printers I surveyed (including Fax) have this property set to 1. This is reasonable: making multiple copies is non-sensical for them. In contrast, all physical printer drivers can print multiple copies, and have this property at 999 or 9999.

For the default printer, the easiest way to tell is

var ps = new System.Drawing.Printing.PrinterSettings();
if (ps?.MaximumCopies > 1) {
    // physical printer
}
Upgrowth answered 10/8, 2023 at 6:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.