3

This problem prevents connecting to a new network using Simple WiFi (NuGet, GitHub). For whatever reason, a connection point that already has a profile works just fine.

The problem line is accessPoint.Connect(request). When the password is wrong, this works fine. When the password is right, however, an exception gets thrown from System.Private.CoreLib.

After taking a look at other samples on the web, it seems like everything is done correctly. I therefore created a sample application to reproduce the error (WPF, .NET 6.0):

MainWindow.xaml.cs

using SimpleWifi;
using SimpleWifi.Win32;
using System;
using System.Linq;
using System.Windows;
using System.Windows.Media;

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

        private void RefreshAndAssignWiFiConnections()
        {
            // Refresh WiFi list
            // https://stackoverflow.com/a/65024992/4682228
            var client = new WlanClient();
            foreach (WlanInterface wlanInterface in client.Interfaces)
                wlanInterface.Scan();

            Wifi wifi = new Wifi();
            var accessPoints = wifi.GetAccessPoints()
                              .OrderByDescending(ap => ap.SignalStrength)
                              .Where(ap => !string.IsNullOrEmpty(ap.Name))
                              .Select(ap => ap.Name)
                              .ToList();
            ComboBox_WiFiConnections.ItemsSource = accessPoints;
            ComboBox_WiFiConnections.SelectedItem = accessPoints.FirstOrDefault();
        }

        private void ComboBox_WiFiConnections_DropDownOpened(object sender, EventArgs e)
        {
            RefreshAndAssignWiFiConnections();
        }

        private void PasswordBox_WiFiPassword_PasswordChanged(object sender, RoutedEventArgs e)
        {
            PasswordBox_WiFiPassword.BorderBrush = Brushes.Transparent;
        }

        private void Button_WiFiLogin_Click(object sender, RoutedEventArgs e)
        {
            Wifi wifi = new Wifi();
            var accessPointName = ComboBox_WiFiConnections.SelectedValue as string;
            var accessPoint = wifi.GetAccessPoints().FirstOrDefault(ap => ap.Name == accessPointName);
            AuthRequest request = new(accessPoint)
            {
                Password = PasswordBox_WiFiPassword.Password,
            };
            try
            {
                if (request.IsUsernameRequired)
                {
                    // Doesn't reach: username not missing
                }
                if (request.IsDomainSupported)
                {
                    // Doesn't reach: no domain supported
                }
                if (accessPoint.Connect(request)) // This call throws the exception
                {
                    // Success!
                    // ...
                }
                else
                {
                    // Wrong password
                    PasswordBox_WiFiPassword.BorderBrush = Brushes.Red;
                }
            }
            catch (Exception ex)
            {
                // "Value cannot be null. (Parameter 'stream')"
                // at System.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
                // at System.IO.StreamReader..ctor(Stream stream, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean leaveOpen)
                // at SimpleWifi.ProfileFactory.GetTemplate(String name)
                // at SimpleWifi.ProfileFactory.Generate(WlanAvailableNetwork network, String password)
                // at SimpleWifi.AuthRequest.Process()
                // at SimpleWifi.AccessPoint.Connect(AuthRequest request, Boolean overwriteProfile)
                // at MecaView.Main.Button_WiFiLogin_Click(Object sender, RoutedEventArgs e) in C: \Users\dlabrecque\Documents\GitHub\MecaView\Prj\Main.xaml.cs:line 669
            }
        }
    }
}

MainWindow.xaml

<StackPanel>
    <ComboBox x:Name="ComboBox_WiFiConnections" DropDownOpened="ComboBox_WiFiConnections_DropDownOpened" Width="200"/>
    <PasswordBox x:Name="PasswordBox_WiFiPassword" PasswordChanged="PasswordBox_WiFiPassword_PasswordChanged" Width="200"/>
    <Button x:Name="Button_WiFiLogin" Click="Button_WiFiLogin_Click" Content="Login" Width="200"/>
</StackPanel>

Anyone know why this exception might be happening? A missing parameter? A bug in the library?

Note: it may be others are getting a problem with the same symptoms; question 1, question 2.

Denis G. Labrecque
  • 1,023
  • 13
  • 29
  • 1
    Have you tried to report the problem on the Github library page? – IFrank Aug 16 '22 at 20:36
  • @FrankProp the original .NET Framework repo https://github.com/DigiExam/simplewifi has the issues feature, but not the .NET standard repo I'm using https://github.com/mahdi-ataollahi/simplewifi. The original example seems to work fine as well, though using WPF .NET 6 I haven't been able to use it. – Denis G. Labrecque Aug 17 '22 at 19:15
  • 1
    So the same, identical code works in .Net Framework and doesn't work in .Net 6? – IFrank Aug 17 '22 at 19:26

1 Answers1

1

I had the exact same issue trying to use it in a Winforms application using .NET6.

Listing the networks, disconnecting from the network, and connecting to a network with a saved profile, all work perfectly. But overwriting a network with a profile, or trying to connect to a network that does not have a known profile throws the exception.

Running the standalone console app, works fine.

The error is there because it is not reading the template XML files. This is what I did to get it to work for me (the code probably could be simpler, but this is how I implemented it).

private static string GetTemplate(string name)
{
    string resourceName = string.Format("SimpleWifi.ProfileXML.{0}.xml", name);
    string result = string.Empty;
    var assembly = System.Reflection.Assembly.GetExecutingAssembly();
    using (var filestream = assembly.GetManifestResourceStream(resourceName))
    {
        byte[] fileContents = new byte[filestream.Length];
        filestream.Read(fileContents, 0, fileContents.Length);
        //
        using (MemoryStream stream = new MemoryStream(fileContents))
        {
            using (StreamReader sr = new StreamReader(stream))
            {
                result = sr.ReadToEnd();
            }
        }
    }
    return result;
}
DTrain
  • 21
  • 3