Vista Wi-Fi Signal Strength
Tuesday, September 9, 2008 by CaptainBeaker | Discussion: DesktopX
** Works only with Vista **
I've been trying to make an object to display Wi-Fi signal strength in DX, on a Vista machine. There are several Widgets and objects in the WinCustomize library but none seem to work on Vista. I've been doing some research on the subject and can't find much solid info, other than recurring comments that the standard methods(using VBscript) that work on XP don't work on Vista.
I believe the MSNdis_80211_ReceivedSignalStrengt WMI Class (and other MSNdis_80211) classes don't play nice on Vista. This is the likely reason NetStumbler won't run on Vista.
A developer at: http://www.codeproject.com/KB/gadgets/WifiScanner.aspx used the command line info below to get SSID, strength, and other info. This command is normally run from the command line, but he runs it from code and he redirects the output to a text file and parses the info to get what he needs. I think this approach could be done with DX but I don't have the DX brainpower to make DX execute the command and redirect it to a text file. The parsing I could figure out.
netsh wlan show networks mode=bssi
I did run netsh wlan show networks mode=bssi > c:\text.txt from the command line and was able to redierct it to a text file, but that's as far as I can get and need to do it from code without a command window opening.
Any suggestions would be appreciated.
Thanks!
Reply #2 Wednesday, September 10, 2008 9:49 PM
I just submitted a working Vista Wi-Fi meter. Pending moderation, it should be available in a couple of days. Here is the script if anyone is interested:
- Const ForReading = 1, ForWriting = 2, ForAppending = 8
- 'Declare the file system object
- Dim fso, f, Msg
- Dim signal
- Dim SSID
- Set fso = CreateObject("Scripting.FileSystemObject")
- '************************************************************
- 'Called when the script is executed
- Sub Object_OnScriptEnter
- Dim UpdateInterval
- UpdateInterval = 60000 'Update this value to chabge the update interval
- Update
- Object.SetTimer 800 , UpdateInterval
- End Sub
- Sub Object_OnTimer800
- Update
- End Sub
- 'Called when the script is terminated
- Sub Object_OnScriptExit
- Object.KillTimer 800
- End Sub
- 'Called on mouse over object
- Sub Object_OnMouseEnter
- DesktopX.Object("WIFI Signal Text3").visible=True
- DesktopX.Object("WIFI Signal Text3").text = "SSID:" & SSID
- End Sub
- 'Called when mouse leaves object
- Sub Object_OnMouseLeave
- DesktopX.Object("WIFI Signal Text3").visible=False
- DesktopX.Object("WIFI Signal Text3").text = "SSID:" & SSID
- End Sub
- 'Called when L-click is pressed
- Function Object_OnLButtonDown(x,y)
- Update
- End Function
- Sub Update
- textfile = "c:\wifiinfo.txt"
- tempstring=""
- Set oShell = CreateObject("WScript.shell")
- strCommand = "cmd /c netsh wlan show networks mode=bssid > c:\wifiinfo.txt"
- oShell.run strCommand, 0, True 'runs the command and suppresses the command window
- 'Check if file exists
- If fso.FileExists(textfile) Then
- Set f = fso.OpenTextFile(textfile, ForReading)
- While Not f.AtEndOfStream
- getline = f.ReadLine
- fileinfo = fileinfo & getline & vbcrlf
- Wend
- f.Close
- Else
- msgbox "File does not exist"
- End If
- 'file loaded into fileinfo
- '**** parse out signal strength & SSID ****
- 'find the location of the 1st occurence of "%"
- pos=InStr(fileinfo,"%")
- 'move left 3 places and get 3 characters - this is the signal strength
- signal=Mid(fileinfo,(pos-3),3)
- signal=LTrim(signal)
- 'find SSID and strip stuff from left and right
- pos=InStr(fileinfo,"Network type") 'this is the next thing after the SSID name - find the position
- tempstring=Left(fileinfo,pos-1) 'strip everything after and including Network Type
- tempstring=RTrim(tempstring)
- tempstring=Left(tempstring,(Len(tempstring)-2)) 'this strips off the newline characters from the right
- pos=InStr(fileinfo,"SSID1 :") 'find the location of this in the remaining string
- tempstring=Right(tempstring,(pos+7)) 'then move over 7 spaces and strip everything from the left
- SSID = tempstring 'only the SSID with no spaces to the left or right remains
- ' **** parsing is done: netsh can return a string with data from more than one network, ****
- ' **** but parsing is done from the start of the string to find the first occurence of"%", which ****
- ' **** will be the currently active SSID and signal strength ****
- Select Case signal
- Case "100","99","98","97","96","95","94","93","92","91","90","89","88"
- object.State="6"
- DesktopX.Object("WIFI Status reflection").state ="6"
- Case "87","86","85","84","83","82","81","80","79","78","77","76","75","74","73"
- object.State="5"
- DesktopX.Object("WIFI Status reflection").state ="5"
- Case "72","71","70","69","68","67","66","65","64","63","62","61","60","59","58","57"
- object.State="4"
- DesktopX.Object("WIFI Status reflection").state ="4"
- Case "56","55","54","53","52","51","50","49","48","47","46","45","44","43","42"
- object.State="3"
- DesktopX.Object("WIFI Status reflection").state ="3"
- Case "41","40","39","38","37","36","35","34","33","32","31","30","29","28","27"
- object.State="2"
- DesktopX.Object("WIFI Status reflection").state ="2"
- Case "26","25","24","23","22","21","20","19","18","17","16","15","14","13","12","11"
- object.State="1"
- DesktopX.Object("WIFI Status reflection").state ="1"
- Case "10","9","8","7","6","5","4","3","2","1","0"
- object.State="1"
- DesktopX.Object("WIFI Status reflection").state ="1"
- Case Else
- object.State="No Signal"
- DesktopX.Object("WIFI Status reflection").state ="No Signal"
- End Select
- DesktopX.Object("WIFI Signal Text").text = signal &"%"
- DesktopX.Object("WIFI Signal Text2").text = signal &"%"
- DesktopX.Object("WIFI Signal Text3").visible=False
- DesktopX.Object("WIFI Signal Text3").text = "SSID:" & SSID
- End Sub
Reply #4 Wednesday, September 10, 2008 10:53 PM
Well, the first version isn't too fancy. It's more of a proof of concept for me than anything else. I plan to spruce it up with more user definable options, and fancier graphics. I designed this version to fit on my DX built taskbar, so it's small and basic so it does not take up much space.
Reply #6 Wednesday, September 10, 2008 11:08 PM
It should. It uses the standard netsh (Network Services Shell) command to do its business, which is included with XP.
Reply #7 Thursday, September 11, 2008 8:58 AM
ZubazDoes it work on XP too?I will try to test it on my XP machine so I can give a definate answer. The existing Wi-Fi meter objects in the Wincustomize library look like they work fine on XP(and are very nice) - based on the user comments. I would have been content to use one of these, but I tried a long time to get them to work on Vista and after some research found out that the WMI calls used won't work, so that's why I made it.
Reply #8 Thursday, September 11, 2008 5:29 PM
Just tested it on my XP machine. Does NOT work on XP. I geuss the netsh command has a little more functionality in Vista then in XP. XP users will have to use one of the other existing wifi widgets, sorry.
Reply #9 Thursday, September 11, 2008 5:42 PM
Going to update the description to indicate that?
Reply #10 Thursday, September 11, 2008 5:54 PM
Hey CaptainBeaker!
A little bit of feedback:
- creating a file at the root folder isn't really nice (plus you might not have the rights to do it anyway). It might be better to put that file in the temp directory. You can get it with the following script:
- Dim tempFolder Set WshShell = CreateObject("WScript.Shell") tempFolder = WshShell.ExpandEnvironmentStrings("%temp%")
- you can probably save the whole file creation and use the Exec command on the WScript.Shell object. It returns a WshScriptExec object with access to the StdOut and StdErr channels (ie. no need to redirect output). Take a look at the WScript help, there are a few examples on how to use it.
- that big switch case is hurting my eyes
. What's wrong with a few ifs and elses?
Reply #11 Thursday, September 11, 2008 5:57 PM
Sorry for the garbled script (and the edit button is not working
).
Good job on the widget. Looking forward for a version using the canvas ![]()
Reply #12 Thursday, September 11, 2008 9:07 PM
Thanks for the suggestions. I have done away with the select case and used your code to place the file in the user temp folder.
I'm still reading about WshScriptExec. It would be nice to capture the output of netsh without having to mess with a file. I did a quick test. The Exec command seems to call up a command window briefly when executing the NETSH command. I have to find a way to supress this command window or I'll be stuck with my method.
Reply #13 Thursday, September 11, 2008 9:19 PM
Me too! However, I have to get Canvas working on my Vista machine(s) first. I imported your .dxpack included in the latest build and still nothing. I put one of my drawing scripts into a new object and started the script. Got a (Null) error from my script on the following line:
Set ctx = canvas.getContext("2d")
The Canvas plug-in was added to the 'Additional Abilities' of the object
Reply #14 Thursday, September 11, 2008 11:30 PM
Mmmh, not good. I'm going to add some logging to the next beta so we can track down that problem. There is an error when creating the cairo surface and context for some reason (and it's strange that it's not crashing, given that this part is done earlier and lacks some error checking... oops
)
Reply #15 Tuesday, September 16, 2008 9:42 AM
that big switch case is hurting my eyes . What's wrong with a few ifs and elses?
I've been (partly) successful using Exec instead of Run and capturing the stdout and putting the result into a variable. The code bolw does exactly what I need it to do, but... It does not run under DX. It runs from the desktop fine - suppresses the cmd window and puts stdout into a variable. I don't think Wscript attributes are visible from within DX. I get object undefined errors wherever I have Wscript when I run the script from inside a Dx object. Telling the object to use an external script (containing the code below) still results in the same errors.
However, I have found a better solution which still uses the Run command and does not use a file. I had a revelation of sorts...Output from most command line functions can be directed to a file using ">", but starting with Server 2003, this same output can be directed to the Clipboard using "|clip" .
I've replaced all of the file saving and reading stuff with:
strCommand = "netsh wlan show networks mode=bssid |clip"
oShell.run strCommand, 0, True
netshresults = System.Clipboard
In my code, I save the current clipboard contents into a temp variable before I put the netsh stuff into it, then read the clipboard into a variable so I can parse it up. I then put the original contents of the clipboard back.
I'm currently testing everything right now and everything seems to be working. I'll post the update tonight.
- Set oShell = CreateObject("WScript.Shell") ' Make script run in Cscript so we can capture the std out of the Exec command. ' Must run in cscript because under wscript there is no way to suppress the command window If Instr(1, WScript.FullName, "CScript", vbTextCompare) = 0 Then oShell.Run "cscript """ & WScript.ScriptFullName & """", 0, False WScript.Quit End If ‘ execute command here strCommand = " netsh wlan show networks mode=bssi " set objShell = CreateObject("Wscript.Shell") set objProc = objShell.Exec(strCommand) Do
- WScript.Sleep 100 Loop Until objProc.Status <> 0 if objProc.ExitCode <> 0 then WScript.Echo "XXXXXX EXIT CODE: " & objProc.ExitCode WScript.Echo "XXXXXX ERROR: " & objProc.StdErr.ReadAll end if netsh_output = objProc.StdOut.ReadAll
Reply #16 Wednesday, September 17, 2008 10:49 AM
You could add some code to see if they are running XP or Vista, then use the above code for Vista and this WMI Call for XP:
Function to get Windows Version:
- Function Get_OSVersion()<br>
- strComputer = "."
- Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")
- Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_OperatingSystem",,48)
- cnt = 0
- For Each objItem In colItems
- cnt = cnt + 1
- Get_OSVersion = objItem.Caption
- Next
- End Function
- t = instr(1,UCase(Get_OSVersion),UCase("Vista"))
- If t> 0 Then
- '--- VISTA CODE HERE ---
- Else
- strComputer = "."
- Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\wmi")
- Set colItems = objWMIService.ExecQuery("Select * From MSNdis_80211_ReceivedSignalStrength")
- For Each objItem in colItems
- intStrength = objItem.NDIS80211ReceivedSignalStrength
- If intStrength > -57 Then
- strBars = "5 Bars"
- ElseIf intStrength > -68 Then
- strBars = "4 Bars"
- ElseIf intStrength > -72 Then
- strBars = "3 Bars"
- ElseIf intStrength > -80 Then
- strBars = "2 Bars"
- ElseIf intStrength > -90 Then
- strBars = "1 Bar"
- Else
- strBars = "Strength cannot be determined"
- End If
- Next
- end if
Reply #17 Wednesday, September 17, 2008 10:50 AM
yep.. EDIT btn aint working.. ignore the <br> in the Function call at the top of the code..
Enjoy
Reply #18 Wednesday, September 17, 2008 11:59 AM
Great idea!
Might be better to check for XP and use WMI only there, since it probably won't work with Windows 7 either.
Reply #19 Monday, December 28, 2009 1:20 PM
I never used DX and don't know how it exactly works, but i needed to know the signal of the wlan i'm connected to for samurize and used:
C:\Windows\System32\cmd.exe /c FOR /F "tokens=2 delims=: " %i IN ('netsh wlan show interfaces ^| find " Señal"') DO @echo %i
or directly on a command prompt
FOR /F "tokens=2 delims=: " %i IN ('netsh wlan show interfaces ^| find " Señal"') DO @echo %i
IMPORTANT NOTE: it works for me both in Vista and 7. But my system is in spanish, so probably you'll have to use "Signal" instead of "Señal" or you could also get any other info shown in netsh wlan show interfaces.
EDIT: For the 'show network' command it should be:
Again, changing "Señal" to "Signal" (or however it's written in english) for it to work in english systems.
Hope this helps
Please login to comment and/or vote for this skin.
Welcome Guest! Please take the time to register with us.
There are many great features available to you once you register, including:
- Richer content, access to many features that are disabled for guests like commenting on the forums and downloading skins.
- Access to a great community, with a massive database of many, many areas of interest.
- Access to contests & subscription offers like exclusive emails.
- It's simple, and FREE!







Reply #1 Tuesday, September 9, 2008 5:47 PM
Figured it out!
Set oShell = CreateObject("WScript.shell")
strCommand = "cmd /c netsh wlan show networks mode=bssid > c:\testing.txt"
oShell.run strCommand, 0, True
Won't be long and I'll have a working Wi-Fi meter that runs in Vista!