【问题标题】:Get Printer Port Number in c#在 C# 中获取打印机端口号
【发布时间】:2014-10-22 07:21:09
【问题描述】:

我想在 c# 中获取我的打印机端口号

我尝试过使用 Win32_Printer 和 PrinterSettings

//Required namespaces
using System.Management;
using System.Drawing.Printing;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Printing;
using System.IO.Ports;
using System.Net;

            String printerName = "My printer name";
            //String query = String.Format("Select Name, PortName from Win32_Printer WHERE Name LIKE '%{0}'", printerName);
            String query = String.Format("Select * from Win32_Printer WHERE Name LIKE '%{0}'", printerName);
            ManagementObjectSearcher printers = new ManagementObjectSearcher(query);
            foreach (ManagementObject printer in printers.Get())
            {
                DeviceName = (string)printer.GetPropertyValue("Name");
                //Console.WriteLine(DeviceName);
                PortName = (string)printer.GetPropertyValue("PortName");
                //Console.WriteLine(PortName);
            } 


        PrinterSettings ps = new PrinterSettings();
        ps.PrinterName = printerName;

我能得到的是端口名,但不是端口号,请帮忙。

【问题讨论】:

  • 打印机使用端口的日子已经一去不复返了,他们现在使用 USB 或网络。当您没有记录从查询中得到的内容时,这只是猜测。

标签: c#-4.0 printing system wmi-query


【解决方案1】:

使用 Microsoft 的 WMI Code Creator v1.0 工具,我发现您可以通过 Win32_TCPIPPrinterPort 访问标准 TCP/IP 端口的 PortNumber。

using System;
using System.Management;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                ManagementObjectSearcher searcher =
                    new ManagementObjectSearcher("root\\CIMV2",
                    "SELECT * FROM Win32_TCPIPPrinterPort");

                foreach (ManagementObject queryObj in searcher.Get())
                {
                    Console.WriteLine("-----------------------------------");
                    Console.WriteLine("Win32_TCPIPPrinterPort instance");
                    Console.WriteLine("-----------------------------------");
                    Console.WriteLine("Name: {0}", queryObj["Name"]);
                    Console.WriteLine("PortNumber: {0}", queryObj["PortNumber"]);
                }
            }
            catch (ManagementException e)
            {
               Console.WriteLine("An error occurred while querying for WMI data: " + e.Message);
            }

            Console.ReadKey();
        }
    }
}

【讨论】:

    【解决方案2】:

    ManagementObject 有一个properties 属性,它返回PropertyData 对象的集合。

    https://msdn.microsoft.com/en-us/library/system.management.managementbaseobject.properties(v=vs.110).aspx

    PropertyData 你可以得到NameValue。只需遍历所有属性,就可以找到端口号。

    https://msdn.microsoft.com/en-us/library/system.management.propertydata(v=vs.110).aspx

    以下是伪代码:(未经测试)

            foreach (ManagementObject printer in printers.Get())
            {
                foreach (PropertyData property in printer.properties)
                {
                     Console.WriteLine(property.Name);
                     Console.WriteLine(property.Value);
    
                }
            } 
    

    【讨论】:

      【解决方案3】:

      using System;
      using System.Runtime.InteropServices;
      using System.ComponentModel;
      using System.Collections.Generic;
      using static System.Net.Mime.MediaTypeNames;
      
      namespace ConsoleApp1
      {
          class Myclass
          {
                       //PortType enum
                      //struct for PORT_INFO_2
                      [StructLayout(LayoutKind.Sequential)]
                      public struct PORT_INFO_2
                      {
                          public string pPortName;
                          public string pMonitorName;
                          public string pDescription;
                          public PortType fPortType;
                          internal int Reserved;
                      }
      
      
                      [Flags]
                      public enum PortType : int
                      {
                          write = 0x1,
                          read = 0x2,
                          redirected = 0x4,
                          net_attached = 0x8
                      }
      
                      //Win32 API
                      [DllImport("winspool.drv", EntryPoint = "EnumPortsA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
                      public static extern int EnumPorts(string pName, int Level, IntPtr lpbPorts, int cbBuf, ref int pcbNeeded, ref int pcReturned);
        
      
              /// <summary>
              /// method for retrieving all available printer ports
              /// </summary>
              /// <returns>generic list populated with post names (i.e; COM1, LTP1, etc)</returns>
      
                public List<string> GetPortNames()
                  {
                      //variables needed for Win32 API calls
                      int result; int needed = 0; int cnt = 0; IntPtr buffer = IntPtr.Zero; IntPtr port = IntPtr.Zero;
      
                      //list to hold the returned port names
                      List<string> ports = new List<string>();
      
                      //new PORT_INFO_2 for holding the ports
                      PORT_INFO_2[] portInfo = null;
      
                      //enumerate through to get the size of the memory we need
                      result = EnumPorts("", 2, buffer, 0, ref needed, ref cnt);
                      try
                      {
                          //allocate memory
                          buffer = Marshal.AllocHGlobal(Convert.ToInt32(needed + 1));
      
                          //get list of port names
                          result = EnumPorts("", 2, buffer, needed, ref needed, ref cnt);
      
                          //check results, if 0 (zero) then we got an error
                          if (result != 0)
                          {
                              //set port value
                              port = buffer;
      
                              //instantiate struct
                              portInfo = new PORT_INFO_2[cnt];
      
                              //now loop through the returned count populating our array of PORT_INFO_2 objects
                              for (int i = 0; i < cnt; i++)
                              {
                                  portInfo[i] = (PORT_INFO_2)Marshal.PtrToStructure(port, typeof(PORT_INFO_2));
                                  port = (IntPtr)(port.ToInt32() + Marshal.SizeOf(typeof(PORT_INFO_2)));
                          }
                          port = IntPtr.Zero;
                      }
                          else
                              throw new Win32Exception(Marshal.GetLastWin32Error());
      
                          //now get what we want. Loop through al the
                          //items in the PORT_INFO_2 Array and populate our generic list
                          for (int i = 0; i < cnt; i++)
                          {
                              ports.Add(portInfo[i].pPortName);                        
                      }
      
                      //sort the list
                      ports.Sort();
      
                      return ports;
                  }
                      catch (Exception ex)
                      {
                          Console.WriteLine(string.Format("Error getting available ports: {0}", ex.Message));
                          Console.ReadLine();
                      return null;
                      }
                      finally
                      {
                          if (buffer != IntPtr.Zero)
                          {
                              Marshal.FreeHGlobal(buffer);
                              buffer = IntPtr.Zero;
                              port = IntPtr.Zero;
                          }
                      }
                   
                  }
      
              [STAThread]
              static void Main()
              {
                  Myclass m = new Myclass();
                  
                  foreach (var item in m.GetPortNames())
                  {
                      Console.WriteLine(item.ToString());
                  }
                 
                  Console.Read();
              }
          } 
      }

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多