Есть ли возможность отличать виртуальный принтер от физического?

У меня есть список всех принтеров, доступных в WinXP. Мне нужен код (в идеале .NET), чтобы отфильтровать все виртуальные принтеры из этого списка. Возможно ли это сделать? Я проанализировал все свойства WinI-класса Win32_Printer, но не нашел подходящего.

Ответ 1

Я не думаю, что это возможно, по крайней мере с какой-либо определенностью. Вся суть виртуального принтера заключается в том, чтобы максимально точно имитировать реальный, поэтому любые различия, которые вы можете идентифицировать, в основном являются просто ошибками в виртуальном принтере.

Тем не менее, вы можете сделать некоторые догадки на основе PortName. Только для нескольких примеров, PortName, который включает в себя IP-адрес или начинается с "USB", скорее всего, относится к физическому соединению.

Ответ 2

Я знаю, что это старый вопрос, но этот ответ может быть полезен кому-то с той же проблемой.

Если мое понимание "виртуального принтера" верное. Вы можете проверить свойство WMI "PrintProcessor" и игнорировать "winprint". Насколько мне известно, это игнорирует все параметры принтера на базе Windows 7. Вот пример кода, чтобы продемонстрировать это. Возвращает имя принтера.

        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);
        }

Ответ 3

У меня есть проект для сбора информации об оборудовании и после тестирования ответа HiTech я вижу, что некоторые из старых принтеров (например, HP 2014 в Windows 10), которые соединяются с LPT, имеют WINPRINT PrintProcessor, и эти принтеры подключаются напрямую к компьютеру, а не виртуально. Поэтому я объединил свойства Local, Network и PortName (в предложении Jerry Coffin), чтобы найти более точные локальные и сетевые принтеры (не виртуальные принтеры).

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;
}

Этот метод работает для принтеров, которые подключаются через USB и LPT. Я не имею никакого представления о других портах (например, о некоторых портах факсов).