{"record":{"id":"821e48ac7bbe52df","repo":"netchx/netch","slug":"getbestroute-821e48","errorCode":null,"errorMessage":"GetBestRoute 搜索失败","messagePattern":"GetBestRoute 搜索失败","errorType":"exception","errorClass":"MessageException","httpStatus":null,"severity":"error","filePath":"Netch/Utils/NetworkInterfaceUtils.cs","lineNumber":28,"sourceCode":"\npublic static class NetworkInterfaceUtils\n{\n    public static NetworkInterface GetBest(AddressFamily addressFamily = AddressFamily.InterNetwork)\n    {\n        string ipAddress;\n        switch (addressFamily)\n        {\n            case AddressFamily.InterNetwork:\n                ipAddress = \"114.114.114.114\";\n                break;\n            case AddressFamily.InterNetworkV6:\n                throw new NotImplementedException();\n            default:\n                throw new InvalidOperationException();\n        }\n\n        if (PInvoke.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse(ipAddress).GetAddressBytes(), 0), 0, out var route) != 0)\n            throw new MessageException(\"GetBestRoute 搜索失败\");\n\n        return Get((int)route.dwForwardIfIndex);\n    }\n\n    public static NetworkInterface Get(int interfaceIndex)\n    {\n        return NetworkInterface.GetAllNetworkInterfaces().First(n => n.GetIndex() == interfaceIndex);\n    }\n\n    public static NetworkInterface Get(Func<NetworkInterface, bool> expression)\n    {\n        return NetworkInterface.GetAllNetworkInterfaces().First(expression);\n    }\n\n    public static void SetInterfaceMetric(int interfaceIndex, int? metric = null)\n    {\n        var arguments = $\"interface ip set interface {interfaceIndex} \";\n        if (metric != null)","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/netchx/netch/blob/9d99eb1c5a2acbf2a34f2600f94242601019a300/Netch/Utils/NetworkInterfaceUtils.cs#L10-L46","documentation":"Identical mechanism to error [21] but in NetworkInterfaceUtils.GetBest, used to pick the best IPv4 NetworkInterface. It probes GetBestRoute to 114.114.114.114; a non-zero return means no IPv4 route exists, so it throws. Note the surrounding switch: AddressFamily.InterNetworkV6 throws NotImplementedException (not implemented), an unknown family throws InvalidOperationException, and only the IPv4 path reaches this GetBestRoute check. On success it returns the interface whose index matches route.dwForwardIfIndex.","triggerScenarios":"Calling GetBest() with no IPv4 default route: all NICs down/disabled, airplane mode, immediately after disabling the main NIC. Passing AddressFamily.InterNetworkV6 throws NotImplementedException instead, so it never reaches this check for IPv6.","commonSituations":"Selecting the outbound interface at startup with no network; a TUN/VPN having cleared routes; a machine with only IPv6 connectivity; calling GetBest before any interface is up.","solutions":["Bring up an IPv4 network interface with a default gateway and retry.","Check for a default route: `Get-NetRoute -DestinationPrefix 0.0.0.0/0`.","Do not pass AddressFamily.InterNetworkV6 (IPv6 selection is not implemented).","Restore any default route that a VPN client removed."],"exampleFix":"// before\nif (PInvoke.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse(ipAddress).GetAddressBytes(), 0), 0, out var route) != 0)\n    throw new MessageException(\"GetBestRoute 搜索失败\");\n// after - report the destination and cause\nif (PInvoke.GetBestRoute(BitConverter.ToUInt32(IPAddress.Parse(ipAddress).GetAddressBytes(), 0), 0, out var route) != 0)\n    throw new MessageException($\"No IPv4 route to {ipAddress}. Connect to a network.\");","handlingStrategy":"validation","validationCode":"// Ensure an Up IPv4 interface with a gateway exists\nvar hasIpv4 = NetworkInterface.GetAllNetworkInterfaces()\n    .Any(n => n.OperationalStatus == OperationalStatus.Up\n              && n.GetIPProperties().GatewayAddresses.Any(g => g.Address.AddressFamily == AddressFamily.InterNetwork));\nif (!hasIpv4)\n    throw new MessageException(\"No active IPv4 interface; cannot select best route.\");","typeGuard":"bool HasIpv4Route() => NetworkInterface.GetAllNetworkInterfaces()\n    .Any(n => n.OperationalStatus == OperationalStatus.Up\n              && n.GetIPProperties().GatewayAddresses.Any(g => g.Address.AddressFamily == AddressFamily.InterNetwork));","tryCatchPattern":"try { var ni = NetworkInterfaceUtils.GetBest(); }\ncatch (MessageException ex) when (ex.Message.Contains(\"GetBestRoute\"))\n{\n    Global.MainForm.NotifyTip(\"No IPv4 network available. Connect and retry.\");\n    return;\n}","preventionTips":["Gate GetBest behind a connectivity check (e.g. NetworkInterface.GetIsNetworkAvailable()).","Subscribe to NetworkChange.NetworkAddressChanged and retry when an IPv4 interface comes up.","Never call GetBest(AddressFamily.InterNetworkV6) until IPv6 support is implemented."],"tags":["network","routing","p-invoke","windows","network-interface"],"backgroundTag":null,"analyzedSha":"9d99eb1c5a2acbf2a34f2600f94242601019a300","analyzedAt":"2026-08-13T14:12:19.105Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}