多种.NET下禁用或启用Windows网卡的方法讨论

.net教程:c#禁用启用windows网卡的方法  查资料查的好辛苦啊,还好,找好了。这不,又要来当回『孔乙己』了,孔老湿当年是非常喜欢研究『茴』字的多种写法的,我呢也比较喜欢研究程序中各个功能的多种实现方法的。咳咳……嗯…… 这个下禁用/启用网卡是有很多种方法滴,你知道这个禁用/启用有几种方法呢,在.NET怎么写么?话说,我就是这么把自己套进去了,不过话说回来,还真给找到有好几种方法可以实现这个禁用/启用网卡的功能,不过实现方法却并不是每种都能够在你的机器下运行起来的。让我们来看看吧。

  首先,第一种方法,网站上流传还是比较广的,中文内容到处非常多贴着这个代码来讨论如何/启用网卡的。这么悬乎,是什么方法?查查:C# 启用或禁用网卡,应该出镜率不是第一就是第二了吧,Here we go, 上代码:

/*
* blog.useasp.net
* MitchellChu's Blog
* 网卡的禁用/启用方法
*
* 要在项目中使用此方法,你必须添加对Shell32的引用。
* enable: 是bool值,表示网卡的启用或禁用,false 禁用
* networkConnectionName:网卡显示的名称,一般是:本地连接,本地连接 2这样的。
*/

public static bool ChangeNetworkConnectionStatus(bool enable, string networkConnectionName)
{
    const string discVerb = "停用(&B)"; // "停用(&B)"; 
    const string connVerb = "启用(&A)"; // "启用(&A)"; 
    const string network = "网络连接"; //"网络连接"; 

    string sVerb = enable ? connVerb : discVerb;

    Shell sh = new Shell(); //Shell32.Shell()
    Folder folder = sh.NameSpace(Shell32.ShellSpecialFolderConstants.ssfCONTROLS);

    try
    {
        //进入控制面板的所有选项 
        foreach (FolderItem myItem in folder.Items())
        {
            //进入网络连接 
            if (myItem.Name == network)
            {
                Folder fd = (Shell32.Folder)myItem.GetFolder;
                foreach (FolderItem fi in fd.Items())
                {
                    //找到本地连接 
                    Console.WriteLine(fi.Name);
                    if ((fi.Name == networkConnectionName))
                    {
                        //找本地连接的所有右键功能菜单 
                        foreach (FolderItemVerb Fib in fi.Verbs())
                        {
                            Console.WriteLine(Fib.Name);
                            if (Fib.Name == sVerb)
                            {
                                Fib.DoIt();
                                return true; //仅此返回true
                            }
                        }
                    }
                }
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
        return false;
    }
    return false; //没有处理成功
}

 这个方法的原理是使用Shell32里面的方法,从控制面板一路查找到要禁用或的右键方法,然后指定指定操作。查找路径如下:

控制面板->网络连接->要查找的网卡->该网卡的右键菜单->调用启用或禁用操作

这个方法的优势是他的确能够实现网卡的禁用和启用,不过劣势就非常多了:

  1. 硬编码,换个环境,改代码吧;
  2. 模拟人的搜索链接方式,系统模式变了,改代码吧;
  3. 兼容性非常的差,至少本人在Win7,Windows2003下都没有正常的运行起来。在Win7下面,控制面板中压根就找不到网络连接(25行),这也就说明第二点,系统模式变了,没招。Windows2003下使用是在38行异常:内存位置访问无效。 (异常来自 HRESULT:0x800703E6)。
  4. 我想这个方法是不是只在XP能够运行? —— 这个没有找到支持的证据,因为官网的说明是最小支持平台是XP和2000 Pro,而之后的2003和Win7都不能用。所以只还猜测只能在XP下用了。

 

第二种方法:使用WMI来操作网卡的禁用/启用,同样,上代码再说:

/*
* blog.useasp.net
* MitchellChu's Blog
* 网卡的禁用/启用方法
*
* 要在项目中使用此方法,你必须添加对System.Management的引用。
* enable: 是bool值,表示网卡的启用或禁用,false 禁用
* networkConnectionName:网卡显示的名称,一般是:本地连接,本地连接 2这样的。
*/

public bool ChangeNetworkConnectionStatus(bool enable, string networkConnectionName)
{
    uint retRslt = 1;
    using (ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapter WHERE PhysicalAdapter=TRUE AND NetConnectionID='" + networkConnectionName + "'"))
    {
        foreach (ManagementObject mbo in mos.Get())
        {
            retRslt = (uint)(enable ? mbo.InvokeMethod("Enable", null) : mbo.InvokeMethod("Disable", null));
            if (retRslt != 0) break;
        }
        if (retRslt == 0)
            return true;
        return false;
    }
}

 这个方法的使用原理就是通过调用WMI中Win32_NetworkAdapter的两个方法来实现禁用和启用网卡的,这个方法和前一个方法相比,简洁了许多,实现起来也更优雅一些,毕竟再也不用硬编码了。不过细心的你应该会发现,网上也有好多人抱怨,这玩意怎么用不了;或者你解决类似网卡的启用禁用问题,你也会发下,这个方法在WIn7神码的跑的非常的欢快,不过到了Windows2003啥的,就对不起了,罢工!

  至于调用WMI中Win32_NetworkAdapter的Enable和Disable方法出错的问题,我们可以在官方网站上找到答案。官方网站明确给出:Win32_NetworkAdapter中Diable和Enable两个方法,支持的最早平台是Windows Vista或者Windows Server 2008,而且是desktop apps only的,明白了吗?这就是为什么你调用Disble或Enable的时候死活不能成功的原因了。如果你碰到这个问题,好好想想其他办法吧,此路不通!至于有人说,我的是Windows 8啊,怎么也会报错?咳咳……管理员权限给了么亲?

  以上这两种方法是当下网络中比较流行的方法,然而却各有限制。在实际的使用中,如果是二选一,个人比较推荐后者。

 

第三种方法:既然前面的方法都有或多或少的问题,那么我们就转到命令行下来试试吧。看个代码先:

/*
* blog.useasp.net
* MitchellChu's Blog
* 网卡的禁用/启用方法
*
* 要在项目中使用此方法,你必须添加对System.Diagnostics的引用。
* enable: 是bool值,表示网卡的启用或禁用,false 禁用
* networkConnectionID:网卡显示的名称,一般是:本地连接,本地连接 2这样的。
*/

public bool ChangeNetworkConnectionStatus(bool enable, string networkConnectionID)
{
    using (Process process = new Process())
    {
        string cmdParameter = "{0} = net PCI\{1}";
        process.EnableRaisingEvents = false;
        process.StartInfo.Arguments = String.Format(cmdParameter, enable ? "enable" : "disable", networkConnectionID);
        process.StartInfo.FileName = "devcon.exe";
        process.StartInfo.CreateNoWindow = true;
        process.StartInfo.ErrorDialog = false;
        process.StartInfo.RedirectStandardError = false;
        process.StartInfo.RedirectStandardInput = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.UseShellExecute = false;
        process.Start();
        string rtn = process.StandardOutput.ReadToEnd();
        if (rtn.Trim().Length == 0)
        {
        	return true;
        }
        else
        {
            return false;
        }
    }
}

这种方法使用的是devcon.exe来实现网卡的禁用和启用的,DevCon 实用工具是一种命令行实用工具,可以替代设备管理器。使用 DevCon,您可以启用、禁用、重新启动、更新、删除和查询单个设备或一组设备。DevCon 还提供与驱动程序开发人员有关、但无法在设备管理器中看到的信息。不过这个工具不是系统自带的,需要单独下载(下载地址官方文档)。这个工具的好处是支持Windows XP ,Wndows 2000,Windows 2003的各个版本,在XP之前的95,95,ME不受支持,在2003之后的系统暂时未知,Win7没有仔细测试,可以获取。这个应该算是devcon的劣势了,不过比起前面两个,它有个优势,就是能随程序一起发布,这点也算比较方便了。

 

第四种方法:同样是命令行中来实现,只不过使用了另外一个命令:netsh。

/*
* blog.useasp.net
* MitchellChu's Blog
* 网卡的禁用/启用方法
*
* 要在项目中使用此方法,你必须添加对System.Diagnostics的引用。
* enable: 是bool值,表示网卡的启用或禁用,false 禁用
* networkConnectionName:网卡显示的名称,一般是:本地连接,本地连接 2这样的。
*/

public bool ChangeNetworkConnectionStatus(bool enable, string networkConnectionName)
{
    using (Process process = new Process())
    {
        string netshCmd = "interface set interface name=\"{0}\" admin={1}";
        process.EnableRaisingEvents = false;
        process.StartInfo.Arguments = String.Format(netshCmd, networkConnectionName, enable ? "ENABLED" : "DISABLED");
        process.StartInfo.FileName = "netsh.exe";
        process.StartInfo.CreateNoWindow = true;
        process.StartInfo.ErrorDialog = false;
        process.StartInfo.RedirectStandardError = false;
        process.StartInfo.RedirectStandardInput = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.UseShellExecute = false;
        process.Start();
        string rtn = process.StandardOutput.ReadToEnd();
        if (rtn.Trim().Length == 0)
        {
        	return true;
        }
        else
        {
            return false;
        }
    }
}

这个禁用,启用windows网卡的方法是使用命令行的netsh命令来实现的,Netsh 是命令行脚本实用工具,它允许从本地或远程显示或修改当前正在运行的计算机的网络配置。而且此君武功了得,基本上有经验的管理员都得到过此君的帮助。更重要的是,用netsh这个命令行来执行启用或禁用网卡这事,本来就是它职责范围内的,所以,netsh驾轻就熟,非常方便就能搞定。netsh支持的平台据我了解应该是XP——?,XP之前的没有了解过。

  到这里,我就已经倾囊而出了,这『茴』字也就这么几个写法了,你还有其他什么『写法』吗?MitchellChu非常欢迎你一起来讨论下。

 

Monday, June 17, 2013 | .NET技术

文章评论

  • # re: 多种.NET下禁用或启用Windows网卡的方法讨论
    话说每次评论的姓名都是乱码
  • # re: 多种.NET下禁用或启用Windows网卡的方法讨论
    一切正常,没见到乱码现象呢。
  • # re: 多种.NET下禁用或启用Windows网卡的方法讨论
    我在 VMPlayer 的 Win7 實測,只有第三種方法可行。
  • # re: 多种.NET下禁用或启用Windows网卡的方法讨论
    @George Fang: 当时我在XP,2003,Win 7, Win 8下测试过这些方法,具体结果现在不太记得了。按习惯,写的越靠前的方法越是不通适。

发表评论

Please add 2 and 6 and type the answer here:

关于博主

  一枚成分复杂的网络IT分子,属于互联网行业分类中的杂牌军。