C#配合WQL实现并口读写

-1 star
1
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Management;

namespace SFTech.POSPrint
{
/// <summary>
///
串口类,IPort是抽像的端口类
/// </summary>
public class ParallelPort : IPort ,IDisposable
{

#region inpout32相关
[DllImport("inpout32.dll", EntryPoint = "Out32")]
public static extern void Output(uint adress, int value);

[DllImport("inpout32.dll", EntryPoint = "Inp32")]
public static extern int Input(uint adress);
[StructLayout(LayoutKind.Sequential)]
private struct OVERLAPPED
{
int Internal;
int InternalHigh;
int Offset;
int OffSetHigh;
int hEvent;
}
#endregion

#region
win32 API
[DllImport("kernel32.dll ")]
private static extern int CreateFile(
string lpFileName,
uint dwDesiredAccess,
int dwShareMode,
int lpSecurityAttributes,
int dwCreationDisposition,
int dwFlagsAndAttributes,
int hTemplateFile
);
[DllImport("kernel32.dll ")]
private static extern bool WriteFile(
int hFile,
byte[] lpBuffer,
int nNumberOfBytesToWrite,
ref int lpNumberOfBytesWritten,
ref OVERLAPPED lpOverlapped
);
[DllImport("kernel32.dll ")]
private static extern bool CloseHandle(
int hObject
);
[DllImport("kernel32.dll ")]
private static extern bool ReadFile(
int hFile,
out byte[] lpBuffer,
int nNumberOfBytesToRead,
ref int lpNumberOfBytesRead,
ref OVERLAPPED lpOverlapped
);

private int iHandle;

private bool _isWork;

private const uint GENERIC_READ = 0x80000000;
private const uint GENERIC_WRITE = 0x40000000;
#endregion
#region
IPort 成员


private bool _IsOpen;
public bool IsOpen
{
get
{
return _IsOpen;
}
private set
{
_IsOpen = value;
}
}

private string _Name;
public string Name
{
get
{
return _Name;
}
set
{
_Name = value;
}
}

public bool WriteData(byte[] Data)
{
//for (int i = 0; i < Data.Length; i++)
// Output(BasePort, Data[i]); 这里原来也想用inpout32实现,但是从字节到int转换比较麻烦,试了几次没达到效果
//return true;

if (iHandle != -1)
{
OVERLAPPED x = new OVERLAPPED();
int i = 0;
WriteFile(iHandle, Data, Data.Length,
ref i, ref x);
return true;
}
else
{
//throw new Exception("不能连接到打印机! ");
return false;
}
}


/// <summary>
///
读状态
/// 用inpout32
/// </summary>
/// <param name="Len"></param>
/// <returns></returns>
public byte[] ReadData(int Len)
{
byte[] result ;//= new byte[Len];
result = new byte[Len];
for (int i = 0; i < result.Length; i++)
result[i] = (byte)Input(BasePort + 1);
return result;
}


/// <summary>
///
打开端口
/// </summary>
public void Open()
{
iHandle = CreateFile(Name, 0x40000000, 0, 0, 3, 0, 0);
if (iHandle != -1)
{
this.IsOpen = true;
}
else
{
this.IsOpen = false;
}

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


/// <summary>
///
关闭端口
/// </summary>
public void Close()
{
this.IsOpen = !CloseHandle(iHandle);
_isWork = false;
}

/// <summary>
///
端口基址
/// </summary>
private uint BasePort { get; set; }
internal ParallelPort(String portName)
{
this.Name = portName;
iHandle = -1;

///用wql查询串口基址
ManagementObjectSearcher search2 =
new ManagementObjectSearcher(
"ASSOCIATORS OF {Win32_ParallelPort.DeviceID='" + this.Name + "'}");
//本来最佳的wql是ASSOCIATORS OF {Win32_ParallelPort.DeviceID='" + this.Name + "'} WHERE ASSCICLASS = Win32_PortResource
//但是不知道为什么不返回结果,所以就做一个简单的遍历吧
foreach (var i in search2.Get())
{

if (i.ClassPath.ClassName == "Win32_PortResource")
{
//得到串口基址 大多数是0x378H
this.BasePort = System.Convert.ToUInt32( i.Properties["StartingAddress"].Value.ToString());

break;
}


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

#endregion

#region
IPort Members

public event PortStateChanged StateChanged;

public event PortDataReceived DataReceive;

public System.Windows.Forms.Form Parent
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}

private int a { get; set; }

/// <summary>
///
检测线程,当状态改变时,引发事件
/// </summary>
private void ReadState()
{

a = 0;
int lastRead =a;
while (_isWork)
{
lastRead = a;
a = Input(BasePort + 1);
if (a != lastRead)
{
if (this.StateChanged != null)
{
PortChangedEvntAvrgs e = new PortChangedEvntAvrgs();
e.PortStatusByte = a;
this.StateChanged(this, e);
}

}
System.Threading.Thread.Sleep(500);

}
}
#endregion

#region
IDisposable Members

public void Dispose()
{
this.Close();
}

#endregion

#region
IPort Members


public void Update()
{
a = 0;
}

#endregion
}
}

0 回答