一个扩充拨号类

主  题:  一个扩充拨号类
作  者:  linzsoft (邪邪)  
等  级:
信 誉 值:  100
所属论坛:  .NET技术 C#
问题点数:  0
回复次数:  16
发表时间:  2003-5-14 16:58:14

提供一个拨号类,原来这个类的雏形是在这里发现的,现在我把它扩充一下方便大家使用
实现功能:

扩充功能
1:拨号(改正win98拨号出现610错误的情况)
2:断开拨号
3:获得当前的拨号连接
4:断线事件

using System;
using System.Runtime.InteropServices;
using static Ras.RasManager;

namespace Ras
{
    //尊重知识产权,原类名空间名未作更改
    public class RasManager
    {
        //拨号数据
        public const int RAS_MaxEntryName = 256;
        public const int RAS_MaxPhoneNumber = 128;
        public const int UNLEN = 256;
        public const int PWLEN = 256;
        public const int DNLEN = 15;
        public const int MAX_PATH = 261;
        public const int RAS_MaxDeviceType = 16;
        public const int RAS_MaxDeviceName = 128;
        public const int RAS_MaxCallbackNumber = RAS_MaxPhoneNumber;
        //回调函数
        public delegate void Callback(uint unMsg, int rasconnstate, int dwError);
        //断线事件数据
        private bool Keep;
        public System.Threading.Thread KeepRas;
        public event RasDeconnect rasDecoonect;
        public delegate void RasDeconnect(object render, ClassCon.RasDecoonectAgrs e);

        //拨号结构
        [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Auto)]
        public struct RASDIALPARAMS
        {
            public int dwSize;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxEntryName + 1)]
            public string szEntryName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxPhoneNumber + 1)]
            public string szPhoneNumber;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxCallbackNumber + 1)]
            public string szCallbackNumber;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = UNLEN + 1)]
            public string szUserName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = PWLEN + 1)]
            public string szPassword;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DNLEN + 1)]
            public string szDomain;
            //win98下面,以下的两个变量去掉,否则产生610错误
            public int dwSubEntry;
            public int dwCallbackId;
        }

        //拨号函数
        [DllImport("Rasapi32.dll", CharSet = CharSet.Auto)]
        public static extern int RasDial(int lpRasDialExtensions, string lpszPhonebook, ref RASDIALPARAMS lprasdialparams, int dwNotifierType, Callback lpvNotifier, ref int lphRasConn);
        private RASDIALPARAMS RasDialParams;
        //拨号连接句柄
        private int Connection;
        //断开拨号
        [DllImport("Rasapi32.dll", CharSet = CharSet.Auto)]
        public static extern int RasHangUp(long lphRasConn);
        //获取当前拨号的数据
        [StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Auto)]
        public struct RASCONN
        {
            public int dwSize;
            public int hrasconn;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxEntryName + 1)]
            public string szEntryName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxDeviceType + 1)]
            public string szDeviceType;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxDeviceName + 1)]
            public string szDeviceName;
        }

        //获取当前拨号
        [DllImport("Rasapi32.dll", CharSet = CharSet.Auto)]
        public static extern int RasEnumConnections(ref RASCONN lprasconn, ref int lpcb, ref int lpcConnections);

        //构造函数
        public RasManager()
        {
            Connection = 0;
            RasDialParams = new RASDIALPARAMS();
            RasDialParams.dwSize = Marshal.SizeOf(RasDialParams);
        }

        //属性区域
        #region Properties
        //注册姓名
        public string UserName
        {
            get { return RasDialParams.szUserName; }
            set { RasDialParams.szUserName = value; }
        }
        //注册密码
        public string Password
        {
            get { return RasDialParams.szPassword; }
            set { RasDialParams.szPassword = value; }
        }
        //拨号名
        public string EntryName
        {
            get { return RasDialParams.szEntryName; }
            set { RasDialParams.szEntryName = value; }
        }
        //拨号电话
        public sting PhoneNumber
        {
            get { return RasDialParams.szPhoneNumber; }
            set { RasDialParams.szPhoneNumber = value; }
        }
        #endregion

        //获取当前拨号,如果拨号唯一,返回1,并且赋值句柄,拨号不为一,返回拨号个数,出错则返回错误码
        public int GetConnect()
        {
            RASCONN lpRasConn = new RASCONN();
            int lpcb = 0;
            int lpcConnections = 0;
            lpRasConn.dwSize = Marshal.SizeOf(lpRasConn);
            lpcb = lpRasConn.dwSize;
            int nRet = RasEnumConnections(ref lpRasConn, ref lpcb, ref lpcConnections);
            if (nRet == 0)
                if (lpcConnections == 1)
                {
                    Connection = lpRasConn.hrasconn;
                    return lpcConnections;
                }
                else
                    return lpcConnections;
            else
                return nRet;
        }

        //同步拨号
        public bool Connect()
        {
            Connection = 0;
            //根据win自己的说明,要执行已有的拨号
            //RasDialParams.szEntryName = 你的拨号连接的名字,并且保持RasDialParams.szPhoneNumber = "";
            //如果要直接拨号
            //RasDialParams.szEntryName = "";RasDialParams.szPhoneNumber = 电话号码。
            //但是我没法检测,有小猫的朋友可以试试
            RasDialParams.szEntryName += "\0";
            RasDialParams.szPhoneNumber += "\0";
            RasDialParams.szUserName += "\0";
            RasDialParams.szPassword += "\0";
            int result = RasDial(0, null, ref RasDialParams, 0, null, ref Connection);
            if (result == 0)
            {
                //拨号成功开始跟踪拨号情况
                if (!Keep)
                {
                    Keep = true;
                    KeepRas = new System.Threading.Thread(new System.Threading.ThreadStart(this.CheckRasEvent));
                    KeepRas.Start();
                }
                return true;
            }
            else
            {
                return false;
            }
        }

        //异步拨号  
        public int AConnect()
        {
            Callback rasDialFunc = new Callback(RasManager.RasDialFunc);
            RasDialParams.szEntryName += "\0";
            RasDialParams.szPhoneNumber += "\0";
            RasDialParams.szUserName += "\0";
            RasDialParams.szPassword += "\0";
            int result = RasDial(0, null, ref RasDialParams, 0, rasDialFunc, ref Connection);
            return result;
        }

        //断开拨号
        public int DeConnect()
        {
            int result = RasHangUp(Connection);
            Connection = 0;
            Keep = false;
            System.Threading.Thread.Sleep(3000);
            return result;
        }

        //异步拨号的回调函数
        public static void RasDialFunc(uint unMsg, int rasconnstate, int dwError)
        {
            //rasconnstate 返回的是当前状态码
            //有兴趣的朋友可以假如自己的代码,它是个枚举,在c++中的结构如下
            /*
            typedef enum _RASCONNSTATE { 
                  RASCS_OpenPort = 0, 
                  RASCS_PortOpened, 
                  RASCS_ConnectDevice, 
                  RASCS_DeviceConnected, 
                  RASCS_AllDevicesConnected, 
                  RASCS_Authenticate, 
                  RASCS_AuthNotify, 
                  RASCS_AuthRetry, 
                  RASCS_AuthCallback, 
                  RASCS_AuthChangePassword, 
                  RASCS_AuthProject, 
                  RASCS_AuthLinkSpeed, 
                  RASCS_AuthAck, 
                  RASCS_ReAuthenticate, 
                  RASCS_Authenticated, 
                  RASCS_PrepareForCallback, 
                  RASCS_WaitForModemReset, 
                  RASCS_WaitForCallback,
                  RASCS_Projected, 
                #if (WINVER >= 0x400) 
                  RASCS_StartAuthentication,    // Windows 95 only 
                  RASCS_CallbackComplete,       // Windows 95 only 
                  RASCS_LogonNetwork,           // Windows 95 only 
                #endif 
                  RASCS_SubEntryConnected,
                  RASCS_SubEntryDisconnected,
                  RASCS_Interactive = RASCS_PAUSED, 
                  RASCS_RetryAuthentication, 
                  RASCS_CallbackSetByCaller, 
                  RASCS_PasswordExpired, 
                #if (WINVER >= 0x500)
                  RASCS_InvokeEapUI,
                #endif
                  RASCS_Connected = RASCS_DONE, 
                  RASCS_Disconnected 
                }RASCONNSTATE; 
            */
        }

        //时时检测网络
        private void CheckRasEvent()
        {
            int i;
            while (Keep)
            {
                i = GetConnect();
                if (i != 1)
                    if (rasDecoonect != null)
                    {
                        rasDecoonect(this, new ClassCon.RasDecoonectAgrs(i));
                        Keep = false;
                    }
            }
        }
    }

    public class RasDecoonectAgrs : System.EventArgs
    {
        public RasDecoonectAgrs(int i)
        {
            RasMeg = i;
        }
        public readonly int RasMeg;
    }
}

例如:

RasM = new ClassCon.RasManager();
RasM.EntryName = "我的连接";
RasM.PhoneNumber = "";
RasM.UserName = "guest";
RasM.Password = "guest";

感兴趣的朋友顶一顶



回复人: linzsoft(邪邪) ( 二级(初级)) 信誉:100 2003-5-14 20:36:18 得分:0

是不是没人看啊?

回复人: snewxf(心疤) ( 一星(中级)) 信誉:110 2003-5-14 20:52:26 得分:0

好贴!!!!!!!!!!!!!!!!!

回复人: eidolon(eidolon) ( 一级(初级)) 信誉:100 2003-5-24 14:06:15 得分:0

如何改成WindowsServices呢?
让他再后台运行.

回复人: eidolon(eidolon) ( 一级(初级)) 信誉:100 2003-5-24 14:35:50 得分:0

我试了一下,有很多的错误啊...???
看得不太懂

回复人: linzsoft(邪邪) ( 二级(初级)) 信誉:100 2003-5-24 17:34:56 得分:0

什么样的错误?
写出来让我看看

回复人: linzsoft(邪邪) ( 二级(初级)) 信誉:100 2003-5-24 17:38:36 得分:0

这里改一下

//异步拨号  
public bool AConnect()
{
    Callback rasDialFunc = new Callback(RasManager.RasDialFunc);
    RasDialParams.szEntryName += "\0";
    RasDialParams.szPhoneNumber += "\0";
    RasDialParams.szUserName += "\0";
    RasDialParams.szPassword += "\0";
    int result = RasDial(0, null, ref RasDialParams, 0, rasDialFunc, ref Connection);
    return result;
}

回复人: CMIC(大象) ( 五级(中级)) 信誉:96 2003-5-24 19:02:12 得分:0

收藏

回复人: eidolon(eidolon) ( 一级(初级)) 信誉:100 2003-5-24 22:00:33 得分:0

public delegate void RasDeconnect(object render,ClassCon.RasDecoonectAgrs e);
这一句是什么意思?
ClassCon哪里来的?

回复人: linzsoft(邪邪) ( 二级(初级)) 信誉:100 2003-5-25 2:43:56 得分:0

原来的这个类的空间名是ClassCon ,后来为了尊重原作者改了回去所以ClassCon改成Ras
写得匆忙了些

这两句是合用的

public event RasDeconnect rasDecoonect;
public delegate void RasDeconnect(object render,ClassCon.RasDecoonectAgrs e);

定义一个事件RasDeconnect rasDecoonect
定义一个委托RasDeconnect,(object render,ClassCon.RasDecoonectAgrs e)委托给rasDecoonect

回复人: eidolon(eidolon) ( 一级(初级)) 信誉:100 2003-5-25 11:03:26 得分:0

//异步拨号  
public bool AConnect()
{
    Callback rasDialFunc = new Callback(RasManager.RasDialFunc);
    RasDialParams.szEntryName += "\0";
    RasDialParams.szPhoneNumber += "\0";
    RasDialParams.szUserName += "\0";
    RasDialParams.szPassword += "\0";
    int result = RasDial(0, null, ref RasDialParams, 0, rasDialFunc, ref Connection);
    return result;
}

returnint类型,而此方法要求返回bool类型,错了吧.?
另外我这样使用:

RasM = new RasManager();
RasM.EntryName = "我的连接";
RasM.PhoneNumber = "";
RasM.Connect();

不会启动我的拨号连接,我用的是56K猫

回复人: eidolon(eidolon) ( 一级(初级)) 信誉:100 2003-5-25 15:38:38 得分:0

up

回复人: cocosoft(pengyun) ( 五级(中级)) 信誉:100 2003-5-25 18:47:06 得分:0

ok

回复人: dy630(半导体) ( 三级(初级)) 信誉:67 2003-5-25 19:18:23 得分:0

收藏!!

回复人: eidolon(eidolon) ( 一级(初级)) 信誉:100 2003-5-26 23:12:54 得分:0

最后在up一下,哪位使用成功了阿...???

回复人: linzsoft(邪邪) ( 二级(初级)) 信誉:100 2003-5-27 1:43:42 得分:0

你是在什么系统下?
如果是win98 你可以这样做,在

public int Connect()
{
    Connection = 0;
    //根据win自己的说明,要执行已有的拨号
    //RasDialParams.szEntryName = 你的拨号连接的名字,并且保持RasDialParams.szPhoneNumber = "";
    //如果要直接拨号
    //RasDialParams.szEntryName = "";RasDialParams.szPhoneNumber = 电话号码。
    //但是我没法检测,有小猫的朋友可以试试
    RasDialParams.szEntryName += "\0";
    RasDialParams.szPhoneNumber += "\0";
    RasDialParams.szUserName += "\0";
    RasDialParams.szPassword += "\0";
    int result = RasDial(0,null,ref RasDialParams,0,null,ref Connection);
                    return result;
}

然后看看他返回的数字,记住如果是610
public struct RASDIALPARAMS就是这个结构写错了,

还有密码一定要添

RasM.UserName = "guest";
RasM.Password = "guest";

最后一个问题,拨号是不可能拨号音的,因为那是windows自己加的调用api拨号不会有拨号音
如果是win2000你可以到 网络和拨号连接 去观察 如果成功运行了,上面会显示正在拨号
结果可能会出现没有联接 断开,这样的原因有很多,你要看看result的号码,或者你写给我看看。

回复人: loke(细东) ( 一级(初级)) 信誉:100 2003-09-29 14:57:00 得分:0

成功~~

Contributors: FHL