Using netsh as a process to get wlan information - Memory Leak?

32 Views Asked by At

I've been trying different options to get the status and signal strength of the current wifi connection. WMI didn't work at all for me, then I stumbled across netsh.exe which returns everything I need. Unfortunately after polling this every 1 second, it seems to be slowing my system quite dramatically.

Here's the code:

Imports System.Threading
Namespace Wifi
Public Class SignalStrength
    Public Event UpdateData(Info As Info)
    Property WlanInfo As New Dictionary(Of String, String)
    Partial Public Class Info
        Property Name As String
        Property Description As String
        Property GUID As String
        Property State As String
        Property SSID As String
        Property Network_type As String
        Property Radio_Type As String
        Property Authentication As String
        Property Cipher As String
        Property Connection_mode As String
        Property Receive_rate As Double
        Property Transmit_rate As Double
        Property Profile As String
        Property Hosted_network_status As String
        Property Signal As Integer
        Public Sub New(WInfo As Dictionary(Of String, String))
            Name = WInfo("Name")
            Description = WInfo("Description")
            GUID = WInfo("GUID")
            State = WInfo("State")
            If State.ToLower = "connected" Then
                Network_type = WInfo("Network type")
                SSID = WInfo("SSID")
                Radio_Type = WInfo("Radio type")
                Authentication = WInfo("Authentication")
                Cipher = WInfo("Cipher")
                Connection_mode = WInfo("Connection mode")
                Receive_rate = WInfo("Receive rate (Mbps)")
                Transmit_rate = WInfo("Transmit rate (Mbps)")
                Signal = CInt(WInfo("Signal").Replace("%", ""))
                Profile = WInfo("Profile")
                Hosted_network_status = WInfo("Hosted network status")
            End If
        End Sub
    End Class
    Public Async Sub GetSignalStrength()
        Do
            Await Task.Run(Sub()
                               Using p As New Process With {
                                                            .StartInfo = New ProcessStartInfo With {
                                                            .Arguments = "wlan show interfaces",
                                                            .CreateNoWindow = True,
                                                            .UseShellExecute = False,
                                                            .FileName = "netsh.exe",
                                                            .RedirectStandardOutput = True
                                                            }}
                                   p.Start()
                                   WlanInfo = New Dictionary(Of String, String)
                                   While Not p.StandardOutput.EndOfStream
                                       Dim info = p.StandardOutput.ReadLine.Split(":")
                                       If info.Length = 2 Then
                                           WlanInfo.Add(info(0).Trim, info(1).Trim)
                                       End If
                                   End While
                               End Using
                               RaiseEvent UpdateData(New Info(WlanInfo))
                               Thread.Sleep(1000)
                           End Sub)
        Loop

    End Sub
End Class
End Namespace

As you can see I'm 'Using' the process, so it should be disposing after each call. Can anyone see someway to improve this, or possibly another option entirely?

EDIT

I think this is solved now... The update event fired every time the process finished, so now it checks for changes before firing the event.

Also I've switched from Async Sub and have created a new Threading.Thread with a continuous loop.

New code:

Do
            Using p As New Process With {.StartInfo = StartInfo}
                p.Start()
                Dim WlanInfo As New Dictionary(Of String, String)
                HasChanges = False
                While Not p.StandardOutput.EndOfStream
                    Dim info = p.StandardOutput.ReadLine.Split(":")
                    If info.Length = 2 Then
                        WlanInfo.Add(info(0).Trim, info(1).Trim)
                    End If
                End While
                If IsNothing(CurrentInfo) Then CurrentInfo = New Dictionary(Of String, String)
                For Each K As String In WlanInfo.Keys
                    If CurrentInfo.Keys.Contains(K) Then
                        If Not CurrentInfo(K) = WlanInfo(K) Then
                            HasChanges = True
                            CurrentInfo = WlanInfo
                            Exit For
                        End If
                    Else
                        HasChanges = True
                        CurrentInfo = WlanInfo
                        Exit For
                    End If
                Next
                If HasChanges Then
                    RaiseEvent UpdateRequired(New Info(CurrentInfo))
                End If
            End Using
        Loop

I'm still open to any ideas to improve this.

0

There are 0 best solutions below