C#利用短信猫收发短信息的方法

如今手机已成为大众的交流工具。有关手机的程序开发越来越广泛,本节通过几个典型实例介绍如何利用短信猫发送、接收短信、远程控制计算机、业务员销售数据采集和短信息娱乐互动平台。 实例431 利用短信猫收发短信息
如今手机已成为大众的交流工具。有关手机的程序开发越来越广泛,本节通过几个典型实例介绍如何利用短信猫发送、接收短信、远程控制计算机、业务员销售数据采集和短信息娱乐互动平台。
实例431 利用短信猫收发短信息
实例说明
短信猫是利用SIM卡发送短信的硬件设备,通过串口或USB接口(根据设备型号而定)与计算机相连。在程序中可以利用短信猫发送或接收短信。本例实现了利用短信猫收发短信息的功能。实例运行结果如图13.15所示。
技术要点
本例使用的是北京人大金仓信息技术有限公司的串口短信猫。在购买短信猫时会附带包括SDK的开发包,其中提供了操作短信猫的函数(封装在dllforvc.dll动态库中)。下面介绍操作短信猫的主要函数。
(1)GSMModemGetSnInfoNew函数
该函数获取短信猫注册需要的信息,代码如下:
    [DllImport("dllforvc.dll",
         EntryPoint = "GSMModemGetSnInfoNew",
         CharSet = CharSet.Ansi,
         CallingConvention = CallingConvention.StdCall)]
    public static extern string GSMModemGetSnInfoNew(string device, string baudrate);
参数说明如下。
l     device:通信端口,为null时系统会自动检测。
l     baudrate:通讯波特率,为null时系统会自动检测。
(2)GSMModemGetDevice函数
该函数获取当前的通讯端口,代码如下:
    [DllImport("dllforvc.dll",
         EntryPoint = "GSMModemGetDevice",
         CharSet = CharSet.Ansi,
         CallingConvention = CallingConvention.StdCall)]
    public static extern string GSMModemGetDevice();
(3)GSMModemGetBaudrate函数
该函数获取当前的通讯波特率,代码如下:
    [DllImport("dllforvc.dll",
         EntryPoint = "GSMModemGetBaudrate",
         CharSet = CharSet.Ansi,
         CallingConvention = CallingConvention.StdCall)]
    public static extern string GSMModemGetBaudrate();
(4)GSMModemInitNew函数
该函数用于初始化短信猫。语法如下:
    [DllImport("dllforvc.dll",
         EntryPoint = "GSMModemInitNew",
         CharSet = CharSet.Ansi,
         CallingConvention = CallingConvention.StdCall)]
    public static extern bool GSMModemInitNew(
        string device,
        string baudrate,
        string initstring,
        string charset,
        bool swHandshake,
        string sn);
参数说明如下。
l     device:标识通信端口,如果为NULL,系统会自动检测。
l     baudrate:标识通讯波特率,如果为NULL,系统会自动检测。
l     initstring:标识初始化命令,为NULL即可。
l     charset:标识通讯字符集,为NULL即可。
l     swHandshake:标识是否进行软件握手,为False即可。
l     sn:标识短信猫的授权号,需要根据实际情况填写。
(5)GSMModemSMSsend函数
该函数用于发送手机短信。语法如下:
    [DllImport("dllforvc.dll",
         EntryPoint = "GSMModemSMSsend",
         CharSet = CharSet.Ansi,
         CallingConvention = CallingConvention.StdCall)]
    public static extern bool GSMModemSMSsend(
        string serviceCenterAddress,
        int encodeval,
        string text,
        int textlen,
        string phonenumber,
        bool requestStatusReport);
参数说明如下。
l     serviceCenterAddress:标识短信中心号码,为NULL即可。
l     encodeval:标识短信息编码格式,如果为8,表示中文短信编码。
l     text:标识短信内容。
l     textlen:标识短信内容的长度。
l     phonenumber:标识接收短信的电话号码。
l     requestStatusReport:标识状态报告。
(6)GSMModemSMSReadAll函数
该函数取得所有短信息,包括SIM卡和手机中的短信息。返回的短信内容格式为电话号码1|短信内容1||电话号码2|短信内容2||:
    //接收短信息返回字符串格式为:手机号码|短信内容||手机号码|短信内容||
    //RD_opt为1表示接收短信息后不做任何处理,为0表示接收后删除信息
    [DllImport("dllforvc.dll",
         EntryPoint = "GSMModemSMSReadAll",
         CharSet = CharSet.Ansi,
         CallingConvention = CallingConvention.StdCall)]
    public static extern string GSMModemSMSReadAll(int RD_opt);
参数说明如下。
l     RD_opt:对读取后的短信息进行处理,0表示删除,1表示不做处理。
实现过程
(1)新建一个项目,命名为Ex13_14,默认窗体为Form1。
(2)在Form1窗体中,主要添加TextBox控件和Label控件,控件的数量及用途如图13.15所示,添加两个Button控件,分别用于发送短信息和接收短信息。
(3)主要程序代码。
将所使用的函数封装在GMS类中。代码如下:
class GMS
{
    //初始化gsm modem,并连接gsm modem
    [DllImport("dllforvc.dll",
         EntryPoint = "GSMModemInitNew",
         CharSet = CharSet.Ansi,
         CallingConvention = CallingConvention.StdCall)]
    public static extern bool GSMModemInitNew(
        string device,
        string baudrate,
        string initstring,
        string charset,
        bool swHandshake,
        string sn);
    //获取短信猫新的标识号码
    [DllImport("dllforvc.dll",
         EntryPoint = "GSMModemGetSnInfoNew",
         CharSet = CharSet.Ansi,
         CallingConvention = CallingConvention.StdCall)]
    public static extern string GSMModemGetSnInfoNew(string device, string baudrate);
    //获取当前通讯端口
    [DllImport("dllforvc.dll",
         EntryPoint = "GSMModemGetDevice",
         CharSet = CharSet.Ansi,
         CallingConvention = CallingConvention.StdCall)]
    public static extern string GSMModemGetDevice();
    //获取当前通讯波特率
    [DllImport("dllforvc.dll",
         EntryPoint = "GSMModemGetBaudrate",
         CharSet = CharSet.Ansi,
         CallingConvention = CallingConvention.StdCall)]
    public static extern string GSMModemGetBaudrate();
    //断开连接并释放内存空间        
    [DllImport("dllforvc.dll",
         EntryPoint = "GSMModemRelease",
         CharSet = CharSet.Ansi,
         CallingConvention = CallingConvention.StdCall)]
    public static extern void GSMModemRelease();
    //取得错误信息    
    [DllImport("dllforvc.dll",
         EntryPoint = "GSMModemGetErrorMsg",
         CharSet = CharSet.Ansi,
         CallingConvention = CallingConvention.StdCall)]
    public static extern string GSMModemGetErrorMsg();
    //发送短信息
    [DllImport("dllforvc.dll",
         EntryPoint = "GSMModemSMSsend",
         CharSet = CharSet.Ansi,
         CallingConvention = CallingConvention.StdCall)]
    public static extern bool GSMModemSMSsend(
        string serviceCenterAddress,
        int encodeval,
        string text,
        int textlen,
        string phonenumber,
        bool requestStatusReport);
    //接收短信息返回字符串格式为:手机号码|短信内容||手机号码|短信内容||
    //RD_opt为1接收短信息后不做任何处理,0为接收后删除信息
    [DllImport("dllforvc.dll",
         EntryPoint = "GSMModemSMSReadAll",
         CharSet = CharSet.Ansi,
         CallingConvention = CallingConvention.StdCall)]
    public static extern string GSMModemSMSReadAll(int RD_opt);
}
在装载Form1窗体时,获取设备信息。代码如下:
        private void Form1_Load(object sender, EventArgs e)
        {
            //机器号码,当参数为空时,函数自动获取设备信息
            txtJQHM.Text = GMS.GSMModemGetSnInfoNew(txtCOM.Text, txtBTL.Text);
            txtCOM.Text = GMS.GSMModemGetDevice();  //COM1
            txtBTL.Text= GMS.GSMModemGetBaudrate();  //波特率
        }
发送短信息。代码如下:
        private void btnSend_Click(object sender, EventArgs e)
        {
               if(txtSJHM.Text == "") 
               {
           MessageBox.Show("手机号码不能为空!","提示", MessageBoxButtons.OK);
                   txtSJHM.Focus();
                   return;
               }
               if(txtContent.Text=="")
               {
           MessageBox.Show("短信内容不能为空!", "提示", MessageBoxButtons.OK);
                   txtContent.Focus();
                   return;
               }
               //连接设备
               if(GMS.GSMModemInitNew(txtCOM.Text, txtBTL.Text, null, null, false, txtPower.Text)==false)
               {
                   MessageBox.Show("设备连接失败!" + GMS.GSMModemGetErrorMsg(),"提示", MessageBoxButtons.OK);
                   return;
               }
               // 发送短信
               if (GMS.GSMModemSMSsend(null, 8, txtContent.Text, Encoding.Default.GetByteCount(txtContent.Text),txtSJHM.Text, false) == true)
                   MessageBox.Show("短信发送成功!", "提示", MessageBoxButtons.OK);
               else
                   MessageBox.Show("短信发送失败!" + GMS.GSMModemGetErrorMsg(), "提示", MessageBoxButtons.OK);
        }
接收短信息。代码如下:
        private void btnResvice_Click(object sender, EventArgs e)
        {
            //1)连接设备
            if (GMS.GSMModemInitNew(txtCOM.Text, txtBTL.Text, null, null, false, txtPower.Text) == false)
            {
                MessageBox.Show("连接失败!" + GMS.GSMModemGetErrorMsg(), "提示", MessageBoxButtons.OK);
                return;
            }
            //2)接收短信
            txtContent.Text = GMS.GSMModemSMSReadAll(1);
            txtSJHM.Text = txtContent.Text.Substring(0, 13);
            txtContent.Text = txtContent.Text.Substring(13, txtContent.Text.Length-13);
        }
举一反三
根据本实例,读者可以开发以下程序。
利用短信猫群发短信。
办公自动化系统,办公短信通知、短信日程提醒、应急信息短信发布和短信审批等。
实例432 利用短信远程关闭计算机
实例说明
本例实现了利用短信远程关闭计算机的功能。运行程序,首先,进行关机信息设置;然后,开启服务;最后,通过手机向短信猫发送“关机”数据。片刻之后,指定的计算机将会自动关机。程序如图13.16所示。
技术要点
相关函数请参见实例“利用短信猫收发短信息”中的技术要点。
实现过程
(1)新建一个项目,命名为Ex13_15,默认窗体为Form1。
(2)在Form1窗体中,主要添加TextBox控件和Label控件,控件的数量及用途如图13.16所示,添加一个Button控件,用于开启或停止远程关闭计算机服务。
(3)主要程序代码。
        private void Form1_Load(object sender, EventArgs e)
        {
           //机器号码
            txtJQHM.Text = GMS.GSMModemGetSnInfoNew(txtCOM.Text, txtBTL.Text); 
            txtCOM.Text = GMS.GSMModemGetDevice();  //COM1
            txtBTL.Text = GMS.GSMModemGetBaudrate();  //波特率
            labStatus.Text = "服务关闭中。。。。。";
        }
        private void Close_Windows()
        {
            try
            {
                //指定生成 WMI 连接所需的所有设置
                ConnectionOptions op = new ConnectionOptions();
                op.Username = txtUser.Text; //远程计算机用户名称
                op.Password = txtPWD.Text;   //远程计算机用户密码
                //设置操作管理范围
         ManagementScope scope = new ManagementScope("\\\\" + txtIP.Text + "\\root\\cimv2", op);
                scope.Connect(); //将此 ManagementScope 连接到实际的 WMI 范围。
                ObjectQuery oq = new ObjectQuery("SELECT * FROM Win32_OperatingSystem");
             ManagementObjectSearcher query = new ManagementObjectSearcher(scope, oq);
                //得到WMI控制 
                ManagementObjectCollection queryCollection = query.Get();
                foreach (ManagementObject obj in queryCollection)
                {
                  obj.InvokeMethod("ShutDown", null); //执行关闭远程计算机
                }
            }
            catch(Exception ex)
            {
                Process p = new Process();
                p.StartInfo.FileName = "cmd.exe";
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.RedirectStandardInput = true;
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.RedirectStandardError = true;
                p.StartInfo.CreateNoWindow = true;
                p.Start();
                p.StandardInput.WriteLine("shutdown /s");
                p.StandardInput.WriteLine("exit");
            }
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            //连接设备
            if (GMS.GSMModemInitNew(txtCOM.Text, txtBTL.Text, null, null, false, txtPower.Text) == false)
            {
                MessageBox.Show("连接失败!" + GMS.GSMModemGetErrorMsg(), "提示", MessageBoxButtons.OK);
                return;
            }
            //接收短信
            string str = GMS.GSMModemSMSReadAll(1);
            if (str==null)
                return;
            if (str.Substring(str.IndexOf("|")+1, 2) == "关机")
            {
                this.Close_Windows();
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            if (button1.Text == "开启服务")
            {
                timer1.Enabled = true;
                labStatus.Text = "关机命令采集中。。。。。";
                button1.Text = "停止服务";
            }
            else
            {
                timer1.Enabled = false;
                button1.Text = "开启服务";
                labStatus.Text = "服务关闭中。。。。。";
            }
        }
举一反三
根据本实例,读者可以实现以下功能。
利用短信实现客户资料查询。
保险行业中:保单查询、续费提醒、客户生日提醒和保费计算等。
实例433 短信息采集烟草销售数据
实例说明
在各类销售行业中,产品销售数据量是企业不可缺少的一项数据。当销售人员在外地出差并且在没有计算机的情况下,如何及时的将销售数据汇报到公司中呢?
本例实现利用短信息采集烟草销售数据的功能。销售人员根据规定的格式编辑短信发送到短信息猫中即可。运行程序,单击【烟草销售信息采集】按钮采集烟草销售数据,然后单击【统计】按钮,将销售数据整理出来。如图13.17所示。
技术要点
相关函数请参见实例“利用短信猫收发短信息”中的技术要点。
另外,程序规定的编辑短信息格式为,以冒号“:”分隔并结束。例如“张三:业务员:12:长春:3400:”。其中,主要使用String.Split( )方法将信息数据拆分。

图13.17 短信息采集烟草销售数据
String.Split( )方法:返回包含此实例中的子字符串(由指定 Char 数组的元素分隔)的 String 数组。
语法:
public string[] Split (
    params char[] separator
)
参数说明如下。
l     separator:分隔此实例中子字符串的 Unicode 字符数组,不包含分隔符的空数组或空引用。
l     返回值:一个数组,其元素包含此实例中的子字符串,这些子字符串由 separator 中的一个或多个字符分隔。
实现过程
(1)新建一个项目,命名为Ex13_16,默认窗体为Form1。
(2)在Form1窗体中,主要添加TextBox控件和Label控件,控件的数量及用途如图13.17所示,添加3个Button控件,分别用于发送短信息、采集销售数据和整理采集数据,添加两个DataGridView表格,分别用于显示短信息内容和整理后的销售数据。
(3)主要程序代码。
单击【烟草销售信息采集】按钮,接受短信息并保存到数据库中。代码如下:
          private void btnResvice_Click(object sender, EventArgs e)
        {
            //连接设备
            if (GMS.GSMModemInitNew(txtCOM.Text, txtBTL.Text, null, null, false, txtPower.Text) == false)
            {
                MessageBox.Show("连接失败!" + GMS.GSMModemGetErrorMsg(), "提示", MessageBoxButtons.OK);
                return;
            }
            //接收短信
            string content = GMS.GSMModemSMSReadAll(0);
            if (content ==null)
            {
                this.getMessage();
                return;
            }
            content= content.Replace("||", "|"); // 替换||为|
            string[] str_sp = content.Split('|');// 进行分离
            int k=0;
            dataGridView1.ColumnCount = 2;
            dataGridView1.RowCount = str_sp.Length / 2;
            dataGridView1.Columns[0].HeaderText = "手机号码";
            dataGridView1.Columns[1].HeaderText = "短信息";
            for (int i = 0; i < str_sp.Length / 2; i++)
            {
                for (int j = 0; j < 2; j++)
                {
                    dataGridView1[j, i].Value = str_sp[k];
                    if (k % 2 != 0)
                        this.InsertMessage("insert into RecivedBox (Mobile,Content,reciveTime)values('" + Convert.ToString(dataGridView1[0, i].Value) + "','" + Convert.ToString(dataGridView1[1, i].Value) + "','" + DateTime.Now.ToString() + "') ");
                    k++;
                }
            }
            this.getMessage();
        }
自定义方法getSplitMessage()用来拆分短信息并且整理为正规数据。代码如下:
        private void getSplitMessage()
        {
            string content = "";
            for (int i = 0; i < dataGridView1.Rows.Count; i++)
            {
                content = content + Convert.ToString(dataGridView1["短信息", i].Value);
            }
            string[] str_sp = content.Split(':');// 进行分离
            int k = 0;
            dataGridView2.ColumnCount = 5;
            dataGridView2.RowCount = str_sp.Length/5 ;
            dataGridView2.Columns[0].HeaderText = "姓名";
            dataGridView2.Columns[1].HeaderText = "职务";
            dataGridView2.Columns[2].HeaderText = "月份";
            dataGridView2.Columns[3].HeaderText = "销售地区";
            dataGridView2.Columns[4].HeaderText = "销售数量";
            for (int i = 0; i < str_sp.Length / 5; i++)
            {
                for (int j = 0; j < 5; j++)
                {
                    dataGridView2[j, i].Value = str_sp[k];
                    k++;
                }
            }
        }
自定义InsertMessage()方法,将接受的短信息保存到数据库中。代码如下:
        private void InsertMessage(string strSql)
        {
            //将短信息内容添加到数据库中
            OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + "message.mdb" + ";Persist Security Info=False");
            con.Open();
            OleDbCommand cmd = new OleDbCommand(strSql, con);
            cmd.ExecuteNonQuery();
            con.Close();
        }
自定义getMessage()方法,获取数据库中所有的短信息数据。代码如下:
        private void getMessage()
        {
            OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + "message.mdb" + ";Persist Security Info=False");
            OleDbDataAdapter dap = new OleDbDataAdapter("select mobile as 手机号码,content as 短信息,reciveTime as 日期 from RecivedBox", con);
            DataSet ds = new DataSet();
            dap.Fill(ds);
            dataGridView1.DataSource = ds.Tables[0].DefaultView;
        }
调用自定义getSplitMessage()方法,将整理后的销售数据显示在DataGridView表格中。代码如下:
        private void btnFind_Click(object sender, EventArgs e)
        {
            if(dataGridView1.Rows.Count>0)
            this.getSplitMessage();

        } 

你可能感兴趣的:(C#)