如何从Windows8删除开放或不安全的Wi-Fi热点:附带源码的Wifi.exe命令行工程

[原文发表地址] How to delete Open or Insecure Wi-Fi HotSpots from Windows 8: Wifi.exe Command Line Utility with Source

[原文发表时间] 2013-06-13

Windows8的大部分我都很满意,只是有一个特性被移除让我很不适应-无线网络对话框。

当然,你可以通过右击Wi-Fi连接“忘记这个网络”,但只有当网络在范围内才可以。 过去可以让你添加或移除网络的无限网络对话框已经不在了。谁知道我的系统保存了多少Wi-Fi热点资料呢?

所以,问题是:我想移除保存的Wi-Fi资料,任何时候只要我想。我写了一个可以运行在Windows7和Windows8上的命令行工具。

clip_image001

TL;DR 版本
有个 Wifi.exe构建压缩包在此 ,还有GitHub上的源码

更新: 我已经把Wifi-Manager放到Chocolately ,你现在可以“cinst wifi-manager”。感谢Brendan Forster 的大量工作!到这里学习更多关于Chocolately包管理

注意事项和“我知道啦”

首先,让我明确一下,我已经写了一个命令行工程来替换另一个命令行工程。我明白这点,在我这么做的时候就知道了。其他一些比我聪明的人做了相似的事情,相比学习一个直观的语法,他们写了一个符合他们想法的工程。别讨厌playa,要恨就恨正则表达式。

旁白: 我的iphone上也有一样的问题。我的手机上保存了超过50个Wi-Fi热点,不越狱就删不掉它们。

你可以用windows自带的netsh.exe访问Wi-Fi资料,所以你可以像这样列出资料:

 c:\>netsh wlan show profiles



Profiles on interface Wi-Fi:



User profiles

-------------
 All User Profile : Wayport_Access
 All User Profile : HANSELMAN
 All User Profile : HANSELMAN-N
 All User Profile : HanselSpot
 All User Profile : EliteWifi
 All User Profile : Qdoba Free Wifi

对于每一个资料,调用

 c:\>netsh wlan show profile "Qdoba Free Wifi"



Profile Qdoba Free Wifi on interface Wi-Fi:

=======================================================================



Profile information

-------------------
 Version : 1
 Type : Wireless LAN
 Name : Qdoba Free Wifi
 Control options :
 Connection mode : Connect manually



Connectivity settings

---------------------
 Number of SSIDs : 1
 SSID name : "Qdoba Free Wifi"
 Network type : Infrastructure

对于每一个资料,检查它们是否安全或开放,和你是否自动连接。然后,如果你想,你可以用netsh wlan delete profile命令删除Qdoba Free Wifi资料,即使这个热点不在你附近。

在我最近和安全专家Troy Hunt主持的广播里,他指出很容易创建一个假的蜜罐-和公共的开放网络同名的 Wi-Fi热点,像星巴克,例如。

  • 鉴于: 如果我的pc或手机被设置为自动连接到任何名为“Starbucks”开放热点,它就会连上去…即使是个邪恶的热点。
  • 因此: 自动删除那些开放(不安全)并设置为自动连接的Wi-Fi热点资料会很好

我有些厌倦了,所以我得赶紧搞出一个工程来做这个。我本可以使用PowerShell或其他的什么,但我想用C#。当作练习。

更新Lee Holmes用PowerShell写出来了!厉害。

Wifi.exe 和它的用法

clip_image002

厌倦了阅读 ? 这里有个构建好的Wifi.exe压缩包GitHub上的源码。你需要右击|属性|解压。

不保证质量。代码很逊而且我很菜,你运行的只是一个在我博客上发现的工程。不过呢,在我的机器上运行的很棒。感谢提出的问题,更感谢做出整洁的PR,运行Resharper并作出PR。如果bug报的好我会更新构建的。

如果你运行Wifi.exe(我放在了我的路径下),你会看到这些:

 c:\>wifi

AP-guest manual WPA2PSK

HANSELMAN-N auto WPA2PSK

HANSELMAN auto WPA2PSK

HanselSpot auto WPA2PSK

Qdoba Free Wifi manual open

Wayport_Access auto open Warning: AUTO connect to OPEN WiFi



Delete WiFi profiles that are OPEN *and* AUTO connect? [y/n]

n

注意列,和命令行窗口。当有个热点是开放的并且设置为自动连接会报出警告。如果你在命令行窗口回答Y,小程序会删除资料。你也可以键入“wifi/deleteautoopen”来绕过命令行窗口并自动删除开放并自动连接的资料

在我上传代码后不久一个pull request添加了一样的功能来删除热点名,这也是很棒的。谢谢!

    1: wifi delete "HOTSPOTNAME"

代码

写命令行应用的好处是有一打的方法来做任何事。

这很琐碎并且很傻,但同时也很有用很频繁。在这种情况下我思考命令行参数处理流程,从催生的流程中解析输出,干净利落的解析,确保能在非英文机器上运行(我想到了,但没测试),清理生成的临时文件。

代码给人印象不深,但其中一些很有趣。下面是一些我喜欢的。

Console.WriteLineString.Format实现列

你知道用String.Format可以右对齐或左对齐列吗?很少有人知道这点,我看过很多人是写死在里面的。

    1: Console.WriteLine(String.Format("{0,-20} {1,10} {2,10} {3,30} ", a.Name, a.ConnectionMode, a.Authentication,

注意{0,-20}(左对齐)和{1,10}(右对齐)。这就好像String.Format里的 {0}和{1} 一样,不过他们包含了对齐和宽度信息。

免费使用Linq

不用LinQ的工程会不会很傻,嗯?谁在可以对字符串执行SQL查询操作时却使用正则表达式?;)

事实上,我不知道这是不是好事。这很有趣,而且有用。你觉得呢?

它获取上面的wlan show profiles输出并解析成一列AP名字列表。我认为它可以在任何语言下使用,假设:这个冒号在那的话。

    1: string result = ExecuteNetSh("wlan show profiles");
    2: var listOfProfiles = from line in result.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries)
    3:                      where line.Contains(":")
    4:                      let l = line
    5:                      where l.Last() != ':'
    6:                      select l.Split(':')[1].Trim();
    7: foreach (string profile in listOfProfiles)
    8: ExecuteNetSh(String.Format("wlan export profile \"{0}\" folder=\"{1}\"", profile, Environment.CurrentDirectory));

清理临时XML文件

我以不定的扩展名导出了很多指定的XML文件。我不能控制它们的文件名,我也不想猜测它们的名字是什么。因为我可能需要重建它们的AP名字编码方案。替代方法是,我寻找当前文件夹(运行这个程序的人,很少把xml 文件放在一个同名文件夹中)下的XML文件,并且只删除命名空间显示在Wi-Fi资料中的那个。只是这个只需要我简单的处理一下。

    1: static XNamespace ns = "https://www.microsoft.com/networking/WLAN/profile/v1";
    2:  
    3: //Delete the exported profiles we made, making sure they are what we think they are! 
    4: foreach (string file in Directory.EnumerateFiles(Environment.CurrentDirectory, "*.xml"))
    5:       if (XElement.Load(file).Name.Namespace == ns)
    6:          File.Delete(file);

捕获命令行输出

最后,这里是如何开始获取输出的命令行处理流程:

    1: Process p = new Process();
    2: p.StartInfo.FileName = "netsh.exe";
    3: p.StartInfo.Arguments = arguments ?? String.Empty;
    4: p.StartInfo.UseShellExecute = false;
    5: p.StartInfo.RedirectStandardOutput = true;
    6: p.Start();
    7:  
    8: string output = p.StandardOutput.ReadToEnd();
    9: return output;

很基础,但很有用。

替代品

写完这些后我注意到有些WinForm程序也可以做这些。这很棒。如果它看起来和windows7对话框一样我不会介意使用它。看看我能不能把它弄到像素完美会很有趣。

有空来查看一下代码,玩一玩并取笑我吧。

https://github.com/shanselman/Windows-Wifi-Manager