You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF应用连接带密码WiFi失败,需触发Windows系统原生连接

WPF自助终端WiFi连接问题:无法连接加密网络

我开发了一款用于kiosk(自助服务终端)的WPF应用,在设置页实现了WiFi设置功能。目前能显示本地所有网络,也能连接、断开无密码网络,但无法连接带密码保护的网络(已知密码也不行)。我希望实现和Windows自带WiFi设置一样的逻辑:输入密码后触发系统层面的连接,而非在应用内处理,现在只收到「连接网络失败」的错误提示。

现有代码

namespace WPFDemo.pages
{
    public partial class SettingsPage : UserControl
    {
        private Dictionary<string, bool> networkConnectionStatus = new Dictionary<string, bool>();

        public SettingsPage()
        {
            InitializeComponent();
        }

        //Wi-Fi Function 
        private void TestToggleButton_Click(object sender, RoutedEventArgs e)
        {
            string ssid = "Alfa ProTeh";

            // Check current connection status
            if (IsConnectedToSSID(ssid))
            {
                // If connected, disconnect
                DisconnectFromWiFi();
            }
            else
            {
                // If not connected, try to connect
                ConnectToWiFi(ssid);
            }
        }
        private bool IsConnectedToSSID(string ssid)
        {
            // Use netsh to check the current connected WiFi SSID
            Process process = new Process();
            process.StartInfo.FileName = "netsh";
            process.StartInfo.Arguments = "wlan show interfaces";
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.CreateNoWindow = true;
            process.Start();

            string output = process.StandardOutput.ReadToEnd();
            process.WaitForExit();

            // This is a simple check; consider more robust parsing for real applications
            return output.Contains(ssid);
        }
        private void DisconnectFromWiFi()
        {
            ProcessStartInfo processStartInfo = new ProcessStartInfo("netsh", "wlan disconnect")
            {
                CreateNoWindow = true,
                UseShellExecute = false
            };

            Process process = Process.Start(processStartInfo);
            process.WaitForExit();
        }
        private void ConnectToWiFi(string ssid, string password = null)
        {
            string commandArguments = password == null ?
                $"wlan connect name=\"{ssid}\" ssid=\"{ssid}\"" :
                $"wlan connect name=\"{ssid}\" ssid=\"{ssid}\" key=\"{password}\""; // Note: The actual netsh command might differ for providing the password

            ProcessStartInfo processStartInfo = new ProcessStartInfo("netsh", commandArguments)
            {
                CreateNoWindow = true,
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true
            };

            Process process = new Process();
            process.StartInfo = processStartInfo;
            process.Start();
            process.WaitForExit();

            string output = process.StandardOutput.ReadToEnd();
            string error = process.StandardError.ReadToEnd();

            if (process.ExitCode == 0)
            {
                MessageBox.Show("Connected successfully to " + ssid, "Success", MessageBoxButton.OK, MessageBoxImage.Information);
            }
            else
            {
                MessageBox.Show("Failed to connect to " + ssid + ".\nError: " + error, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
        private void Expander_Expanded(object sender, RoutedEventArgs e)
        {
            wifiNetworksList.Items.Clear(); // Clear existing items

            ProcessStartInfo processStartInfo = new ProcessStartInfo("netsh", "wlan show networks")
            {
                CreateNoWindow = true,
                UseShellExecute = false,
                RedirectStandardOutput = true
            };

            using (Process process = new Process())
            {
                process.StartInfo = processStartInfo;
                process.Start();

                while (!process.StandardOutput.EndOfStream)
                {
                    string line = process.StandardOutput.ReadLine();
                    // Simple parsing based on the output format of netsh
                    if (line.Contains("SSID"))
                    {
                        string networkName = line.Split(new string[] { ":" }, StringSplitOptions.RemoveEmptyEntries)[1].Trim();
                        // Assume all networks are secured for this example
                        var isConnected = IsConnectedToSSID(networkName);
                        var buttonText = isConnected ? "Disconnect" : "Connect";
                        networkConnectionStatus[networkName] = isConnected; // Update your dictionary accordingly

                        var connectButton = new Button
                        {
                            Content = buttonText,
                            Tag = networkName,
                            Margin = new Thickness(5),
                        };
                        connectButton.Click += ConnectToNetwork_Click;

                        var passwordTextBox = new TextBox
                        {
                            Width = 120,
                            Margin = new Thickness(5),
                            Tag = networkName, // Use Tag to identify the network
                        };

                        var stackPanel = new StackPanel { Orientation = Orientation.Horizontal };
                        stackPanel.Children.Add(new TextBlock { Text = networkName, VerticalAlignment = VerticalAlignment.Center });
                        stackPanel.Children.Add(passwordTextBox);
                        stackPanel.Children.Add(connectButton);

                        var listBoxItem = new ListBoxItem();
                        listBoxItem.Content = stackPanel;
                        wifiNetworksList.Items.Add(listBoxItem);
                    }
                }
            }
        }
        private void scrollViewer_MouseWheel(object sender, MouseWheelEventArgs e)
        {
        }
        private void ConnectToNetwork_Click(object sender, RoutedEventArgs e)
        {
            Button connectButton = sender as Button;
            if (connectButton != null)
            {
                string networkName = connectButton.Tag.ToString();
                var passwordBox = ((StackPanel)connectButton.Parent).Children.OfType<TextBox>().FirstOrDefault(tb => tb.Tag.ToString() == networkName);

                if (connectButton.Content.ToString() == "Connect")
                {
                    string password = passwordBox?.Text;
                    ConnectToWiFi(networkName, password);
                    connectButton.Content = "Disconnect";
                    wifiToggleButton.IsChecked = true;
                }
                else
                {
                    DisconnectFromWiFi();
                    connectButton.Content = "Connect";
                    wifiToggleButton.IsChecked = false;
                }
            }
        }
        //Wi-Fi Function end 
    }
}

问题原因与修复方案

1. 核心错误:netsh命令参数错误

你当前使用的key=参数是无效的,Windows netsh连接加密网络时,正确的密码参数是keyMaterial=。这是导致连接失败的直接原因。

2. 修正ConnectToWiFi方法

替换原方法中的命令参数,使用正确的格式:

private void ConnectToWiFi(string ssid, string password = null)
{
    string commandArguments;
    if (password == null)
    {
        commandArguments = $"wlan connect name=\"{ssid}\" ssid=\"{ssid}\"";
    }
    else
    {
        // 使用正确的keyMaterial参数传递密码
        commandArguments = $"wlan connect ssid=\"{ssid}\" name=\"{ssid}\" keyMaterial=\"{password}\"";
    }

    ProcessStartInfo processStartInfo = new ProcessStartInfo("netsh", commandArguments)
    {
        CreateNoWindow = true,
        UseShellExecute = false,
        RedirectStandardOutput = true,
        RedirectStandardError = true
    };

    Process process = new Process();
    process.StartInfo = processStartInfo;
    process.Start();
    process.WaitForExit();

    string output = process.StandardOutput.ReadToEnd();
    string error = process.StandardError.ReadToEnd();

    if (process.ExitCode == 0)
    {
        MessageBox.Show($"成功连接到 {ssid}", "成功", MessageBoxButton.OK, MessageBoxImage.Information);
    }
    else
    {
        MessageBox.Show($"连接 {ssid} 失败。\n错误信息: {error}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
    }
}

3. 优化密码输入安全性

将密码输入框改为密码模式,避免明文显示:

var passwordTextBox = new TextBox
{
    Width = 120,
    Margin = new Thickness(5),
    Tag = networkName,
    PasswordChar = '*', // 隐藏密码字符
    IsPassword = true // 标记为密码输入框
};
// 或者更推荐使用PasswordBox控件:
// var passwordBox = new PasswordBox
// {
//     Width = 120,
//     Margin = new Thickness(5),
//     Tag = networkName
// };

4. 进阶:模拟Windows原生连接流程(推荐)

如果要完全和Windows自带WiFi设置一致,建议通过P/Invoke调用Windows WLAN API(如WlanSetProfile、WlanConnect),直接触发系统的连接逻辑,支持密码验证、配置保存等完整流程,比netsh更稳定可靠。

5. 其他小优化

  • 断开网络时指定SSID,避免误断其他网络:netsh wlan disconnect ssid=\"{ssid}\"
  • 优化SSID解析逻辑,避免重复读取(比如SSID 1:、SSID 2:):
if (line.StartsWith("    SSID ") && line.Contains(":"))
{
    string networkName = line.Split(new[] { ":" }, StringSplitOptions.RemoveEmptyEntries)[1].Trim();
    // 后续逻辑...
}

内容的提问来源于stack exchange,提问作者elzin kalabic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 11:45:54