老瓶裝新酒 - C#調用WM手機發送短信(源碼)


一些系統,需要能夠發送短信,量很小,平均每日10條。
運營商平台太貴,白名單很嚴格,小額只能發省內;
各短信平台有各種限制,大事件前后會關閉;
飛信以前可以用WAP發,但是現在多了驗證碼,搞不定了;
短信貓買來還得寫控制程序,價錢和時間上……


手上有兩部廢棄的WM手機,沒有故障,只是老舊不好用!


有一個WM軟件(后面有下載),它在WM手機上開啟一個Http服務器,使得我們可以在PC上通過瀏覽器直接訪問!

AP{_O6V~()@5J%NKJA$]5UC

S{9YYV(0SD)`I]`{)_PLD77

有收發短信的功能!
把手機WiFi性能跳到最大,關閉每x分鍾限制自動關閉;軟件設置自動開啟服務,關閉“運行時防止休眠”(它設計上有BUG,這個會導致服務10分鍾就關閉),拉到啟動目錄設為自動啟動。

OK!就是它了,我們寫個程序包裝一下,偽造為Web操作收發短信!


主要代碼如下:

View Code
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using NewLife;
using NewLife.Linq;
using NewLife.Log;
using NewLife.Web;

namespace WMSms
{
    /// <summary>手機類</summary>
    class Mobile : DisposeBase
    {
        #region 屬性
        private String _Address;
        /// <summary>地址</summary>
        public String Address { get { return _Address; } set { _Address = value; } }

        private Boolean _Logined;
        /// <summary>是否已登錄</summary>
        public Boolean Logined { get { return _Logined; } set { _Logined = value; } }
        #endregion

        #region 構造
        public Mobile(String address)
        {
            Address = address;
        }

        protected override void OnDispose(bool disposing)
        {
            base.OnDispose(disposing);

            if (client != null) client.Dispose();
        }
        #endregion

        #region 通訊基礎
        private WebClientX client;

        void EnsureClient()
        {
            if (client != null) return;

            client = new WebClientX(true, true);
            client.Encoding = Encoding.UTF8;

            ServicePointManager.Expect100Continue = false;
        }

        String Get(String url)
        {
            EnsureClient();

            //return client.DownloadString(url);
            var bts = client.DownloadData(url);
            return Encoding.UTF8.GetString(bts);
        }

        String Post(String url, String data)
        {
            EnsureClient();

            client.Headers["Referer"] = url;
            client.Headers["Content-Type"] = "application/x-www-form-urlencoded";
            //return client.UploadString(url, data);
            var bts = Encoding.UTF8.GetBytes(data);
            bts = client.UploadData(url, bts);
            return Encoding.UTF8.GetString(bts);
        }

        String Post(String url, IDictionary<String, Object> data)
        {
            if (data == null) return Post(url, "");

            var sb = new StringBuilder();
            foreach (var item in data)
            {
                if (sb.Length > 0) sb.Append("&");

                if (item.Value != null)
                    sb.AppendFormat("{0}={1}", item.Key, HttpUtility.UrlEncode("" + item.Value));
                else
                    sb.AppendFormat("{0}=", item.Key);
            }

            return Post(url, sb.ToString());
        }
        #endregion

        #region 方法
        public Boolean Login(String pass)
        {
            if (Logined) return true;

            var url = String.Format("http://{0}/authent/?returnurl=%2Ffs%2F", Address);
            var html = Get(url);

            url = String.Format("http://{0}/authent/?returnurl=%2Ffs%2F", Address);

            var dic = new Dictionary<String, Object>();
            dic.Add("user", "Admin");
            dic.Add("pwd", pass);

            html = Post(url, dic);

            var rs = !html.IsNullOrWhiteSpace() && html.Contains("form");

            Logined = rs;

            return rs;
        }

        public Boolean SendMessage(String number, String content)
        {
            var url = String.Format("http://{0}/messaging/?page=newmessage", Address);

            var dic = new Dictionary<String, Object>();
            dic.Add("RequestDeliveryReport", "chk");
            dic.Add("recipient", number);
            dic.Add("recipientName", null);
            dic.Add("smsbody", content);

            var html = Post(url, dic);

            return !html.IsNullOrWhiteSpace() && html.Contains("已發信息");
        }

        public Boolean Ping()
        {
            if (!Logined) return false;

            try
            {
                var url = String.Format("http://{0}/fs/", Address);
                var html = Get(url);

                if (html.IsNullOrWhiteSpace()) return false;

                // 如果回到登錄頁面,則標記為未登錄
                if (html.Contains("authent"))
                {
                    Logined = false;
                    return false;
                }

                return html.Contains("My Device");
            }
            catch (Exception ex)
            {
                XTrace.WriteException(ex);
                return false;
            }
        }
        #endregion

        #region 接收短信
        public List<Message> ReceiveUnReaded()
        {
            var list = Receive(0);
            if (list == null) return null;

            list = list.Where(m => !m.Readed).ToList();
            var i = 1;
            var ls = list;
            while (ls.Count >= 10 && !ls[ls.Count - 1].Readed)
            {
                ls = Receive(i++);
                if (ls == null || ls.Count < 1) break;

                ls = ls.Where(m => !m.Readed).ToList();
                list.AddRange(ls);

                if (list.Count >= 100) break;
            }

            return list;
        }

        public List<Message> ReceiveFromTime(DateTime start)
        {
            var list = Receive(0);
            if (list == null) return null;

            list = list.Where(m => m.Time > start).ToList();
            var i = 1;
            var ls = list;
            while (ls.Count >= 10 && ls[ls.Count - 1].Time > start)
            {
                ls = Receive(i++);
                if (ls == null || ls.Count < 1) break;

                ls = ls.Where(m => m.Time > start).ToList();
                list.AddRange(ls);

                if (list.Count >= 100) break;
            }

            return list;
        }

        static Regex _regMsg = new Regex("<div class=\"([^\"]*)\"><span class=\"msgDesc\">從 :</span>\\s*([^<]*?)\\s*-\\s*<a href=\"\\?page=newmessage&recipient=([^&\"]*)[^\"]*\">答復</a><br/><span class=\"msgDesc\">已收到 :</span>\\s*([^<]*?)\\s*<br/>\\s*([^<]*?)\\s*</div>", RegexOptions.IgnoreCase | RegexOptions.Compiled);
        public List<Message> Receive(Int32 page)
        {
            if (!Logined) return null;

            var url = String.Format("http://{0}/messaging/", Address);
            if (page > 1) url += "?page=" + page;
            var html = Get(url);
            if (html.IsNullOrWhiteSpace()) return null;

            var list = new List<Message>();
            foreach (Match m in _regMsg.Matches(html))
            {
                var msg = new Message();
                msg.Readed = "readMsg".EqualIgnoreCase(m.Groups[1].Value);

                // 名字
                var name = m.Groups[2].Value.Trim();
                if (!name.IsNullOrWhiteSpace())
                {
                    name = HttpUtility.HtmlDecode(name);

                    var p = name.IndexOf("(");
                    if (p > 0) name = name.Substring(0, p).Trim();
                    msg.Name = name;
                }

                // 號碼
                var num = m.Groups[3].Value.Trim();
                if (!num.IsNullOrWhiteSpace())
                {
                    num = HttpUtility.UrlDecode(num);
                    if (num.StartsWith("+86")) num = num.Substring(3);
                    msg.Number = num;
                }

                // 時間
                var dt = m.Groups[4].Value.Trim();
                if (!dt.IsNullOrWhiteSpace())
                {
                    dt = HttpUtility.HtmlDecode(dt);

                    var p = dt.IndexOf("(");
                    if (p > 0) dt = dt.Substring(0, p).Trim();

                    DateTime d;
                    if (DateTime.TryParse(dt, out d))
                        msg.Time = d;
                    else if (DateTime.TryParseExact(dt, "MM/dd/yy dddd HH:mm:ss", null, DateTimeStyles.None, out d))
                        msg.Time = d;
                }

                // 內容
                var txt = m.Groups[5].Value.Trim();
                if (!txt.IsNullOrWhiteSpace())
                {
                    msg.Content = HttpUtility.HtmlDecode(txt);
                }

                list.Add(msg);
            }

            return list;
        }

        public class Message
        {
            private String _Number;
            /// <summary>號碼</summary>
            public String Number { get { return _Number; } set { _Number = value; } }

            private String _Name;
            /// <summary>名稱</summary>
            public String Name { get { return _Name; } set { _Name = value; } }

            private String _Content;
            /// <summary>內容</summary>
            public String Content { get { return _Content; } set { _Content = value; } }

            private DateTime _Time;
            /// <summary>時間</summary>
            public DateTime Time { get { return _Time; } set { _Time = value; } }

            private Boolean _Readed;
            /// <summary>是否已讀</summary>
            public Boolean Readed { get { return _Readed; } set { _Readed = value; } }
        }
        #endregion
    }
}

 

 

 

剛下去小店買了一張移動動感地帶的卡,50塊辦卡返50,分5月返還每月10元,套餐每月20元包400條短信,實際上,后面每個月只需要交10元即可!

 

配置一下路由器,把WM手機的Http端口映射到公網,可供遠程應用系統直接調用!

現在很多可用的二手WM手機只需要一百多塊錢即可買到。

這個方案跟短信貓不相上下,(短信貓成品三百多塊),也算是多一種選擇吧!

 

WM軟件:WiFi.rar

源代碼:WMSmsSrc.rar


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM