查资料查的好辛苦啊,还好,找好了。这不,又要来当回『孔乙己』了,孔老湿当年是非常喜欢研究『茴』字的多种写法的,我呢也比较喜欢研究程序中各个功能的多种实现方法的。咳咳……嗯…… 这个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里面的方法,从控制面板一路查找到要禁用或启用网卡的右键方法,然后指定指定操作。查找路径如下:
控制面板->网络连接->要查找的网卡->该网卡的右键菜单->调用启用或禁用操作
这个方法的优势是他的确能够实现网卡的禁用和启用,不过劣势就非常多了:
- 硬编码,换个环境,改代码吧;
- 模拟人的搜索链接方式,系统模式变了,改代码吧;
- 兼容性非常的差,至少本人在Win7,Windows2003下都没有正常的运行起来。在Win7下面,控制面板中压根就找不到网络连接(25行),这也就说明第二点,系统模式变了,没招。Windows2003下使用是在38行异常:内存位置访问无效。 (异常来自 HRESULT:0x800703E6)。
- 我想这个方法是不是只在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非常欢迎你一起来讨论下。