如何使用 C#/.NET 在 Windows 中使用拨号 (RAS) 连接?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/722805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 22:32:47  来源:igfitidea点击:

How do I work with dial-up (RAS) connections in Windows using C#/.NET?

c#.netdial-upras

提问by Adam Nofsinger

I need to be able to connect, disconnect, and re-connect a dial-up networking connection in a C# .NET Framework application. Creating the connection in the phone-book might also be useful/necessary.

我需要能够在 C# .NET Framework 应用程序中连接、断开和重新连接拨号网络连接。在电话簿中创建连接也可能有用/必要。

Are there any classes or libraries written for C# or .NET out there that wrap all this functionality nicely for me? Anyone have some code they would be willing to share?

是否有任何为 C# 或 .NET 编写的类或库可以很好地为我包装所有这些功能?任何人都有一些他们愿意分享的代码?

Note: Application is unattended, like a Kiosk, and thus requiring user action is unacceptable.

注意:应用程序是无人值守的,就像一个信息亭,因此要求用户操作是不可接受的。

采纳答案by Shea

Check out the DotRas project on CodePlex.com, it has the entire API completed.

查看 CodePlex.com 上的 DotRas 项目,它完成了整个 API。

http://www.codeplex.com/DotRas

http://www.codeplex.com/DotRas

回答by Austin Salonen

This is cut out from a couple different classes (some code omitted for possible privacy issues) so it may not compile with a straight copy. Hope it helps!

这是从几个不同的类中删除的(为了可能的隐私问题省略了一些代码),因此它可能无法直接编译。希望能帮助到你!

using System.Runtime.InteropServices;

[DllImport("wininet.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public extern static bool InternetGetConnectedState(
    out int connectionDescription,
    int reservedValue);

[DllImport("wininet.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.I4)]
public static extern int InternetAttemptConnect(int dwReserved);

public sealed class InternetConnection
{
    private InternetConnection()
    { }

    public static bool IsConnected()
    {
        int connectionDescription = 0;

        return InternetGetConnectedState(out connectionDescription, 0);
    }

    public static int Connect()
    {
        return InternetAttemptConnect(0);
    }
}

回答by Shea

One way to do this is through Interop around RAS. RasDialDlg() can be used to open a dial-up networking connection without displaying the dialog box. Use RasHangUp() to disconnect.

一种方法是通过围绕 RAS 的互操作。RasDialDlg() 可用于打开拨号网络连接而不显示对话框。使用 RasHangUp() 断开连接。

RasEnumConnections() can be used to list available connections.

RasEnumConnections() 可用于列出可用连接。

The dll is Rasapi32.dll - headers are in ras.h and raserror.h

dll 是 Rasapi32.dll - 头文件在 ras.h 和 raserror.h

回答by Shea

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;

namespace MenelGameAuto.Internet
{
    class RAS
    {
        #region <Fields>

        private int rasConnectionsAmount; // ilo?? struktur typu RASCONN
        #endregion

        [DllImport("wininet.dll", CharSet = CharSet.Auto)]
        static extern bool InternetGetConnectedState(
            ref int lpdwFlags,
            int dwReserved);

        const int MAX_PATH = 260;
        const int RAS_MaxDeviceType = 16;
        const int RAS_MaxPhoneNumber = 128;
        const int RAS_MaxEntryName = 256;
        const int RAS_MaxDeviceName = 128;

        const int RAS_Connected = 0x2000;

        /// <summary>
        /// Wykazuje wszystkie po??czenia RAS.
        /// </summary>
        [DllImport("rasapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        private static extern int RasEnumConnections([In, Out] RASCONN[] lprasconn, ref int lpcb,ref int lpcConnections);

        [DllImport("rasapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern uint RasHangUp(IntPtr hRasConn);

        [DllImport("RASAPI32", SetLastError = true, CharSet = CharSet.Auto)]
        static extern int RasGetConnectStatus(IntPtr hrasconn, ref RASCONNSTATUS lprasconnstatus);

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        struct RASCONN
        {
            public int dwSize;
            public IntPtr 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;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
            public string szPhonebook;
            public int dwSubEntry;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        struct RASCONNSTATUS
        {
            public int dwSize;
            public int rasconnstate;
            public int dwError;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxDeviceType + 1)]
            public string szDeviceType;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxDeviceName + 1)]
            public string szDeviceName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = RAS_MaxPhoneNumber + 1)]
            public string szPhoneNumber;
        }


        /// <summary>
        /// Pobranie wszystkich po??czeń RAS.
        /// </summary>
        /// <returns>Struktury po??czeń RAS</returns>
        private RASCONN[] GetRasConnections()
        {
            // Stworzenie tablicy, któr? pó?niej nale?y przekaza? funkcjom
            int rasEnumReturn;
            RASCONN[] rasconnStructs = new RASCONN[256];
            rasconnStructs.Initialize(); // inicjalizacja wszystkich pól struktury
            rasconnStructs[0].dwSize = Marshal.SizeOf(typeof(RASCONN)); // inicjalizacja pierwszego pola pierwszej struktury na warto?? wielko?ci tej struktury
            int sizeOfRasconnStruct = rasconnStructs[0].dwSize * rasconnStructs.Length; // wielko?? pojedynczej struktury * ilosc

            // Wywo?anie RasEnumConnections do zdobycia wszystkich aktywnych po??czeń RAS
            rasEnumReturn = RasEnumConnections(rasconnStructs, ref sizeOfRasconnStruct, ref rasConnectionsAmount);

            // je?eli RasEnumConnections nie zwróci?o ERROR_SUCCESS
            if (rasEnumReturn != 0) throw new Win32Exception(rasEnumReturn);
            return rasconnStructs;
        }

        /// <summary>
        /// Roz??cza internet.
        /// </summary>
        public void Disconnect()
        {
            RASCONN[] rasStructs = GetRasConnections();

            // Przej?cie przez ka?d? struktur? RASCONN
            for (int i = 0; i < rasConnectionsAmount; i++)
            {
                // Pobranie pojedynczej struktury
                RASCONN rStruct = rasStructs[i];

                // Je?eli uchwyt do po??czenia wynosi 0, to brak po??czenia
                if (rStruct.hrasconn == IntPtr.Zero) continue; // i nast?pna struktura...

                // Roz??czenie...
                RasHangUp(rStruct.hrasconn);
            }
        }

        public void Connect()
        {
            // TODO
        }

        public bool IsConnected()
        {
            RASCONN[] rasStructs = GetRasConnections();

            RASCONNSTATUS rasConnStatus = new RASCONNSTATUS();
            rasConnStatus.dwSize = Marshal.SizeOf(typeof(RASCONNSTATUS));

            for (int i = 0; i < rasConnectionsAmount; ++i)
            {
                // Pobranie pojedynczej struktury
                RASCONN rStruct = rasStructs[i];

                int statusResult = RasGetConnectStatus(rStruct.hrasconn, ref rasConnStatus);
                if (statusResult != 0) throw new Win32Exception(statusResult);
                if(rasConnStatus.rasconnstate == RAS_Connected) return true;
            }
            return false;
        }
    }
}