I got curious so I pulled the source for MadMACs. Turned out to be pretty straightforward to port the core logic to C#, so here it is if anyone is interested.
private const string baseReg =
@"SYSTEMCurrentControlSetControlClass{4D36E972-E325-11CE-BFC1-08002bE10318}";
public static bool SetMAC(string nicid, string newmac)
{
bool ret = false;
using (RegistryKey bkey = GetBaseKey())
using (RegistryKey key = bkey.OpenSubKey(baseReg + nicid))
{
if (key != null)
{
key.SetValue("NetworkAddress", newmac, RegistryValueKind.String);
ManagementObjectSearcher mos = new ManagementObjectSearcher(
new SelectQuery("SELECT * FROM Win32_NetworkAdapter WHERE Index = " + nicid));
foreach (ManagementObject o in mos.Get().OfType<ManagementObject>())
{
o.InvokeMethod("Disable", null);
o.InvokeMethod("Enable", null);
ret = true;
}
}
}
return ret;
}
public static IEnumerable<string> GetNicIds()
{
using (RegistryKey bkey = GetBaseKey())
using (RegistryKey key = bkey.OpenSubKey(baseReg))
{
if (key != null)
{
foreach (string name in key.GetSubKeyNames().Where(n => n != "Properties"))
{
using (RegistryKey sub = key.OpenSubKey(name))
{
if (sub != null)
{
object busType = sub.GetValue("BusType");
string busStr = busType != null ? busType.ToString() : string.Empty;
if (busStr != string.Empty)
{
yield return name;
}
}
}
}
}
}
}
public static RegistryKey GetBaseKey()
{
return RegistryKey.OpenBaseKey(
RegistryHive.LocalMachine,
InternalCheckIsWow64() ? RegistryView.Registry64 : RegistryView.Registry32);
}
For brevity's sake, I've left out the implementation of InternalCheckIsWow64()
, but that can be found here. Without this, I was running into issues with not finding the registry I wanted due to structural differences between 32- and 64-bit OSes.
Obligatory disclaimer -- play with the registry at your own peril.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…