c# - 从 WPF 应用程序以编程方式关闭/打开 Wi-Fi

标签 c# wpf visual-studio-2015 windows-10-desktop

我有一个带有控件(复选框/切换开关)的 WPF 应用程序。我想使用这些按钮打开/关闭 Wi-Fi。我已经尝试过以下代码,但似乎没有帮助

我使用的是 Windows 10 和 Visual Studio 2015

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication4
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            // string name = "Hello World";
        }


        static void Enable(string interfaceName)
        {
            System.Diagnostics.ProcessStartInfo psi =
                   new System.Diagnostics.ProcessStartInfo("netsh", "interface set interface \"" + interfaceName + "\" enable");
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo = psi;
            p.Start();
        }

        static void Disable(string interfaceName)
        {
            System.Diagnostics.ProcessStartInfo psi =
                new System.Diagnostics.ProcessStartInfo("netsh", "interface set interface \"" + interfaceName + "\" disable");
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo = psi;
            p.Start();
        }

        private void checkBox_Checked(object sender, RoutedEventArgs e)
        {
            string interfaceName = "Local Area Connection";

            Disable(interfaceName);


        }

    }
}

我经历了以下link与第一个答案,但没有任何帮助。

我需要一些帮助,以便我可以通过单击按钮以编程方式关闭/打开 Wi-Fi。

最佳答案

您可以通过 Native Wifi API 更改软件 radio 状态(而非硬件 radio 状态)来打开/关闭 Wi-Fi 。使用Managed Wifi API的一些代码项目中,我写了一个示例。

using System;
using System.Linq;
using System.Runtime.InteropServices;
using NativeWifi;

public static class WlanRadio
{
    public static string[] GetInterfaceNames()
    {
        using (var client = new WlanClient())
        {
            return client.Interfaces.Select(x => x.InterfaceName).ToArray();
        }
    }

    public static bool TurnOn(string interfaceName)
    {
        var interfaceGuid = GetInterfaceGuid(interfaceName);
        if (!interfaceGuid.HasValue)
            return false;

        return SetRadioState(interfaceGuid.Value, Wlan.Dot11RadioState.On);
    }

    public static bool TurnOff(string interfaceName)
    {
        var interfaceGuid = GetInterfaceGuid(interfaceName);
        if (!interfaceGuid.HasValue)
            return false;

        return SetRadioState(interfaceGuid.Value, Wlan.Dot11RadioState.Off);
    }

    private static Guid? GetInterfaceGuid(string interfaceName)
    {
        using (var client = new WlanClient())
        {
            return client.Interfaces.FirstOrDefault(x => x.InterfaceName == interfaceName)?.InterfaceGuid;
        }
    }

    private static bool SetRadioState(Guid interfaceGuid, Wlan.Dot11RadioState radioState)
    {
        var state = new Wlan.WlanPhyRadioState
        {
            dwPhyIndex = (int)Wlan.Dot11PhyType.Any,
            dot11SoftwareRadioState = radioState,
        };
        var size = Marshal.SizeOf(state);

        var pointer = IntPtr.Zero;
        try
        {
            pointer = Marshal.AllocHGlobal(size);
            Marshal.StructureToPtr(state, pointer, false);

            var clientHandle = IntPtr.Zero;
            try
            {
                uint negotiatedVersion;
                var result = Wlan.WlanOpenHandle(
                    Wlan.WLAN_CLIENT_VERSION_LONGHORN,
                    IntPtr.Zero,
                    out negotiatedVersion,
                    out clientHandle);
                if (result != 0)
                    return false;

                result = Wlan.WlanSetInterface(
                    clientHandle,
                    interfaceGuid,
                    Wlan.WlanIntfOpcode.RadioState,
                    (uint)size,
                    pointer,
                    IntPtr.Zero);

                return (result == 0);
            }
            finally
            {
                Wlan.WlanCloseHandle(
                    clientHandle,
                    IntPtr.Zero);
            }
        }
        finally
        {
            Marshal.FreeHGlobal(pointer);
        }
    }

    public static string[] GetAvailableNetworkProfileNames(string interfaceName)
    {
        using (var client = new WlanClient())
        {
            var wlanInterface = client.Interfaces.FirstOrDefault(x => x.InterfaceName == interfaceName);
            if (wlanInterface == null)
                return Array.Empty<string>();

            return wlanInterface.GetAvailableNetworkList(Wlan.WlanGetAvailableNetworkFlags.IncludeAllManualHiddenProfiles)
                .Select(x => x.profileName)
                .Where(x => !string.IsNullOrEmpty(x))
                .ToArray();
        }
    }

    public static void ConnectNetwork(string interfaceName, string profileName)
    {
        using (var client = new WlanClient())
        {
            var wlanInterface = client.Interfaces.FirstOrDefault(x => x.InterfaceName == interfaceName);
            if (wlanInterface == null)
                return;

            wlanInterface.Connect(Wlan.WlanConnectionMode.Profile, Wlan.Dot11BssType.Any, profileName);
        }
    }
}

通过 GetInterfaceNames 检查可用的接口(interface)名称,然后使用其中一个名称调用 TurnOn/TurnOff。根据 MSDN,它应该需要管理员权限,但在我的环境中不需要。


补充

我向此类添加了另外两个方法。所以顺序会是这样的。

  1. 通过 GetInterfaceNames 获取现有 Wi-Fi 接口(interface)名称。
  2. 选择一个接口(interface)并通过 TurnOn 将其打开。
  3. 通过 GetAvailableNetworkProfileNames 界面获取与可用 Wi-Fi 网络关联的配置文件名称。
  4. 选择一个配置文件并通过 ConnectNetwork 连接到网络。
  5. 使用完网络后,通过 TurnOff 关闭接口(interface)。

关于c# - 从 WPF 应用程序以编程方式关闭/打开 Wi-Fi,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34451581/

相关文章:

c# - 编码的 UI 测试生成器导致我的 Visual Studio 应用程序崩溃

typescript - 使用 TypeScript 装饰器导致错误

c# - 摆脱 C# 中的预编译器指令

c# - asp.net MVC 模型绑定(bind)一个字节数组

WPF 在 NET 3.5 中将命令附加到回车键上的文本框

WPF 和 MVVM : How to Refresh controls

c++ - 为什么第二个输出是6?

c# - DataGridView 滚动事件(和 ScrollEventType.EndScroll)

c# - asp 的 Javascript 更多/更少文本按钮 :label

WPF MVVM : Notifying the View of a change to an element within an ObservableCollection?