通过WIFI或者GPRS获得时间,解决Windows Mobile换电池掉时间的问题

转自:http://blog.csdn.net/ppCuda/archive/2010/01/03/5123011.aspx

时隔1年多了,我的WM5换电池都会掉时间。虽然网上出现了一些校准工具,但是对我的Atom Exec好像都不管用。

于是就在上一个版本的基础上增加了自动WIFI连接互联网时间校准和自动GPRS时间校准。C#版的

首先是打开和关闭WIFI功能

        /// <summary>
        /// 设置WifI的状态,打开/关闭
        /// </summary>
        /// <param name="open">true为打开WIFI,false为关闭WIFI</param>
        /// <returns>操作成功返回true</returns>
        private bool setwifistate(bool open)
        {
            //查找注册表获得WIFI设备名称,再将WIFI电源打开
            bool ret = false;
            string[] sNames = null;
            RegistryKey keyWlan = null;
            try
            {
                keyWlan = Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Control\Power\State");
                sNames = keyWlan.GetValueNames();
            }
            catch { }
            finally
            {
                if (keyWlan != null) keyWlan.Close();
            }

            foreach (string wl in sNames)
            {
                if (wl.StartsWith("{98C5250D-C29A-4985-AE5F-AFE5367E5006}\\"))
                {
                    //POWER_NAME = 0x00000001
                    SetDevicePower(wl, 0x00000001, open ? DevicePowerState.D0 : DevicePowerState.D4);
                    ret = true;
                    break;
                }
            }
            return ret;
        }

然后是检查WIFI是否已经连接上一个热点了,这个需要不断的check

       /// <summary>
        /// 查看WifI连接热点状态
        /// </summary>
        /// <returns>true为连接上一个热点</returns>
        private bool checkwificonstate()
        {
            bool ret = false;
            RegistryKey keyWlan = null;
            try
            {
                keyWlan = Registry.LocalMachine.OpenSubKey(@"System\State\Hardware");
                int value = (int)keyWlan.GetValue("wifi", 0);
                if (value >= 0x00000010)
                {
                    ret = true;
                }
            }
            catch { }
            finally
            {
                if (keyWlan != null) keyWlan.Close();
            }
        
            return ret;
        }

以上是wifi连接打开热点,接下来是打开GPRS查询

GPRS的打开主要是依靠ConnMgrEstablishConnectionSync这个函数来实现,网上查询到一个ConnectionManager的类封装了这一操作,我就拿出来跟大家一起分享!

  public class ConnectManager
    {
        const int S_OK = 0;
        const uint CONNMGR_PARAM_GUIDDESTNET = 0x1;
        const uint CONNMGR_PRIORITY_USERINTERACTIVE = 0x08000;
        const uint INFINITE = 0xffffffff;
        const uint CONNMGR_STATUS_CONNECTED = 0x10;
        const int CONNMGR_MAX_DESC = 128;    // @constdefine Max size of a network description

        const int CONNMGR_FLAG_PROXY_HTTP = 0x1; // @constdefine HTTP Proxy supported
        const int CONNMGR_FLAG_PROXY_WAP = 0x2; // @constdefine WAP Proxy (gateway) supported
        const int CONNMGR_FLAG_PROXY_SOCKS4 = 0x4; // @constdefine SOCKS4 Proxy supported
        const int CONNMGR_FLAG_PROXY_SOCKS5 = 0x8; // @constdefine SOCKS5 Proxy supported

        const UInt16 IDC_WAIT = 32514;
        const UInt16 IDC_ARROW = 32512;

        private IntPtr m_hConnection = IntPtr.Zero;

        public ConnectManager()
        {
        }

        ~ConnectManager()
        {
            ReleaseConnection();
        }

        /// <summary>
        /// 查看连接是否可用
        /// </summary>
        /// <returns></returns>
        public bool GetConnMgrAvailable()
        {
            IntPtr hConnMgr = ConnMgrApiReadyEvent();
            bool bAvailbale = false;
            uint dwResult = WaitForSingleObject(hConnMgr, 2000);

            if (dwResult == 0)
            {
                bAvailbale = true;
            }

            // 关闭
            if (hConnMgr.ToInt32() != 0) CloseHandle(hConnMgr);

            return bAvailbale;
        }
        /// <summary>
        /// 映射URL
        /// </summary>
        /// <param name="lpszURL"></param>
        /// <param name="guidNetworkObject"></param>
        /// <param name="pcsDesc"></param>
        /// <returns></returns>
        public int MapURLAndGUID(string lpszURL, ref GUID guidNetworkObject, ref string pcsDesc)
        {
            if (lpszURL == null || lpszURL.Length < 1)
                return 0;

            uint nIndex = 0;
            int hResult = ConnMgrMapURL(lpszURL, ref guidNetworkObject, ref nIndex);
            if (hResult < 0)
            {
                throw new Exception("Could not map a request to a network identifier");
            }
            else
            {
                if (pcsDesc != null)
                {
                    CONNMGR_DESTINATION_INFO DestInfo = new CONNMGR_DESTINATION_INFO();
                    if (ConnMgrEnumDestinations((int)nIndex, ref DestInfo) >= 0)
                    {
                        pcsDesc = DestInfo.szDescription;
                    }
                }
            }

            return (int)nIndex;
        }
        /// <summary>
        /// 枚举网络标识符信息
        /// </summary>
        /// <param name="lstNetIdentifiers"></param>
        public List<CONNMGR_DESTINATION_INFO> EnumNetIdentifier()
        {
            List<CONNMGR_DESTINATION_INFO> lstNetIdentifiers = new List<CONNMGR_DESTINATION_INFO>();
            // 得到网络列表
            for (uint dwEnumIndex = 0; ; dwEnumIndex++)
            {
                CONNMGR_DESTINATION_INFO networkDestInfo = new CONNMGR_DESTINATION_INFO();

                if (ConnMgrEnumDestinations((int)dwEnumIndex, ref networkDestInfo) != 0)
                {
                    break;
                }
                lstNetIdentifiers.Add(networkDestInfo);
            }

            return lstNetIdentifiers;
        }

        /// <summary>
        /// 建立连接
        /// </summary>
        /// <param name="nIndex"></param>
        /// <returns></returns>
        public bool EstablishConnection(uint nIndex)
        {
            ReleaseConnection();
            // 得到正确的连接信息
            CONNMGR_DESTINATION_INFO DestInfo = new CONNMGR_DESTINATION_INFO();
            int hResult = ConnMgrEnumDestinations((int)nIndex, ref DestInfo);

            if (hResult >= 0)
            {
                // 初始化连接结构
                CONNMGR_CONNECTIONINFO ConnInfo = new CONNMGR_CONNECTIONINFO();

                ConnInfo.cbSize = (uint)Marshal.SizeOf(ConnInfo);
                ConnInfo.dwParams = CONNMGR_PARAM_GUIDDESTNET;
                ConnInfo.dwFlags = CONNMGR_FLAG_PROXY_HTTP | CONNMGR_FLAG_PROXY_WAP | CONNMGR_FLAG_PROXY_SOCKS4 | CONNMGR_FLAG_PROXY_SOCKS5;
                ConnInfo.dwPriority = CONNMGR_PRIORITY_USERINTERACTIVE;
                ConnInfo.guidDestNet = DestInfo.guid;
                ConnInfo.bExclusive = 1;  //0为共享连接,程序退出之后GPRS不关闭;1为不共享
                ConnInfo.bDisabled = 0;

                uint dwStatus = 0;
                hResult = ConnMgrEstablishConnectionSync(ref ConnInfo, ref m_hConnection, 18 * 1000, ref dwStatus);
                if (hResult < 0)
                {
//                    bool bRet = WaitForConnected(10, ref dwStatus);
                    return false;
                }
                else
                {
                    return true;
                }
            }

            return false;
        }
        /// <summary>
        /// 连接状态
        /// </summary>
        /// <param name="nTimeoutSec"></param>
        /// <param name="pdwStatus"></param>
        /// <returns></returns>
        public bool WaitForConnected(int nTimeoutSec, ref uint pdwStatus)
        {
            uint dwStartTime = GetTickCount();
            bool bRet = false;

            while (GetTickCount() - dwStartTime < (uint)nTimeoutSec * 1000)
            {
                if (m_hConnection.ToInt32() != 0)
                {
                    uint dwStatus = 0;
                    int hr = ConnMgrConnectionStatus(m_hConnection, ref dwStatus);
                    if (dwStatus != 0) pdwStatus = dwStatus;
                    if (hr >= 0)
                    {
                        if (dwStatus == CONNMGR_STATUS_CONNECTED)
                        {
                            bRet = true;
                            break;
                        }
                    }
                }
                Thread.Sleep(100);
            }

            return bRet;
        }

        /// <summary>
        /// 释放所有连接
        /// </summary>
        public void ReleaseConnection()
        {

            if (m_hConnection.ToInt32() != 0)
            {
                ConnMgrReleaseConnection(m_hConnection, 0);
                m_hConnection = IntPtr.Zero;
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct CONNMGR_CONNECTIONINFO
        {
            public uint cbSize;
            public uint dwParams;
            public uint dwFlags;
            public uint dwPriority;
            public int bExclusive;
            public int bDisabled;
            public GUID guidDestNet;
            public IntPtr hWnd;
            public uint uMsg;
            public uint lParam;
            public uint ulMaxCost;
            public uint ulMinRcvBw;
            public uint ulMaxConnLatency;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct CONNMGR_DESTINATION_INFO
        {
            public GUID guid;  // @field GUID associated with network
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CONNMGR_MAX_DESC)]
            public string szDescription;  // @field Description of network
            public int fSecure; // @field Is it OK to allow multi-homing on the network
        }

        public struct GUID
        {          // size is 16
            public uint Data1;
            public UInt16 Data2;
            public UInt16 Data3;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
            public byte[] Data4;
        }

        [DllImport("coredll.dll")]
        public static extern uint GetTickCount();

        [DllImport("coredll.dll")]
        public static extern uint WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds);

        [DllImport("cellcore.dll")]
        public static extern int ConnMgrMapURL(string pwszURL, ref GUID pguid, ref uint pdwIndex);

        [DllImport("cellcore.dll")]
        public static extern int ConnMgrEstablishConnectionSync(ref CONNMGR_CONNECTIONINFO ci, ref IntPtr phConnection, uint dwTimeout, ref uint pdwStatus);

        [DllImport("cellcore.dll")]
        private static extern IntPtr ConnMgrApiReadyEvent();

        [DllImport("cellcore.dll")]
        public static extern int ConnMgrReleaseConnection(IntPtr hConnection, int bCache);

        [DllImport("cellcore.dll")]
        public static extern int ConnMgrEnumDestinations(int nIndex, ref CONNMGR_DESTINATION_INFO pDestInfo);

        [DllImport("cellcore.dll")]
        public static extern int ConnMgrConnectionStatus(IntPtr hConnection,    // @parm Handle to connection, returned from ConnMgrEstablishConnection
            ref uint pdwStatus       // @parm Returns current connection status, one of CONNMGR_STATUS_*
            );

        [DllImport("coredll.dll")]
        private static extern int CloseHandle(IntPtr hObject);
    };

 

软件下载如下: (在叉叉上点右键另存为MatchTime.exe,去掉.jpg即可)

 

另外具体工程和代码下载已传至csdn,正在验证,随后贴出来与大家分享!

连接查询时间服务器获得时间和设置系统时间的代码略过,详见我上一篇blog


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ppCuda/archive/2010/01/03/5123011.aspx

你可能感兴趣的:(Windows Mobile)