C#(.Net) 配合WQL实现并口读写

C#(.Net) 配合WQL实现并口读写

 

最近做开发,要对POS打印机就进行编程,说白了,也就是一个端口读写,再根据打印机说明实现几个POS指令就OK了,但是遇到了一个困难的问题,因为是无人系统,一个打印机打印客户单据,一个打印历史单据,这个还不是最要命的,最要命的是一个是串口的,一个是并口的,对于串口还好办,因为.Net里有现成的SerialPort类,可是并口就难了。

搜了一下网上的资料,不外乎两种方法。

第一种是用win32 API来实现。见

http://support.microsoft.com/kb/823179/zh-cn

另一种方式是用第三方的动态连接库inpout32.dll

http://www.codeproject.com/KB/vb/Inpout32_read.aspx

两种方式,各有优劣。

如果用win32 API的话,操作固然方便,但是有一个死穴,就是无法读并口的数据。

如果用inpout32呢,到是能读能写,但是并口的地址(0x378,0x379,0x37a)并不是一个固定值。

参见文档

http://www.cnblogs.com/thunderdanky/articles/795010.html

但是客户要求能实时检测打印机状态 。。 这个问题可是难住了一天。

怎么办?让客户自己到设备管理器里去找并口基址?MS有点太土了。

后来看了一些资料,突然发现WQL好像可以实现查找串口基址的功能,实验了一下,还真实现了,嘿嘿

好了,现在就贴代码


ContractedBlock.gif ExpandedBlockStart.gif Code
  1using System;
  2using System.Collections.Generic;
  3using System.Text;
  4using System.Runtime.InteropServices;
  5using System.Management;
  6
  7namespace SFTech.POSPrint
  8ExpandedBlockStart.gifContractedBlock.gif{
  9ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
 10    /// 串口类,IPort是抽像的端口类
 11    /// </summary>

 12    public class ParallelPort : IPort ,IDisposable
 13ExpandedSubBlockStart.gifContractedSubBlock.gif    {
 14
 15ContractedSubBlock.gifExpandedSubBlockStart.gif        inpout32相关#region inpout32相关
 16        [DllImport("inpout32.dll", EntryPoint = "Out32")]
 17        public static extern void Output(uint adress, int value);
 18
 19        [DllImport("inpout32.dll", EntryPoint = "Inp32")]
 20        public static extern int Input(uint adress); 
 21        [StructLayout(LayoutKind.Sequential)]
 22        private struct OVERLAPPED
 23ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 24            int Internal;
 25            int InternalHigh;
 26            int Offset;
 27            int OffSetHigh;
 28            int hEvent;
 29        }

 30        #endregion

 31
 32ContractedSubBlock.gifExpandedSubBlockStart.gif        win32 API#region win32 API
 33        [DllImport("kernel32.dll ")]
 34        private static extern int CreateFile(
 35          string lpFileName,
 36          uint dwDesiredAccess,
 37          int dwShareMode,
 38          int lpSecurityAttributes,
 39          int dwCreationDisposition,
 40          int dwFlagsAndAttributes,
 41          int hTemplateFile
 42          );
 43        [DllImport("kernel32.dll ")]
 44        private static extern bool WriteFile(
 45          int hFile,
 46          byte[] lpBuffer,
 47          int nNumberOfBytesToWrite,
 48          ref   int lpNumberOfBytesWritten,
 49          ref   OVERLAPPED lpOverlapped
 50          );
 51        [DllImport("kernel32.dll ")]
 52        private static extern bool CloseHandle(
 53          int hObject
 54          );
 55        [DllImport("kernel32.dll ")]
 56       private static extern bool ReadFile(
 57          int hFile,
 58          out byte[] lpBuffer,
 59          int nNumberOfBytesToRead,
 60          ref int lpNumberOfBytesRead,
 61          ref OVERLAPPED lpOverlapped
 62        ); 
 63
 64        private int iHandle;
 65
 66        private bool _isWork;
 67     
 68        private const uint  GENERIC_READ = 0x80000000;
 69        private const uint GENERIC_WRITE = 0x40000000;
 70        #endregion

 71ContractedSubBlock.gifExpandedSubBlockStart.gif        IPort 成员#region IPort 成员
 72
 73
 74        private bool _IsOpen;
 75        public bool IsOpen
 76ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 77            get
 78ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 79                return _IsOpen;
 80            }

 81            private set
 82ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 83                _IsOpen = value;
 84            }

 85        }

 86
 87        private string _Name;
 88        public string Name
 89ExpandedSubBlockStart.gifContractedSubBlock.gif        {
 90            get
 91ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 92                return _Name;
 93            }

 94            set
 95ExpandedSubBlockStart.gifContractedSubBlock.gif            {
 96                _Name = value;
 97            }

 98        }

 99
100        public bool WriteData(byte[] Data)
101ExpandedSubBlockStart.gifContractedSubBlock.gif        {
102            //for (int i = 0; i < Data.Length; i++)
103            //    Output(BasePort, Data[i]); 这里原来也想用inpout32实现,但是从字节到int转换比较麻烦,试了几次没达到效果
104            //return true;
105
106            if (iHandle != -1)
107ExpandedSubBlockStart.gifContractedSubBlock.gif            {
108                OVERLAPPED x = new OVERLAPPED();
109                int i = 0;
110                WriteFile(iHandle, Data, Data.Length,
111                  ref   i, ref   x);
112                return true;
113            }

114            else
115ExpandedSubBlockStart.gifContractedSubBlock.gif            {
116                //throw new Exception("不能连接到打印机! ");
117                return false;
118            }

119        }

120
121
122ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
123        /// 读状态
124        /// 用inpout32
125        /// </summary>
126        /// <param name="Len"></param>
127        /// <returns></returns>

128        public byte[] ReadData(int Len)
129ExpandedSubBlockStart.gifContractedSubBlock.gif        {
130            byte[] result ;//= new byte[Len];
131            result = new byte[Len];
132            for (int i = 0; i < result.Length; i++)
133                result[i] = (byte)Input(BasePort + 1);
134            return result;
135        }

136
137
138ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
139        /// 打开端口
140        /// </summary>

141        public void Open()
142ExpandedSubBlockStart.gifContractedSubBlock.gif       {
143           iHandle = CreateFile(Name, 0x4000000000300);
144           if (iHandle != -1)
145ExpandedSubBlockStart.gifContractedSubBlock.gif           {
146               this.IsOpen = true;
147           }

148           else
149ExpandedSubBlockStart.gifContractedSubBlock.gif           {
150               this.IsOpen = false;
151           }

152
153           this.IsOpen = true;
154           _isWork = true;
155           //开一个线程检测状态口状态
156           new System.Threading.Thread(new System.Threading.ThreadStart(ReadState)).Start();
157        }

158
159
160ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
161        /// 关闭端口
162        /// </summary>

163        public void Close()
164ExpandedSubBlockStart.gifContractedSubBlock.gif        {
165           this.IsOpen =  !CloseHandle(iHandle);
166           _isWork = false;
167        }

168
169ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
170        /// 端口基址
171        /// </summary>

172ExpandedSubBlockStart.gifContractedSubBlock.gif        private uint BasePort getset; }
173        internal ParallelPort(String portName)
174ExpandedSubBlockStart.gifContractedSubBlock.gif        {
175            this.Name = portName;
176            iHandle = -1;
177
178ExpandedSubBlockStart.gifContractedSubBlock.gif            /**////用wql查询串口基址
179            ManagementObjectSearcher search2 =
180                    new ManagementObjectSearcher(
181                        "ASSOCIATORS OF {Win32_ParallelPort.DeviceID='" + this.Name  + "'}");
182            //本来最佳的wql是ASSOCIATORS OF {Win32_ParallelPort.DeviceID='" + this.Name  + "'} WHERE ASSCICLASS = Win32_PortResource
183            //但是不知道为什么不返回结果,所以就做一个简单的遍历吧
184            foreach (var i in search2.Get())
185ExpandedSubBlockStart.gifContractedSubBlock.gif            {
186
187                if (i.ClassPath.ClassName == "Win32_PortResource")
188ExpandedSubBlockStart.gifContractedSubBlock.gif                {
189                    //得到串口基址 大多数是0x378H
190                    this.BasePort = System.Convert.ToUInt32( i.Properties["StartingAddress"].Value.ToString());
191
192                    break;
193                }

194
195
196            }

197            if (BasePort == 0)
198                throw new Exception("不是有效端口");
199            IsOpen = false;
200        }

201
202        #endregion

203
204ContractedSubBlock.gifExpandedSubBlockStart.gif        IPort Members#region IPort Members
205
206        public event PortStateChanged StateChanged;
207
208        public event PortDataReceived DataReceive;
209
210        public System.Windows.Forms.Form Parent
211ExpandedSubBlockStart.gifContractedSubBlock.gif        {
212            get
213ExpandedSubBlockStart.gifContractedSubBlock.gif            {
214                throw new NotImplementedException();
215            }

216            set
217ExpandedSubBlockStart.gifContractedSubBlock.gif            {
218                throw new NotImplementedException();
219            }

220        }

221
222ExpandedSubBlockStart.gifContractedSubBlock.gif        private int a getset; }
223
224ExpandedSubBlockStart.gifContractedSubBlock.gif        /**//// <summary>
225        /// 检测线程,当状态改变时,引发事件
226        /// </summary>

227        private void ReadState()
228ExpandedSubBlockStart.gifContractedSubBlock.gif        {
229
230            a = 0;
231            int lastRead =a;
232            while (_isWork)
233ExpandedSubBlockStart.gifContractedSubBlock.gif            {
234                lastRead = a;
235                a = Input(BasePort + 1);
236                if (a != lastRead)
237ExpandedSubBlockStart.gifContractedSubBlock.gif                {
238                    if (this.StateChanged != null)
239ExpandedSubBlockStart.gifContractedSubBlock.gif                    {
240                        PortChangedEvntAvrgs e = new PortChangedEvntAvrgs();
241                        e.PortStatusByte = a;
242                        this.StateChanged(this, e);
243                    }

244                   
245                }

246                System.Threading.Thread.Sleep(500);
247                
248            }

249        }

250        #endregion

251
252ContractedSubBlock.gifExpandedSubBlockStart.gif        IDisposable Members#region IDisposable Members
253
254        public void Dispose()
255ExpandedSubBlockStart.gifContractedSubBlock.gif        {
256            this.Close();
257        }

258
259        #endregion

260
261ContractedSubBlock.gifExpandedSubBlockStart.gif        IPort Members#region IPort Members
262
263
264        public void Update()
265ExpandedSubBlockStart.gifContractedSubBlock.gif        {
266            a = 0;
267        }

268
269        #endregion

270    }

271}

272
posted @ 2009-03-17 19:47 葛云飞 阅读( ...) 评论( ...) 编辑 收藏
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值