c#本身就是让你少抄这份心! 好像不行吧! c#  +   C++

解决方案 »

  1.   

    先在VC中编写一个DLL,然后在C#中调用。
      

  2.   

    MScomm
    http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=320
      

  3.   

    using System;
    using System.IO;
    using System.Threading;
    using System.Runtime.InteropServices; public class SerialStream : Stream { public class SerialAsyncResult : IAsyncResult {
    public SerialAsyncResult(object asyncObject) {
    m_AsyncObject = asyncObject;
    m_WaitHandle = new ManualResetEvent(false);
    } internal void Init(object stateObject, AsyncCallback callback, bool bIsRead) {
    m_StateObject = stateObject;
    m_Callback = callback;
    m_bIsRead = bIsRead;
    m_bCompleted = false;
    m_WaitHandle.Reset();
    } internal void Reset() {
    m_StateObject = null;
    m_Callback = null;
    m_bCompleted = true;
    m_WaitHandle.Reset();
    } internal bool m_bIsRead;
    internal bool m_bCompleted = true; public bool IsCompleted { get { return m_bCompleted; } }
    public bool CompletedSynchronously { get { return false; } } private object m_AsyncObject;
    public object AsyncObject { get { return m_AsyncObject; } } private object m_StateObject;
    public object AsyncState { get { return m_StateObject; } } private ManualResetEvent m_WaitHandle;
    public WaitHandle AsyncWaitHandle { get { return m_WaitHandle; } } private AsyncCallback m_Callback;
    public AsyncCallback Callback { get { return m_Callback; } }
    }

    private unsafe void AsyncFSCallback(uint errorCode, uint numBytes, NativeOverlapped* pOverlapped) {
    SerialAsyncResult sar = (SerialAsyncResult)Overlapped.Unpack(pOverlapped).AsyncResult; if (sar.m_bIsRead)
    m_iReadCount = (int)numBytes;
    else
    m_iWriteCount = (int)numBytes;
    ((ManualResetEvent)sar.AsyncWaitHandle).Set(); if (errorCode == ERROR_OPERATION_ABORTED)
    sar.m_bCompleted = false;
    else
    sar.m_bCompleted = true; if (sar.Callback != null)
    sar.Callback.Invoke(sar);
    } private IOCompletionCallback m_IOCompletionCallback;
    private int m_hFile = 0; private string m_sPort;
    public string Port {
    get {
    return m_sPort;
    }
    set {
    if (m_sPort != value) {
    Close();
    Open(value);
    }
    }
    } private const uint GENERIC_READ = 0x80000000;
    private const uint GENERIC_WRITE = 0x40000000;
    private const uint ERROR_OPERATION_ABORTED = 995;
    private const uint ERROR_IO_PENDING = 997; public void Open(string port) {
    m_hFile = CreateFile(port, (uint)((m_bRead?GENERIC_READ:0)|(m_bWrite?GENERIC_WRITE:0)), 0, 0, 3, 0x40000000, 0);
    if (m_hFile <= 0) {
    m_hFile = 0;
    throw new FileNotFoundException("Unable to open " + port);
    }
    m_sPort = port; ThreadPool.BindHandle(m_hFile);
    } public SerialStream(string port, FileAccess access) {
    m_bRead  = (access.ToInt32() & FileAccess.Read.ToInt32()) != 0;
    m_bWrite = (access.ToInt32() & FileAccess.Write.ToInt32()) != 0;
    Open(port);
    m_IOCompletionCallback = new IOCompletionCallback(AsyncFSCallback);
    } private bool m_bRead;
    public bool CanRead { override get { return m_bRead; } } private bool m_bWrite;
    public bool CanWrite { override get { return m_bWrite; } } public bool CanSeek { override get { return false; } } public bool Closed  { get { return m_hFile <= 0; } } public bool DataAvailable { override get { return true; } } public override long Length { get { return 0; } } public override void SetLength(long nLength) { } public override void Close() {
    CloseHandle(m_hFile);
    m_hFile = 0;
    m_sPort = null;
    } private int m_iReadCount;
    public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) {
    SerialAsyncResult ar = new SerialAsyncResult(this);
    ar.Init(state, callback, true);
    Overlapped ov = new Overlapped(0, 0, ar.AsyncWaitHandle.GetHandle(), ar);
    unsafe fixed (byte* data = &buffer[0]) {
    int read = 0;
    NativeOverlapped* nov = ov.Pack(m_IOCompletionCallback);
    ReadFile(m_hFile, data, count, &read, nov);
    } if (GetLastError() == ERROR_IO_PENDING)
    return ar;
    else
    throw new Exception("Unable to initialize read. Errorcode: " + GetLastError().ToString());
    } private int m_iWriteCount;
    public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) {
    SerialAsyncResult ar = new SerialAsyncResult(this);
    ar.Init(state, callback, false);
    Overlapped ov = new Overlapped(0, 0, ar.AsyncWaitHandle.GetHandle(), ar);
    unsafe fixed (byte* data = &buffer[0]) {
    int write = 0;
    NativeOverlapped* nov = ov.Pack(m_IOCompletionCallback);
    WriteFile(m_hFile, data, count, &write, nov);
    }
    if (GetLastError() == ERROR_IO_PENDING)
    return ar;
    else
    throw new Exception("Unable to initialize write. Errorcode: " + GetLastError().ToString());
    }

    public override int EndRead(IAsyncResult asyncResult) {
    SerialAsyncResult sar = (SerialAsyncResult)asyncResult;
    if (!sar.m_bIsRead)
    throw new Exception("Invalid parameter: IAsyncResult is not from a read");
    sar.AsyncWaitHandle.WaitOne();
    if (!sar.m_bCompleted) {
    ((ManualResetEvent)sar.AsyncWaitHandle).Reset();
    sar.AsyncWaitHandle.WaitOne();
    }
    sar.Reset(); return m_iReadCount;
    }

    public override int EndWrite(IAsyncResult asyncResult) {
    SerialAsyncResult sar = (SerialAsyncResult)asyncResult;
    if (sar.m_bIsRead)
    throw new Exception("Invalid parameter: IAsyncResult is from a read");
    sar.AsyncWaitHandle.WaitOne();
    if (!sar.m_bCompleted) {
    ((ManualResetEvent)sar.AsyncWaitHandle).Reset();
    sar.AsyncWaitHandle.WaitOne();
    }
    sar.Reset(); return m_iWriteCount;
    } public override void Flush() { FlushFileBuffers(m_hFile); } private const uint PURGE_TXABORT = 0x0001;  // Kill the pending/current writes to the comm port.
    private const uint PURGE_RXABORT = 0x0002;  // Kill the pending/current reads to the comm port.
    private const uint PURGE_TXCLEAR = 0x0004;  // Kill the transmit queue if there.
    private const uint PURGE_RXCLEAR = 0x0008;  // Kill the typeahead buffer if there. public bool PurgeRead() { return(PurgeComm(m_hFile, PURGE_RXCLEAR)); }
    public bool PurgeWrite() { return(PurgeComm(m_hFile, PURGE_TXCLEAR)); }
    public bool CancelRead() { return(PurgeComm(m_hFile, PURGE_RXABORT)); }
    public bool CancelWrite() { return(PurgeComm(m_hFile, PURGE_TXABORT)); } public override long Seek(long offset, SeekOrigin origin) { return 0; } public long Position { override get { return 0; } override set { } } public void SetTimeouts(int ReadIntervalTimeout, int ReadTotalTimeoutMultiplier, int ReadTotalTimeoutConstant, 
    int WriteTotalTimeoutMultiplier, int WriteTotalTimeoutConstant) {
    SerialTimeouts Timeouts = new SerialTimeouts(ReadIntervalTimeout, ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant, 
     WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant);
    unsafe SetCommTimeouts(m_hFile, &Timeouts);
    } public enum Parity {None, Odd, Even, Mark, Space};
    public enum StopBits {One, OneAndHalf, Two};
    public enum FlowControl {None, XOnXOff, Hardware}; [StructLayout(LayoutKind.Sequential)]
    public struct DCB {
    public int DCBlength;
    public uint BaudRate;
    public uint Flags;
    public uint fBinary { get { return Flags&0x0001; } 
      set { Flags = Flags & ~1U | value; } }
    public uint fParity { get { return (Flags>>1)&1; }
      set { Flags = Flags & ~(1U << 1) | (value << 1); } }
    public uint fOutxCtsFlow { get { return (Flags>>2)&1; }
      set { Flags = Flags & ~(1U << 2) | (value << 2); } }
    public uint fOutxDsrFlow { get { return (Flags>>3)&1; }
      set { Flags = Flags & ~(1U << 3) | (value << 3); } }
    public uint fDtrControl { get { return (Flags>>4)&3; }
      

  4.   

      set { Flags = Flags & ~(3U << 4) | (value << 4); } }
    public uint fDsrSensitivity { get { return (Flags>>6)&1; }
      set { Flags = Flags & ~(1U << 6) | (value << 6); } }
    public uint fTXContinueOnXoff { get { return (Flags>>7)&1; }
      set { Flags = Flags & ~(1U << 7) | (value << 7); } }
    public uint fOutX { get { return (Flags>>8)&1; }
      set { Flags = Flags & ~(1U << 8) | (value << 8); } }
    public uint fInX { get { return (Flags>>9)&1; }
      set { Flags = Flags & ~(1U << 9) | (value << 9); } }
    public uint fErrorChar { get { return (Flags>>10)&1; }
      set { Flags = Flags & ~(1U << 10) | (value << 10); } }
    public uint fNull { get { return (Flags>>11)&1; }
      set { Flags = Flags & ~(1U << 11) | (value << 11); } }
    public uint fRtsControl { get { return (Flags>>12)&3; }
      set { Flags = Flags & ~(3U << 12) | (value << 12); } }
    public uint fAbortOnError { get { return (Flags>>13)&1; }
      set { Flags = Flags & ~(1U << 13) | (value << 13); } }
    public ushort wReserved;
    public ushort XonLim;
    public ushort XoffLim;
    public byte ByteSize;
    public byte Parity;
    public byte StopBits;
    public sbyte XonChar;
    public sbyte XoffChar;
    public sbyte ErrorChar;
    public sbyte EofChar;
    public sbyte EvtChar;
    public ushort wReserved1; public override string ToString() {
    return "DCBlength: " + DCBlength + "\r\n" +
    "BaudRate: " + BaudRate + "\r\n" +
    "fBinary: " + fBinary + "\r\n" +
    "fParity: " + fParity + "\r\n" +
    "fOutxCtsFlow: " + fOutxCtsFlow + "\r\n" +
    "fOutxDsrFlow: " + fOutxDsrFlow + "\r\n" +
      

  5.   

    "fDtrControl: " + fDtrControl + "\r\n" +
    "fDsrSensitivity: " + fDsrSensitivity + "\r\n" +
    "fTXContinueOnXoff: " + fTXContinueOnXoff + "\r\n" +
    "fOutX: " + fOutX + "\r\n" +
    "fInX: " + fInX + "\r\n" +
    "fErrorChar: " + fErrorChar + "\r\n" +
    "fNull: " + fNull + "\r\n" +
    "fRtsControl: " + fRtsControl + "\r\n" +
    "fAbortOnError: " + fAbortOnError + "\r\n" +
    "XonLim: " + XonLim + "\r\n" +
    "XoffLim: " + XoffLim + "\r\n" +
    "ByteSize: " + ByteSize + "\r\n" +
    "Parity: " + Parity + "\r\n" +
    "StopBits: " + StopBits + "\r\n" +
    "XonChar: " + XonChar + "\r\n" +
    "XoffChar: " + XoffChar + "\r\n" +
    "EofChar: " + EofChar + "\r\n" +
    "EvtChar: " + EvtChar + "\r\n";
    }
    } public bool SetPortSettings(uint baudrate, byte databits, StopBits stopbits, Parity parity, FlowControl flowcontrol) {
    unsafe {
    DCB dcb = new DCB();
    dcb.DCBlength = sizeof(DCB);
    dcb.BaudRate = baudrate;
    dcb.ByteSize = databits;
    dcb.StopBits = (byte)stopbits;
    dcb.Parity = (byte)parity;
    dcb.fParity = (parity > 0)? 1U : 0U;
    dcb.fBinary = dcb.fDtrControl = dcb.fTXContinueOnXoff = 1;
    dcb.fOutxCtsFlow = dcb.fAbortOnError = (flowcontrol == FlowControl.Hardware)? 1U : 0U;
    dcb.fOutX = dcb.fInX = (flowcontrol == FlowControl.XOnXOff)? 1U : 0U;
    dcb.fRtsControl = (flowcontrol == FlowControl.Hardware)? 2U : 1U;
    dcb.XonLim = 2048;
    dcb.XoffLim = 512;
    dcb.XonChar = 0x11; // Ctrl-Q
    dcb.XoffChar = 0x13; // Ctrl-S
    return SetCommState(m_hFile, &dcb);
    }
    } public bool GetPortSettings(out DCB dcb) {
    unsafe {
    DCB dcb2 = new DCB();
    dcb2.DCBlength = sizeof(DCB);
    bool ret = GetCommState(m_hFile, &dcb2);
    dcb = dcb2;
    return ret;
    }
    } [dllimport("kernel32.dll", SetLastError=true)]
    static extern int CreateFile(string filename, uint access, uint sharemode, uint security_attributes, uint creation, uint flags, uint template); [dllimport("kernel32.dll", SetLastError=true)]
    static extern bool CloseHandle(int handle); [dllimport("kernel32.dll", SetLastError=true)]
    static unsafe extern bool ReadFile(int hFile, byte* lpBuffer, int nNumberOfBytesToRead, int* lpNumberOfBytesRead, NativeOverlapped* lpOverlapped); [dllimport("kernel32.dll", SetLastError=true)]
    static unsafe extern bool WriteFile(int hFile, byte* lpBuffer, int nNumberOfBytesToWrite, int* lpNumberOfBytesWritten, NativeOverlapped* lpOverlapped); [dllimport("kernel32.dll", SetLastError=true)]
    static unsafe extern bool SetCommTimeouts(int hFile, SerialTimeouts* lpCommTimeouts); [dllimport("kernel32.dll", SetLastError=true)]
    static unsafe extern bool SetCommState(int hFile, DCB* lpDCB); [dllimport("kernel32.dll", SetLastError=true)]
    static unsafe extern bool GetCommState(int hFile, DCB* lpDCB); [dllimport("kernel32.dll", SetLastError=true)]
    static unsafe extern bool BuildCommDCB(string def, DCB* lpDCB); [dllimport("kernel32.dll", SetLastError=true)]
    static unsafe extern int GetLastError(); [dllimport("kernel32.dll", SetLastError=true)]
    static unsafe extern bool FlushFileBuffers(int hFile); [dllimport("kernel32.dll", SetLastError=true)]
    static unsafe extern bool PurgeComm(int hFile, uint dwFlags);
    } [StructLayout(LayoutKind.Sequential)]
    public struct SerialTimeouts {
    public int ReadIntervalTimeout;
    public int ReadTotalTimeoutMultiplier;
    public int ReadTotalTimeoutConstant;
    public int WriteTotalTimeoutMultiplier;
    public int WriteTotalTimeoutConstant; public SerialTimeouts(int r1, int r2, int r3, int w1, int w2) {
    ReadIntervalTimeout = r1;
    ReadTotalTimeoutMultiplier = r2;
    ReadTotalTimeoutConstant = r3;
    WriteTotalTimeoutMultiplier = w1;
    WriteTotalTimeoutConstant = w2;
    } public override string ToString() {
    return "ReadIntervalTimeout: " + ReadIntervalTimeout + "\r\n" +
       "ReadTotalTimeoutMultiplier: " + ReadTotalTimeoutMultiplier + "\r\n" +
       "ReadTotalTimeoutConstant: " + ReadTotalTimeoutConstant + "\r\n" +
       "WriteTotalTimeoutMultiplier: " + WriteTotalTimeoutMultiplier + "\r\n" +
       "WriteTotalTimeoutConstant: " + WriteTotalTimeoutConstant + "\r\n";
    }
    } public class SerialSettings {
    private bool m_bDirty = false;
    public bool Dirty { get { return m_bDirty; } } // Timeouts
    private SerialTimeouts Timeouts = new SerialTimeouts(1, 0, 0, 0, 0); public int ReadIntervalTimeout {
    get { return Timeouts.ReadIntervalTimeout; }
    set { if (Timeouts.ReadIntervalTimeout != value) {
      Timeouts.ReadIntervalTimeout = value;
      m_bDirty = true;
      }
    }
    } public int ReadTotalTimeoutMultiplier {
    get { return Timeouts.ReadTotalTimeoutMultiplier; }
    set { if (Timeouts.ReadTotalTimeoutMultiplier != value) {
    Timeouts.ReadTotalTimeoutMultiplier = value;
    m_bDirty = true;
      }
    }
    } public int ReadTotalTimeoutConstant {
    get { return Timeouts.ReadTotalTimeoutConstant; }
    set { if (Timeouts.ReadTotalTimeoutConstant != value) {
      Timeouts.ReadTotalTimeoutConstant = value;
      m_bDirty = true;
      }
    }
    } public int WriteTotalTimeoutMultiplier {
    get { return Timeouts.WriteTotalTimeoutMultiplier; }
    set { if (Timeouts.WriteTotalTimeoutMultiplier != value) {
      Timeouts.WriteTotalTimeoutMultiplier = value;
      m_bDirty = true;
      }
    }
    } public int WriteTotalTimeoutConstant {
    get { return Timeouts.WriteTotalTimeoutConstant; }
    set { if (Timeouts.WriteTotalTimeoutConstant != value) {
      Timeouts.WriteTotalTimeoutConstant = value;
      m_bDirty = true;
      }
    }
    } // Valid stuff
    private static readonly object[] s_iValidBitRates = new object[] {75u, 110u, 134u, 150u, 300u, 600u, 1200u, 1800u, 2400u, 4800u, 
    7200u, 9600u, 14400u, 19200u, 38400u, 57600u, 115200u, 128000u};
    public static object[] ValidBitRates {
    get { return s_iValidBitRates; }
    } private static readonly object[] s_iValidDataBits = new object[] {(byte)5, (byte)6, (byte)7, (byte)8};
    public static object[] ValidDataBits {
    get { return s_iValidDataBits; }
    } // Port settings
    private uint m_iBitRate = 57600;
    public uint BitRate {
    get { return m_iBitRate; }
    set { if (m_iBitRate != value) {
      m_iBitRate = value;
      m_bDirty = true;
      }
    }
    } private byte m_iDataBits = 8;
    public byte DataBits {
    get { return m_iDataBits; }
    set { if (m_iDataBits != value) {
      m_iDataBits = value;
      m_bDirty = true;
      }
    }
    } private SerialStream.Parity m_Parity = SerialStream.Parity.None;
    public SerialStream.Parity Parity {
    get { return m_Parity; }
    set { if (m_Parity != value) {
      m_Parity = value;
      m_bDirty = true;
      }
    }
    } private SerialStream.StopBits m_StopBits = SerialStream.StopBits.One;
    public SerialStream.StopBits StopBits {
    get { return m_StopBits; }
    set { if (m_StopBits != value) {
      m_StopBits = value;
      m_bDirty = true;
      }
    }
    } private SerialStream.FlowControl m_FlowControl = SerialStream.FlowControl.None;
    public SerialStream.FlowControl FlowControl {
    get { return m_FlowControl; }
    set { if (m_FlowControl != value) {
      m_FlowControl = value;
      m_bDirty = true;
      }
    }
    }
    }