Delong_z 发表于 2009-4-13 22:25:07

[原创]发布《串口调试助手V1.0》程序+C#源码

在 OurAVR 论坛潜水已经有一年多了,在这里下载了不少好的资料,今天把我的第一个 C# 程序和源代码共享出来,供大家交流学习,请高手多多指教。
本来想用 VB 的, N 年前学过一点点,现在忘得差不多了。近年来一直在做单片机编程,对 C 比较熟悉,所以决定用 C# ,一周下来,弄出了这个东东。
个人认为 C#=VB+C。(VB 的界面,C 的语法)。比较适合搞单片机的人学习上位机编程,容易上手。说得不对的地方,请多包涵。


串口调试助手V1.0
共享软件

软件描述:
1、自动检测系统串口数量,如有USB转串口设备插入,即插即用,自动添加到下拉列表框。
2、修改端口设置后自动打开串口。
3、可以发送字符、十六进制数据。
4、字符和十六进制数据可以定时循环发送。
5、支持自定义帧格式,自动加入校验。可选和校验和异或校验。
6、有十进制<-->十六进制互转功能,方便参数计算。
7、接收分别以字符和十六进制显示,完美支持中文显示和回车换行。可以自动滚屏,自动清屏。
8、单击接收到的十六进制数据,可以自动解码成十进制有符号和无符号数据,方便调试通讯协议。

开发说明:
本软件是我为了方便自己产品开发,利用业余时间而编写的。这也是我初学 VS2005 一周以来,设计的第一款 Windows 应用程序。
针对自己定义的通讯协议,增加了一些实用的解码功能,方便自己调试程序。
这是免费软件,可以随意复制。在使用过程中有任何意见或建议,可以通过如下方式与我联系:
QQ:        357641612
E-Mail:Delong_z@163.com

本软件采用 Microsoft Visual Studio 2005 开发,需要安装 Microsoft .Net Framework 2.0 支持才能工作。



重庆阿尔舍电子技术有限公司
      钟   慰
   2009年4月13日


http://cache.amobbs.com/bbs_upload782111/files_14/ourdev_436157.JPG
程序主界面 (原文件名:SerialComm.JPG)

安装程序ourdev_436158.rar(文件大小:455K) (原文件名:SerialCommSetup.rar)

C#2005源代码ourdev_436169.rar(文件大小:239K) (原文件名:SerialComm.rar)

关键源码在6楼,除了解决串口线程死锁相关部分外,其它的都比较简单。解决死锁问题主要参考网上的一篇文章来改写的。只有在不停接收数据时关闭串口时,才有可能死锁,经过改进,这种几率已经比较小了。万一死锁了,用鼠标右键在程序任务栏右击程序几下就可以恢复。

ch2003_23 发表于 2009-4-13 22:42:35

高手啊 顶……

END12345678 发表于 2009-4-14 03:09:51

要装控件吧

zhwm3064 发表于 2009-4-14 06:09:10

谢谢

1181zjf 发表于 2009-4-14 07:41:41

顶!

jjj206 发表于 2009-4-14 08:15:02

不得不顶呀!

Delong_z 发表于 2009-4-14 09:39:32

源码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;

namespace SerialComm
{
    public partial class Form1 : Form
    {
      //===================================================
      //申明全局变量。
      public int CmdIdx = 0;          //命令发送指针初始为0。
      bool IsReceving = false;      //接收数据标志。
      bool DoingStr = false;          //处理字符串标志。
      bool DoingHex = false;          //处理十六进制标志。
      //===================================================

      public Form1()
      {
            InitializeComponent();
      }      

      private void IntToHex()
      {
            try
            {
                int Int = int.Parse(tbDec.Text);
                string TempStr = Convert.ToString(Int, 16);
                while(TempStr.Length < 8 )
                  TempStr = '0' + TempStr;
                tbHex.Text = TempStr.ToUpper();
                tbDec.SelectAll();
            }
            catch (Exception Err)
            {
                tbDec.SelectAll();
                MessageBox.Show(Err.Message, "串口调试助手");
            }
      }

      private void HexToInt()
      {
            try
            {
                int Int = Convert.ToInt32(tbHex.Text,16);
                tbDec.Text = Int.ToString();
                tbHex.SelectAll();
            }
            catch (Exception Err)
            {
                tbHex.SelectAll();
                MessageBox.Show(Err.Message, "串口调试助手");
            }
      }

      private void CmdClick(int idx)
      {   //发送命令。
            try
            {
                //自动打开端口。
                if (!sComm.IsOpen)
                  btOpen_Click(null, null);

                string TempStr = string.Empty;
                switch(idx)
                {
                  case 1:
                        TempStr = tbCmd1.Text;
                        break;
                  case 2:
                        TempStr = tbCmd2.Text;
                        break;
                  case 3:
                        TempStr = tbCmd3.Text;
                        break;
                  case 4:
                        TempStr = tbCmd4.Text;
                        break;
                  case 5:
                        TempStr = tbCmd5.Text;
                        break;
                  default:
                        return;
                }

                TempStr = DelSpace(TempStr);

                if (cbDefFrm.Checked)   //自动添加帧头帧尾和校验
                {
                  TempStr=DelSpace(tbStart.Text)+TempStr;   //加入头。

                  //转换为字节数组。
                  int Len=TempStr.Length;         //待校验的字符串长度。
                  byte[] VerBin = new byte;
                  int j=0;
                  for(int i=0;i<Len;i+=2,j++)
                  {
                        VerBin = Convert.ToByte(TempStr.Substring(i, 2), 16);
                  }
                  //计算校验字节。
                  byte VerByte=0;
                  if (rdXor.Checked)
                  {
                        for (int i = 0; i < VerBin.Length; i++)
                            VerByte ^= VerBin;   //异或校验。
                        
                  }
                  else if (rdAdd.Checked)
                  {
                        for (int i = 0; i < VerBin.Length; i++)
                            VerByte += VerBin;   //和校验。
                  }
                  //校验字节转为HEX字符串。
                  string VerStr = Convert.ToString(VerByte, 16);
                  //合成一帧。
                  TempStr = TempStr + DelSpace(VerStr) + DelSpace(tbEnd.Text);
                }

                SendAsHex(TempStr);
            }
            catch (Exception err)
            {
                TimeHex.Stop();
                TimeHex.Enabled = false;
                MessageBox.Show(err.Message, "串口调试助手");
                cbTimeHex.Checked = false;
            }
      }

      private void ClrEncode()
      {
            lbHexData.Text = string.Empty;

            tbByte1.Text = string.Empty;
            tbByte2.Text = string.Empty;
            tbByte3.Text = string.Empty;
            tbByte4.Text = string.Empty;
            tbUInt16L.Text = string.Empty;
            tbUInt16R.Text = string.Empty;
            tbUInt32.Text = string.Empty;

            tbSByte1.Text = string.Empty;
            tbSByte2.Text = string.Empty;
            tbSByte3.Text = string.Empty;
            tbSByte4.Text = string.Empty;
            tbInt16L.Text = string.Empty;
            tbInt16R.Text = string.Empty;
            tbInt32.Text = string.Empty;
      }

      private void SendAsHex(string str)
      {
            int Len = str.Length;            
            //组包发送。
            byte[] send = new byte;
            int j = 0;
            for (int i = 0; i < Len; i = i + 2, j++)
                send = Convert.ToByte(str.Substring(i, 2), 16);
            sComm.Write(send, 0, send.Length);
      }

      //清除空格。
      private string DelSpace(string str)
      {            
            string TempStr = string.Empty;
            int Len = str.Length;
            for (int i = 0; i < Len; i++)
            {
                if (str != ' ')
                  TempStr += str;
            }
            //Hex 位数检查。
            Len = TempStr.Length;
            if (Len % 2 != 0)
                TempStr = '0' + TempStr;
            return TempStr;
      }

      //重新打开端口。
      private void ReOpenPort()
      {
            try
            {
                btClose_Click(null,null);
                //重新打开通讯端口。
                if (!sComm.IsOpen)
                  btOpen_Click(null, null);
            }
            catch (Exception Err)
            {
                MessageBox.Show(Err.Message, "串口调试助手");
            }
      }

      private void Form1_Load(object sender, EventArgs e)
      {
            try
            {
                foreach (string com in System.IO.Ports.SerialPort.GetPortNames())//自动获取串行口名称
                  this.cmPort.Items.Add(com);
                cmPort.SelectedIndex = 0;
            }
            catch
            {
                MessageBox.Show("找不到通讯端口!", "串口调试助手");
            }
      }

      private void OpenPort()
      {
            //***避免串口死锁***
            sComm.WriteTimeout = 1000;//写超时,如果底层串口驱动效率问题,能有效的避免死锁。
            sComm.ReadTimeout = 1000;   //读超时,同上。
            sComm.NewLine = "\r\n";   //回车换行。
            sComm.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.sComm_DataReceived);   //注册事件。
            //***避免串口死锁***

            sComm.PortName = cmPort.Text;
            sComm.BaudRate = int.Parse(cmBaudRate.Text);
            sComm.DataBits = int.Parse(cmDataBit.Text);
            sComm.Parity = (Parity)Enum.Parse(typeof(Parity), cmParity.Text);
            sComm.StopBits = (StopBits)Enum.Parse(typeof(StopBits), cmStopBit.Text);
            sComm.Open();
      }

      private void ClosePort()
      {
            //安全关闭当前串口。
            //***避免串口死锁***
            sComm.DataReceived -= this.sComm_DataReceived;   //注销串口中断接收事件,避免下次再执行进来,造成死锁。
            while(IsReceving)
                Application.DoEvents();   //处理串口接收事件及其它系统消息。
            sComm.Close();                  //现在没有死锁,可以关闭串口。
            //***避免串口死锁***
      }

      private void StopAutoSend()
      {
            //停止自动发送字符串。
            TimeStr.Stop();
            TimeStr.Enabled = false;
            tbTimeStr.Enabled = true;
            cbTimeStr.Checked = false;
            //停止自动发送命令。
            TimeHex.Stop();
            TimeHex.Enabled = false;
            tbTimeHex.Enabled = true;
            cbTimeHex.Checked = false;
      }
      //===================================================

      private void btOpen_Click(object sender, EventArgs e)
      {
            try
            {
                OpenPort();   //安全打开串口。
                if (sComm.IsOpen)
                {
                  btClose.Enabled = true;
                  btOpen.Enabled = false;
                  lbComStat.Text = "已打开 " + Convert.ToString(sComm.PortName) + ' ' + Convert.ToString(sComm.BaudRate) + ' ' + Convert.ToString(sComm.DataBits) + ' ' + Convert.ToString(sComm.Parity) + ' ' + Convert.ToString(sComm.StopBits);
                  tbSendStr.Focus();
                }
            }
            catch (Exception er)
            {
                StopAutoSend(); //停止自动发送。
                ClosePort();    //安全关闭当前串口。
                MessageBox.Show("端口打开失败!" + er.Message, "串口调试助手");
                lbComStat.Text = "已关闭";
            }
      }

      private void btSend_Click(object sender, EventArgs e)
      {
            //自动打开端口。
            if (!sComm.IsOpen)
                btOpen_Click(null, null);
            //发送文本。
            try
            {
                string txt = tbSendStr.Text;
                Byte[] EncodeByte = new byte;
                EncodeByte = Encoding.GetEncoding("GB2312").GetBytes(txt);
                int Len = EncodeByte.Length;
                sComm.Write(EncodeByte, 0, Len);
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message, "串口调试助手");
            }
      }

      private void btClrSend_Click(object sender, EventArgs e)
      {
            tbSendStr.Text = string.Empty;
      }

      private void cmPort_MouseDown(object sender, MouseEventArgs e)
      {
            try
            {
                cmPort.Items.Clear();
                foreach (string com in System.IO.Ports.SerialPort.GetPortNames())//自动获取串行口名称
                  this.cmPort.Items.Add(com);
            }
            catch
            {
                MessageBox.Show("找不到通讯端口!", "串口调试助手");
            }
      }

      private void sComm_DataReceived(object sender, SerialDataReceivedEventArgs e)
      {
            try
            {
                IsReceving = true;//***正在接收状态指示。
                //读入收到的数据。
                int Len = sComm.BytesToRead;
                if (Len < 1)
                {
                  IsReceving = false;//***接收完成状态指示。
                  return;
                }

                byte[] data = new byte;
                sComm.Read(data, 0, Len);

                //字符串处理。
                string Str = Encoding.GetEncoding("GB2312").GetString(data);

                //数据转十六进制字符串。
                string Hex = string.Empty;
                for (int i = 0; i < data.Length; i++)
                {
                  string tempstr = Convert.ToString(data, 16);
                  if (tempstr.Length < 2)
                        tempstr = '0' + tempstr;
                  Hex += tempstr + ' ';
                }
                Hex = Hex.ToUpper();

                //使用委托跨线程读取数据。
                rtbRecStr.Invoke(new EventHandler(delegate
                {
                  DoingStr = true;    //***正在处理字符串。

                  rtbRecStr.AppendText(Str);
                  if (cbAutoClr.Checked && rtbRecStr.Text.Length > 10000)
                        rtbRecStr.Text = string.Empty;
                  rtbRecStr.ScrollToCaret();      //将控件的内容滚动到当前位置。

                  DoingStr = false;
                }
                ));

                rtbRecHex.Invoke(new EventHandler(delegate
                {
                  DoingHex = true;    //***正在处理十六进制数据。

                  rtbRecHex.AppendText(Hex);
                  if (cbAutoClr.Checked && rtbRecHex.Text.Length > 10000)
                        rtbRecHex.Text = string.Empty;
                  rtbRecHex.ScrollToCaret();      //将控件的内容滚动到当前位置。

                  DoingHex = false;
                }
                ));
            
                while(DoingStr || DoingHex)
                  Application.DoEvents();   //处理串口接收事件及其它系统消息。
                IsReceving =false;//***接收完成状态指示。
            }
            catch (Exception Err)
            {
                MessageBox.Show(Err.Message, "串口调试助手");
            }
      }

      private void btClrRec_Click(object sender, EventArgs e)
      {
            rtbRecStr.Text = string.Empty;
            rtbRecHex.Text = string.Empty;
            ClrEncode();
      }

      private void rtbRecHex_MouseClick(object sender, MouseEventArgs e)
      {
            try
            {
                int idx = rtbRecHex.SelectionStart / 3;
                idx *= 3;
                if (rtbRecHex.Text.Length >= idx + 4 * 3)
                {
                  rtbRecHex.Select(idx, 4 * 3);
                  string SubStr = rtbRecHex.Text.Substring(idx, 4 * 3);
                  lbHexData.Text = SubStr;
                  string[] TempStr = SubStr.Split(' ');
                  string[] Frm=new string;
                  if(rdBig.Checked)
                  {   //直接拷贝。
                        Array.Copy(TempStr, Frm, Frm.Length);
                  }
                  else
                  {   //前后交换。
                        Frm = TempStr;
                        Frm = TempStr;
                        Frm = TempStr;
                        Frm = TempStr;
                  }
                  //数据解码。
                  tbByte1.Text = Convert.ToString(Convert.ToByte(Frm, 16), 10);
                  tbByte2.Text = Convert.ToString(Convert.ToByte(Frm, 16), 10);
                  tbByte3.Text = Convert.ToString(Convert.ToByte(Frm, 16), 10);
                  tbByte4.Text = Convert.ToString(Convert.ToByte(Frm, 16), 10);
                  tbUInt16L.Text = Convert.ToString(Convert.ToUInt16(Frm + Frm, 16), 10);
                  tbUInt16R.Text = Convert.ToString(Convert.ToUInt16(Frm + Frm, 16), 10);
                  tbUInt32.Text = Convert.ToString(Convert.ToUInt32(Frm + Frm + Frm + Frm, 16), 10);

                  tbSByte1.Text = Convert.ToString(Convert.ToSByte(Frm, 16), 10);
                  tbSByte2.Text = Convert.ToString(Convert.ToSByte(Frm, 16), 10);
                  tbSByte3.Text = Convert.ToString(Convert.ToSByte(Frm, 16), 10);
                  tbSByte4.Text = Convert.ToString(Convert.ToSByte(Frm, 16), 10);
                  tbInt16L.Text = Convert.ToString(Convert.ToInt16(Frm + Frm, 16), 10);
                  tbInt16R.Text = Convert.ToString(Convert.ToInt16(Frm + Frm, 16), 10);
                  tbInt32.Text = Convert.ToString(Convert.ToInt32(Frm + Frm + Frm + Frm, 16), 10);
                }
                else
                {
                  ClrEncode();
                }
            }
            catch (Exception Err)
            {
                MessageBox.Show(Err.Message, "串口调试助手");
            }
      }

      private void rdBig_CheckedChanged(object sender, EventArgs e)
      {
            rtbRecHex_MouseClick(null, null);   //重新刷新数据解码。
      }

      private void cbDefFrm_CheckedChanged(object sender, EventArgs e)
      {
            if (cbDefFrm.Checked)
            {
                gpDefFrm.Enabled = true;
            }
            else
            {
                gpDefFrm.Enabled = false;
            }
      }

      private void cbTimeHex_CheckedChanged(object sender, EventArgs e)
      {
            try
            {
                if (cbTimeHex.Checked)
                {
                  //禁止Str自动发送。
                  cbTimeStr.Checked = false;

                  int t=int.Parse(tbTimeHex.Text);
                  if (t < 5)
                  {
                        t = 5;
                        tbTimeHex.Text = Convert.ToString(t,10);
                  }
                  //起动Hex自动发送。
                  tbTimeHex.Enabled = false;
                  TimeHex.Enabled = true;
                  TimeHex.Interval = t;
                  TimeHex.Start();
                }
                else
                {
                  TimeHex.Stop();
                  TimeHex.Enabled = false;
                  tbTimeHex.Enabled = true;
                }
            }
            catch (Exception Err)
            {
                MessageBox.Show("定时值不正确!" + Err.Message, "串口调试助手");
            }
      }

      private void cbTimeStr_CheckedChanged(object sender, EventArgs e)
      {
            try
            {
                if (cbTimeStr.Checked)
                {
                  //禁止Hex自动发送。
                  cbTimeHex.Checked = false;

                  int t = int.Parse(tbTimeStr.Text);
                  if (t < 5)
                  {
                        t = 5;
                        tbTimeStr.Text = Convert.ToString(t,10);
                  }
                  //启动Str自动发送。
                  tbTimeStr.Enabled = false;
                  TimeStr.Enabled = true;
                  TimeStr.Interval = t;
                  TimeStr.Start();
                }
                else
                {
                  TimeStr.Stop();
                  TimeStr.Enabled = false;
                  tbTimeStr.Enabled = true;
                }
            }
            catch (Exception Err)
            {
                MessageBox.Show("定时值不正确!" + Err.Message, "串口调试助手");
            }
      }

      private void btCmd1_Click(object sender, EventArgs e)
      {
            CmdClick(1);
      }

      private void btCmd2_Click(object sender, EventArgs e)
      {
            CmdClick(2);
      }

      private void btCmd3_Click(object sender, EventArgs e)
      {
            CmdClick(3);
      }

      private void btCmd4_Click(object sender, EventArgs e)
      {
            CmdClick(4);
      }

      private void btCmd5_Click(object sender, EventArgs e)
      {
            CmdClick(5);
      }

      private void cmPort_SelectedIndexChanged(object sender, EventArgs e)
      {
            ReOpenPort();
      }

      private void cmBaudRate_SelectedIndexChanged(object sender, EventArgs e)
      {
            ReOpenPort();
      }

      private void cmDataBit_SelectedIndexChanged(object sender, EventArgs e)
      {
            ReOpenPort();
      }

      private void cmParity_SelectedIndexChanged(object sender, EventArgs e)
      {
            ReOpenPort();
      }

      private void cmStopBit_SelectedIndexChanged(object sender, EventArgs e)
      {
            ReOpenPort();
      }

      private void TimeHex_Tick(object sender, EventArgs e)
      {
            try
            {
                int[] Len ={ tbCmd1.Text.Length,tbCmd2.Text.Length,tbCmd3.Text.Length,tbCmd4.Text.Length,tbCmd5.Text.Length};
                int j = 0;
                int OldIdx=CmdIdx;
                for (int i = OldIdx; i<OldIdx+5; i++)
                {
                  CmdIdx %= 5;
                  j = i % 5;
                  if (CmdIdx == j)
                  {
                        CmdIdx++;
                        if (Len > 0)
                        {
                            CmdClick(CmdIdx);
                            return;
                        }
                  }
                }
            }
            catch (Exception Err)
            {
                MessageBox.Show("定时发送错误!" + Err.Message, "串口调试助手");
                cbTimeHex.Checked = false;
            }
      }

      private void TimeStr_Tick(object sender, EventArgs e)
      {
            try
            {
                btSend_Click(null, null);
            }
            catch (Exception Err)
            {
                MessageBox.Show("定时发送错误!" + Err.Message, "串口调试助手");
                cbTimeStr.Checked = false;
            }

      }

      private void tbDec_KeyPress(object sender, KeyPressEventArgs e)
      {
            if (e.KeyChar == '\r')//回车键
                IntToHex();   //转换为Hex。
      }

      private void tbDec_Leave(object sender, EventArgs e)
      {
            IntToHex();
      }

      private void tbHex_KeyPress(object sender, KeyPressEventArgs e)
      {
            if (e.KeyChar == '\r')//回车键
            {
                while (tbHex.Text.Length < 8)
                  tbHex.Text = '0' + tbHex.Text;
                HexToInt();         //转换为Dec。
            }
      }

      private void tbHex_Leave(object sender, EventArgs e)
      {
            while (tbHex.Text.Length < 8)
                tbHex.Text = '0' + tbHex.Text;
            HexToInt();             //转换为Dec。
      }

      private void btClose_Click(object sender, EventArgs e)
      {
            StopAutoSend(); //停止自动发送。
            ClosePort();    //安全关闭串口。
            if (!sComm.IsOpen)
            {
                btOpen.Enabled = true;
                btClose.Enabled = false;
                lbComStat.Text = "已关闭";
            }
      }

      private void btQuit_Click(object sender, EventArgs e)
      {
            btClose_Click(null, null);
            this.Close();
      }
      //===================================================
    }
}

loongsuns 发表于 2009-4-14 13:41:53

这个有用 收藏了

yin66 发表于 2009-4-14 13:44:17

mark

Delong_z 发表于 2009-4-14 19:42:36

需要 Microsoft .Net Framework 2.0 库支持,本来想把库也加到安装程序里的,但有点大了,不方便上传,安装时它会自动从微软官方网站上下载组件。如果你已经安装过 .Net 的库,那安装程序会跳过下载安装的步骤,几秒钟就安装完了。

avrandfootball 发表于 2009-4-14 22:37:00

擦擦!

phone 发表于 2009-4-14 23:30:55

需要 Microsoft .Net Framework 2.0 库支持,能不能换成vc6写的?

wormchen 发表于 2009-4-15 09:01:31

我自己也写过,不过比较简单,没楼主的功能多!

xcodes 发表于 2009-4-15 09:04:20

其实用脚本是一样一样一样一样的

anylon 发表于 2009-4-15 09:19:14

谢谢!

weilight2008 发表于 2009-4-15 09:22:58

mark////////

dachun 发表于 2009-4-15 10:39:19

不错,不错!感觉好极了!

sjzd 发表于 2009-4-15 10:50:49

mark

ZRJ8951 发表于 2009-4-15 14:00:32

Delong_z 发表于 2009-4-16 09:29:40

回11楼,以前学VC,还专门下载了视频教程来看,但都是看得云里雾里的。MFC搞得人头晕。
VC功能确实很不错,但不好学,所以我还是选择简单易懂的语言来编写,更何况 C# 的功能也不弱,也还简单。几天就学会了。

li775662823 发表于 2010-4-8 15:00:15

上面的那个sComm 在哪里定义的啊?

lbc___ 发表于 2010-4-8 15:10:36

回复【楼主位】Delong_z
-----------------------------------------------------------------------

好东西,用C# vs2005在windows下做界面和串口,的确非常方便

wsm80828 发表于 2010-7-14 08:29:40

mark

1181zjf 发表于 2010-7-14 09:23:50

mark

lou0908 发表于 2010-7-14 13:07:02

bj

yaowszhang 发表于 2010-8-6 23:10:04

发送中文乱码如何解决

wsm80828 发表于 2010-8-7 07:54:15

纯顶了!

yyj_sd 发表于 2010-8-7 08:54:46

mark,学习了。

lsw0136 发表于 2010-8-7 10:21:57

mark

32dong809 发表于 2010-8-7 11:44:02

楼主强!

ndt2000 发表于 2010-12-1 16:34:16

mark

an1988 发表于 2011-1-19 16:59:58

mark

lixupeng 发表于 2011-1-19 20:41:51

学习下!!!

pjdu 发表于 2011-1-20 11:25:40

同意

SamuelSiu 发表于 2011-2-15 16:40:36

mark

Delong_z 发表于 2011-3-31 15:12:38

对了,有朋友反映不能编译,只要在工程属性的 签名 一栏里把 “为 ClickOnce 清单签名”取消钩选即可。

sangreal 发表于 2011-3-31 15:25:35

标记下

skywym 发表于 2011-5-25 16:19:03

mark

lee345 发表于 2011-5-31 16:10:06

用下C#,谢

monkhooder 发表于 2011-5-31 17:10:31

其实我喜欢C++的

416446891 发表于 2011-5-31 18:20:51

MARK

zbb8637 发表于 2011-6-1 13:22:53

zxs2000 发表于 2011-7-28 17:30:42

mark

myhonour 发表于 2011-9-5 14:41:39

mark

summarize 发表于 2011-9-5 23:43:31

为什么没有发送文件项呢?

caoning10 发表于 2011-12-25 10:11:23

mark

HYLG 发表于 2011-12-25 10:29:08

这个要顶,必须的。

saluo 发表于 2012-1-15 13:28:33

mark

ymgfc 发表于 2012-1-17 02:45:32

学习了,我之前用C#写了一个类似的,尽管已经释放串口变量,但是在关闭窗体的时候还是假死,一直没有解决

goldrained 发表于 2012-1-17 15:01:19

标记一下

armecos 发表于 2012-1-17 15:11:19

bsyg2323 发表于 2012-1-18 00:00:28

真心好东西,保留起来学习

williamrain 发表于 2012-1-20 22:27:33

mark

fjcw 发表于 2012-8-16 10:18:38

好东西!
谢谢!

wangku001wei 发表于 2012-8-17 20:53:24

不错不错谢谢楼主

SCS_Super 发表于 2012-8-31 20:04:51

有谁能放些C#的学习资料就好了。。这方面比较少!

yfgww 发表于 2012-9-10 11:19:46

mark{:smile:}{:smile:}

huyang27 发表于 2012-10-8 10:44:31

高手,不得不顶

guohuoping 发表于 2012-10-8 17:54:39

谢谢!牛人!佩服!
页: [1]
查看完整版本: [原创]发布《串口调试助手V1.0》程序+C#源码