天天看點

列印系統開發(45)——C#添加本地列印機

class Program
    {
        static void Main(string[] args)
        {
            const string printerName = "Print to file";
            const string portName = "FILE:";
            const string driverName = "ZEBRA R110Xi4 300DPI";

            PrinterPorts printerPorts = new PrinterPorts();

            var portNames = printerPorts.GetPortNames();
            //判断端口是否存在
            if (!portNames.Contains(portName))
            {
                Console.WriteLine("{0} port is not existed", portName);
                return;
            }

            var driverNames = GetDrivers();
            //判断Driver是否存在
            if (!driverNames.Contains(driverName))
            {
                Console.WriteLine("{0} driver is not existed", driverName);
                return;
            }

            AddPrinter(printerName, portName, driverName);

            Console.ReadKey();
        }

        private static void AddPrinter(string printerName, string portName,string printerDriver)
        {
            try
            {
                //init Win32_Printer class     
                var printerClass = new ManagementClass("Win32_Printer");

                //create new Win32_Printer object   
                ManagementObject printerObject = printerClass.CreateInstance();

                if (printerObject == null)
                {
                    throw new Exception("printerObject is null");
                }

                printerObject["PortName"] = portName;
                //set driver and device names              
                printerObject["DriverName"] = printerDriver;

                printerObject["DeviceID"] = printerName;

                // specify put options: update or create              
                PutOptions options = new PutOptions();
                options.Type = PutType.UpdateOrCreate;
                //put a newly created object to WMI objects set              
                printerObject.Put(options);
            }
            catch (Exception ex)
            {
                throw new Exception(String.Format("WMI exception: {0}", ex.Message));
            }
        }

        /// <summary>
        /// Get's a list of drives installed on the computer
        /// </summary>
        /// <returns></returns>
        private static List<string> GetDrivers()
        {
            var drivers = new List<string>();

            var selectQuery = new SelectQuery("Win32_PrinterDriver");
            var searcher = new ManagementObjectSearcher(selectQuery);

            foreach (ManagementObject printerDriver in searcher.Get())
            {
                // Your code here.
                var obj = printerDriver["name"];
                string name = string.Empty;

                if (obj != null)
                {
                    name = obj.ToString().Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries)[0];
                }

                drivers.Add(name);
            }

            return drivers;
        }

    }
           
class PrinterPorts
    {
        //PortType enum
        [Flags]
        public enum PortType : int
        {
            write = 0x1,
            read = 0x2,
            redirected = 0x4,
            net_attached = 0x8
        }


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

        //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;
            }
            finally
            {
                if (buffer != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(buffer);
                    buffer = IntPtr.Zero;
                    port = IntPtr.Zero;

                }
            }
        }
    }
           

Â