Здравствуйте, AC1D, Вы писали:
ACD>1.) Ктонить писал чтонить для работы с последовательным портом на C#?
ACD>Есть ли какие нить компонентики\классы? Надо всеголишь получить данные.
Есть очень полезная иерархия в дотнете — корнем от Stream.
Есть класс FileStream, но, к сожалению, им невозможно открыть девайс.
Поэтому накатал свой простенький класс для доступа к девайсам (пару вещей пришлось делать напрямую через WinAPI):
DeviceStream.cs
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace DriverLib {
public class DeviceStream : Stream {
private IntPtr handle;
public DeviceStream(IntPtr handle) {
this.handle=handle;
}
public DeviceStream(string path) {
WinAPI.Check(handle = WinAPI.CreateFileA(path, (uint)FileAccess.ReadWrite,
(uint)FileShare.ReadWrite, nullPtr, 3, 0, nullPtr) );
}
public IntPtr Handle { get { return this.handle; } }
public override void Flush() { }
public override bool CanRead { get { return true; } }
public override bool CanSeek { get { return false; } }
public override bool CanWrite { get { return true; } }
public override long Length { get { return 0; } }
static Exception canNotSeek = new IOException("Can not seek in driver stream.");
public override long Position {
get { return 0; }
set { throw canNotSeek; }
}
public override long Seek(long offset, SeekOrigin origin) {
throw canNotSeek;
}
public override void SetLength(long value) {
throw canNotSeek;
}
private static IntPtr nullPtr=(IntPtr)0;
public override int Read(byte[] buffer, int offset, int count)
{
if (offset+count>buffer.Length)
throw new IndexOutOfRangeException();
unsafe {
fixed(byte* buf=buffer) {
byte* buf1=buf+offset;
uint readed;
WinAPI.Check(WinAPI.ReadFile(handle, buf1, (uint)count, &readed, nullPtr)!=0);
return (int)readed;
}
}
}
public override void Write(byte[] buffer, int offset, int count)
{
if (offset+count>buffer.Length)
throw new IndexOutOfRangeException();
unsafe {
fixed(byte* buf=buffer) {
byte* buf1=buf+offset;
uint writed;
WinAPI.Check(WinAPI.WriteFile(handle, buf1, (uint)count, &writed, nullPtr)!=0);
}
}
}
public void Dispose() {
if (handle!=(IntPtr)0)
WinAPI.CloseHandle(handle);
}
}
}
WinAPI.cs
using System;
using System.Runtime.InteropServices;
namespace DriverLib {
public sealed class WinAPI {
// private constructor
private WinAPI() {}
/// <summary>
/// WinAPI INVALID_HANDLE value
/// </summary>
public static readonly IntPtr InvalidHandle = new IntPtr(- 1L);
[DllImport("Kernel32.dll")]
[return : MarshalAs(UnmanagedType.Error)]
public static extern ErrorCode GetLastError();
/// <summary>
/// Win32 API error codes.
/// to be continued ...
/// </summary>
public enum ErrorCode {
NO_ERROR = 0,
ERROR_NO_MORE_ITEMS = 259
}
/// <summary>
/// Checks last Win32 API error.
/// Throws an WinAPI.Exception
/// </summary>
public static void CheckLastError() {
Check(GetLastError());
}
public static void Check(ErrorCode err) {
if (err != ErrorCode.NO_ERROR)
throw new Exception("System error #"+err);
// TODO: add more information in error description
}
/// <summary>
/// Throws exception if false
/// </summary>
public static void Check(bool result) {
if (result == false)
CheckLastError();
}
/// <summary>
/// BOOL WinAPI result checking
/// </summary>
public static void Check(uint result) {
Check(result != 0);
}
/// <summary>
/// Handle check for INVALID_HANDLE
/// </summary>
public static void Check(IntPtr result) {
Check(result != InvalidHandle);
}
/// <summary>
/// API exception
/// </summary>
public class Exception : System.SystemException {
public Exception() { }
public Exception(string text) : base(text) { }
public Exception(string text, Exception innerException)
: base(text, innerException) { }
}
[DllImport("Kernel32.dll")]
protected static extern IntPtr CreateFileA(
[MarshalAs(UnmanagedType.LPStr)]
String lpFileName,
uint dwDesiredAccess,
uint dwShareMode,
IntPtr lpSecurityAttributes,
uint dwCreationDisposition,
uint dwFlagsAndAttributes,
IntPtr hTemplateFile);
[DllImport("Kernel32.dll")]
public unsafe static extern uint ReadFile(
IntPtr hFile,
byte* lpBuffer,
uint nNumberOfBytesToRead,
uint* lpNumberOfBytesRead,
IntPtr lpOverlapped);
[DllImport("Kernel32.dll")]
public unsafe static extern uint WriteFile(
IntPtr hFile,
byte* lpBuffer,
uint nNumberOfBytesToWrite,
uint* lpNumberOfBytesWritten,
IntPtr lpOverlapped);
[DllImport("Kernel32.dll")]
public static extern uint CloseHandle(IntPtr hObject);
}
}
а теперь весело так все это используем:
DeviceStream comPort= new DeviceStream("COM1:9600,n,8,1,ds");
try {
comPort.Open();
comPort.WriteByte(0x7); // write something to port
comPort.WriteByte(0xA);
} catch (Exception ex) {
MessageBox.Show(ex.ToString());
} finally {
comPort.Close();
}