.NET 快速宽带连接程序
背景引入
今天来实验室,发现之前设置的自动宽带连接计划任务又一次自动运行(而且又是黑乎乎的控制台一闪而过,根本不知道啥情况),本来不需要"宽带连接"(宿舍有线需要宽带连接,而实验室不需要),结果程序运行还浪费了我一些时间,强迫症+完美主义的我简直难受极了!!!,然后,定下计划,设计一个快速宽带连接的程序!
程序大致构思
首先,针对我的有线用网场景,大致分为 实验室-教学楼-宿舍,其中实验室和宿舍是使用场景最多的,所以需要判断用网场景。
其次,针对不同的用网场景,需要的操作,实验室部分一般自动连接即可,而宿舍需要拨号上网(PPPoE),所以,需要有宽带连接的命令,在这里,我选用的是rasdial命令,rasdial命令用法如下:
rasdial 连接名(比如:宽带连接) 用户名 密码
最后,快捷程序的编程语言选择问题,由于我使用Windows系统,而且需要一点即开的应用程序,所以我选择了C#语言,能直接编译为.exe文件双击使用
.NET 项目构建
老生常谈的控制台应用程序为首选(也许以后可以弄个GUI程序),由于Win10系统的VS2019没有安装.NET平台,无法新建C#项目,所以我选择了跨平台的.NET 5.0,使用VSCode作为编辑器,并且实验环境为WSL。
新建文件夹为Connect,输入
dotnet new console
新建了一个.NET Console Application 项目,可以发现,程序自动为我们生成了两个文件
点开Program.cs文件,会发现 "C# for Visual Studio Code"插件自动为我们创建了工作区的lauch和tasks文件,F5运行成功则表明,程序编译、运行环境配置成功。
因为Win10使用的是.NET Framework平台,跟跨平台的.NET 5.0不兼容,所以需要在Connect.csproj 中修改目标运行平台为.NET Framework 4.7
<TargetFrameworks>net5.0;net47</TargetFrameworks>
判断用网场景
由于实验室的有线网能自动联网,而宿舍有线网无法自动联网,所以一个简单的判断用网场景就是,当前有线网络是否自动连接上了。
而要知道有线网络的连接状况,需要知道网络适配器的状况,也就是这个
.NET为我们提供 System.Net.NetworkInformation 命名空间描述网络状态,其中 _public abstract class NetworkInterface_抽象类描述了网络适配器
那我们就可以遍历所有的网络适配器,从中找出有线网连接的对象
// 获取网络适配器信息
public static bool GetNetWork(){
// 获取所有网络适配器
NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
// 遍历查询
foreach (NetworkInterface adapter in adapters)
{
// 查询到有线连接 以太网 的对象
if(adapter.Name=="以太网"){
Console.WriteLine(adapter.Description);
Console.WriteLine(String.Empty.PadLeft(adapter.Description.Length, '='));
Console.WriteLine(" Status .................................. : {0}",adapter.OperationalStatus);//连接器使用状态,Up为开,Down为关
Console.WriteLine(" Id ...................................... : {0}",adapter.Id);//连接器id号
Console.WriteLine(" Interface Name .......................... : {0}",adapter.Name);
Console.WriteLine(" Interface type .......................... : {0}", adapter.NetworkInterfaceType);//网络适配器类型,有Lan,WLan等
Console.WriteLine(" Physical Address ........................ : {0}",
adapter.GetPhysicalAddress().ToString());//MAC地址
Console.WriteLine(" Is receive only.......................... : {0}", adapter.IsReceiveOnly);
Console.WriteLine(" Multicast................................ : {0}", adapter.SupportsMulticast);
Console.WriteLine();
return adapter.OperationalStatus==OperationalStatus.Up; //如果当前有线以太网已经连接,则返回true
}
}
return false;//否则返回false
}
如果返回为true,则代表实验室有线已经连接,否则,为宿舍需要宽带连接
调用系统命令
当为宿舍用网时,有线连接无法使用,需要宽带拨号,则程序需要调用rasdial命令进行拨号上网,所以需要创建一个进程进行调用,.NET提供了ProcessStartInfo和Process完成进程创建和调用
public static bool CallRad(){
//创建一个ProcessStartInfo对象 使用系统shell 指定命令和参数 设置标准输出
var psi = new ProcessStartInfo("rasdial"){Arguments="宽带连接 (用户名) (密码)", RedirectStandardOutput = true,//输出重定向
UseShellExecute=false};
// 创建进程
var proc=Process.Start(psi);
if(proc==null){
Console.WriteLine("Can not exec.");
return false;
}else{
Console.WriteLine("-------------Start read standard output--------------");
//开始读取
using (var sr = proc.StandardOutput)
{
while (!sr.EndOfStream)
{
Console.WriteLine(sr.ReadLine());
}
if (!proc.HasExited)
{
proc.WaitForExit();
}
}
Console.WriteLine("---------------Read end------------------");
// 进程执行状态,0代表成功
Console.WriteLine("Exited Code : {0}",proc.ExitCode);
return proc.ExitCode==0;
}
}
成功进行了宽带连接则会返回true
控制台结果展示
首先打印有线网卡信息,然后针对需要联网的宿舍有线,进行等待,其中控制台需要刷新打印信息,这里用到了"\r"制表符,并且针对控制台缓冲区的更新,还有一个刷新一行缓存区的函数,不刷新的话,会造成文字一直保留缓冲区,重叠现象
// 清除一行
public static void ClearCurrentConsoleLine()
{
int currentLineCursor = Console.CursorTop;
Console.SetCursorPosition(0, Console.CursorTop);
Console.Write(new string(' ', Console.WindowWidth));
Console.SetCursorPosition(0, currentLineCursor);
}
总体控制
public static void RasCon(){
// 获取网卡信息
bool res=GetNetWork();
// 针对网卡结果进行分析
if(res){
Console.WriteLine("当前网络已经连接");
// return ;
}else{
for(int i=0;i<=wtime;i++){
ClearCurrentConsoleLine();
Console.Write("\r当前网络未连接,{0}秒后自动连接",wtime-i);
Console.Out.Flush();
Thread.Sleep(second);
}
Console.WriteLine();
// 调用系统命令
if(CallRad()){
Console.WriteLine("\n宽带连接拨号成功!!!");
}else{
Console.WriteLine("\n宽带连接拨号失败!!!");
}
}
Thread.Sleep(3*second);
}
整体运行效果如下:
程序整体运行时间可以缩短,等有时间回宿舍进行测试一波!!!