是否有可能将虚拟打印机与物理打印机不同?

发布于 2024-08-23 00:24:09 字数 107 浏览 3 评论 0原文

我有 WinXP 中所有可用打印机的列表。我需要代码(最好是 .NET)来从此列表中过滤掉所有虚拟打印机。可以做吗?我分析了 Win32_Printer wmi 类的所有属性,但找不到任何合适的属性。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

痞味浪人 2024-08-30 00:24:09

我认为这是不可能的,至少可以肯定地说。虚拟打印机的全部意义在于尽可能地模仿真实打印机,因此您可以识别的任何差异基本上都只是虚拟打印机中的错误。

也就是说,您可以根据PortName 进行一些猜测。仅举几个示例,包含 IP 地址或以“USB”开头的 PortName 可能指的是物理连接。

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.

千と千尋 2024-08-30 00:24:09

我知道这是一个老问题,但这个答案可能对遇到同样问题的人有帮助。

如果我对“虚拟打印机”的理解是正确的。您可以检查 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);
}

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);
}
九公里浅绿 2024-08-30 00:24:09

我有一个收集硬件信息的项目
在测试 HiTech 答案后,我看到一些与 LPT 连接的旧打印机(例如 Windows 10 上的 HP 2014)有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 连接的打印机。我对其他端口(例如某些传真端口)一无所知。

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).

尽揽少女心 2024-08-30 00:24:09

到目前为止我发现属性 MaxCopies (来自 Win32_Printer wmi 类)似乎是一个合适的区分器。

我调查的所有虚拟打印机(包括传真)都将此属性设置为 1。这是合理的:制作多份副本对它们来说是没有意义的。相比之下,所有物理打印机驱动程序都可以打印多份副本,并且具有 999 或 9999 的此属性。

对于默认打印机,最简单的辨别方法是

var ps = new System.Drawing.Printing.PrinterSettings();
if (ps?.MaximumCopies > 1) {
    // physical printer
}

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文