使用 EnableBIDI = true 检索打印机的 Linq 语句

发布于 2024-10-29 21:35:51 字数 1525 浏览 1 评论 0原文

对于 Linq 大师来说,这应该是一件容易的事。

我想检索用户可用的所有物理打印机。据我所知,没有任何可以查询的属性/设置可以告诉您打印机是物理打印机还是虚拟打印机。但已经有一个关于该主题的问题: 是虚拟打印机与物理打印机有可能不同吗?

我正在使用一种可靠的方式来查看它是否是虚拟打印机,然后检查“EnableBIDI”属性是否设置为 true。

 ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
 ManagementObjectCollection coll = searcher.Get();
 var installedPhysicalPrinters = new List<string>();


        var scratch = from ...

结果应该是installedPhysicalPrinters 包含已安装打印机名称的列表。

我到目前为止

        foreach (ManagementObject printer in coll)
        {

            var validPrinter = (from PropertyData p in printer.Properties
                                from ManagementObject pr in coll
                                where p.Name == "EnableBIDI" && (bool) p.Value == true
                                select p).FirstOrDefault();

            if (validPrinter != null)
            {

                installedPrinters.Add(validPrinter.Value.ToString());

                // this is just to see the properties
                foreach (PropertyData property in printer.Properties)
                {

                    lstMessages.Items.Add(string.Format("{0}: {1}", property.Name, property.Value));


                } 
            }


        }

显然这是错误的,我最终在列表中得到了“真实”值的列表,而不是打印机名称。

使用嵌套 foreaches 很容易解决,但那是 2004 年的事了......

This should be an easy one for Linq guru's.

I wanna retrieve all the physical printers that are available to a user. As far as I can tell there is no property/setting that you can query which tells you whether a printer is a physical of a virtual one. But there's already a question about that topic : Is there a possibility to differ virtual printer from physical one?

I'm using a reliable-ish way to see if it's a virtual one, and I check whether the "EnableBIDI" property is set to true.

 ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
 ManagementObjectCollection coll = searcher.Get();
 var installedPhysicalPrinters = new List<string>();


        var scratch = from ...

The result should be that the installedPhysicalPrinters contains a list of installedprinter names.

I got this far

        foreach (ManagementObject printer in coll)
        {

            var validPrinter = (from PropertyData p in printer.Properties
                                from ManagementObject pr in coll
                                where p.Name == "EnableBIDI" && (bool) p.Value == true
                                select p).FirstOrDefault();

            if (validPrinter != null)
            {

                installedPrinters.Add(validPrinter.Value.ToString());

                // this is just to see the properties
                foreach (PropertyData property in printer.Properties)
                {

                    lstMessages.Items.Add(string.Format("{0}: {1}", property.Name, property.Value));


                } 
            }


        }

Obviously this is wrong, and I end up with a list of "true" values in the list, instead of the printer names.

Using nested for eaches it's easy to solve, but that's sooo 2004...

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

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

发布评论

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

评论(1

好多鱼好多余 2024-11-05 21:35:51

结合 LINQ 和 System.Management 的问题在于,后者使用较旧的非泛型容器(如 ManagementObjectCollection),您不能直接将其与 LINQ 一起使用,因为它使用非泛型 IEnumerable 接口。

幸运的是,您可以解决这个问题,如下例所示:

static void Main(string[] args)
{
    Func<PropertyData, bool> indicatesPhysical = property => property.Name == "EnableBIDI"; // && (bool) property.Value;
    Func<ManagementBaseObject, bool> isPhysicalPrinter = obj => obj.Properties.OfType<PropertyData>().Any(indicatesPhysical);

    var searcher = new ManagementObjectSearcher("Select * from Win32_Printer");
    var collection = searcher.Get();
    var physicalPrinters = collection.OfType<ManagementBaseObject>().Where(isPhysicalPrinter);

    foreach (var item in physicalPrinters)
    {
        Console.WriteLine(item.Properties["DeviceID"].Value);
        Console.WriteLine(item.Properties["EnableBIDI"].Value);
    }
}

您可以使用 Enumerable.OfType<>() 扩展方法将指定的 IEnumerable 接口转换为 IEnumerable 接口。代码>IEnumerable。这将有助于完成这些查询。

您关于如何区分物理打印机和虚拟打印机的示例对我来说不起作用,但它与您正在处理的主要问题无关,即尝试使用 LINQ 表达式使代码更具可读性。

The issue with combining LINQ and System.Management is that the latter uses older non-generic containers (like ManagementObjectCollection) that you can't use directly with LINQ because it uses the non-generic IEnumerable interface.

Luckily you can work around that, as in the following example:

static void Main(string[] args)
{
    Func<PropertyData, bool> indicatesPhysical = property => property.Name == "EnableBIDI"; // && (bool) property.Value;
    Func<ManagementBaseObject, bool> isPhysicalPrinter = obj => obj.Properties.OfType<PropertyData>().Any(indicatesPhysical);

    var searcher = new ManagementObjectSearcher("Select * from Win32_Printer");
    var collection = searcher.Get();
    var physicalPrinters = collection.OfType<ManagementBaseObject>().Where(isPhysicalPrinter);

    foreach (var item in physicalPrinters)
    {
        Console.WriteLine(item.Properties["DeviceID"].Value);
        Console.WriteLine(item.Properties["EnableBIDI"].Value);
    }
}

You can use the Enumerable.OfType<>() extension method to transform the specified IEnumerable interface into an IEnumerable<ManagementBaaseObject>. That will help in getting those queries along.

Your example on how to differentiate between physical and virtual printers didn't work on my end, but it's irrelevant to what the main problem is that you're dealing with, namely trying to make code more readable by using LINQ expressions.

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