AutoHotkey Community

It is currently May 26th, 2012, 7:10 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 43 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: May 27th, 2009, 5:29 pm 
Offline
User avatar

Joined: September 8th, 2008, 12:26 am
Posts: 1048
Location: Ploieşti, RO
While some people like to mock newbies instead of helping them, others still remember how it feels like. Besides, it's annoying having to deal with a DOS command window when calling the built-in ping.exe in Win9x. Maybe someone will find this function useful.

Main function to call is Ping(); the others are helpers but may be used independently, if needed.

Changelog:
Code:
*** v2.0 changes the function name, as requested by tuncay down this topic

EDIT May 29, 2009
v1.1
The function code has been cleaned up a little by removing the example. Also a few comments have been added.
Another example, in form of a ready-to-use script, has been provided separately.

Example has been updated at 18:36 EEST.
v1.2
Added speech capabilities thanks to the script provided at http://www.autohotkey.com/forum/viewtopic.php?p=229945#229945 (thank you, DerRaphael).
It requires the COM library, downloadable at http://www.autohotkey.com/forum/viewtopic.php?t=22923 (thank you, Sean).
/EDIT

June 13, 2009
v1.5.1
- Added settings saving through ini file
- Added translation option

July 7, 2009
-Fixed small typo in main function script (ErroLevel -> ErrorLevel)

April 29, 2010
v2.0
• As per Tuncay's request (see the forum topic), the names of all functions have been changed for better stdlib compatibility. Main function - formerly A_Ping() - is now called ping(); script's name has been changed accordingly, version was raised to 2.0. The NetCon Alert script has also been modified to reflect the aforementioned changes and its version was also boosted to 2.0 (for consistency with the function version).

July 14, 2010 v2.1.0
• added round trip display, on request
• minor change to the _T(string) function

September 5, 2010
• Changed script date (thanks Tuncay for the heads up)

The ping() function is unchanged; only the NetCon Alert example script was modified, as mentioned above.


Download page for NetCon Alert (includes ping() function and older versions):
NetCon Alert download page

COMPATIBILITY: AutoHotkey 1.0.48.05 (AHK Basic)
==============

Feel free to modify any of them if they don't work in your super-duper OS - it's been built and tested in Win98SE only. 8)

Image
NetCon Alert example:
Code:
; NetCon Alert by Drugwash, January 1, 2010
version=2.1.0
;***********************************************
#Persistent
#NoEnv
#SingleInstance, force
SetBatchLines, -1
DetectHiddenWindows, On
SetWorkingDir %A_ScriptDir%
p = %1%
debug := RegExMatch(p, "i)d[e]b[u]g")
inifile := "NCA_settings.ini"
IfNotExist, %inifile%
   {
   spk=0               ; speech activation switch
   isit=0               ; speech limit switch
   times=1               ; speech count
   spoken=0            ; spoken count
   hostlist=127.0.0.1|192.168.2.1|www.google.com||www.wikipedia.com|99.99.99.99|
   ;host := "www.google.com"   ; address to ping (preselected in the ComboBox)
   data=AHK test         ; data to be sent on ping
   timeout=500            ; ping timeout [ms]
   itime=5000            ; initial ping loop time [ms]
   stime=1000            ; secondary ping time [ms]
   pause=0               ; pause checking switch
   fail=0               ; failure count
   chk=0               ; failed checks count (per host)
   max = 3               ; no. of failures that yield alert
   time := itime            ; set timer to ping loop time
   lang=EN               ; default language
   }
else
   {
   IniRead, spk, %inifile%, Settings, UseSpeech, 0
   IniRead, isit, %inifile%, Settings, LimitSpeech, 0
   IniRead, times, %inifile%, Settings, SpeechLimitTimes, 1
   IniRead, itime, %inifile%, Settings, PrimaryPingDelay, 5000
   IniRead, stime, %inifile%, Settings, SecondaryPingDelay, 1000
   IniRead, max, %inifile%, Settings, Failures, 3
   IniRead, hostlist, %inifile%, Hosts, HostList, 127.0.0.1|192.168.2.1|www.google.com||www.wikipedia.com|99.99.99.99|
   IniRead, data, %inifile%, Ping, Data, AHK test
   IniRead, timeout, %inifile%, Ping, Timeout, 500
   IniRead, lang, %inifile%, Translation, Language, EN
   }
end := InStr(hostlist, "||")-1
Loop
   if (A_Index = end || SubStr(hostlist, end - A_Index, 1) = "|")
      {
      begin := end - A_Index + 1
      end := end - begin + 1
      break
      }
host := SubStr(hostlist, begin, end)
langtmpl := ".\lang\NCA_lang_EN.ini"
langfile := ".\lang\NCA_lang_" lang ".ini"
lang := (lang) ? lang : "EN"
mtitle := "NetCon Alert " version   ; main window title
stitle := "NCA Settings"         ; settings window title
;***********************************************
if !A_IsCompiled
   Menu, Tray, Icon, NCA.ico
Menu, Tray, NoStandard
Menu, Tray, Add, Show notification, showit
Menu, Tray, Add, Settings, setit
Menu, Tray, Add, Pause pinging, pauseit
Menu, Tray, Add, Exit, quitit
Menu, Tray, Default, Show notification
if debug
   Menu, Tray, Add, Reload, reloadit
;***********************************************
Gui, Margin, 10, 10
Gui, Add, Groupbox, xm ym-5 w310 h100 Center, Notification
Gui, Add, Checkbox, xp y+13 w110 vbugger, Don't show again
Gui, Font, s18 cRed bold, Tahoma
Gui, Add, Text, xm+5 ym+10 w300 h30 Center +0x200, Network OK !
Gui, Font
Gui, Add, Text, xp y+5 w300 h14 Center +0x200, No ping to %host% failed so far.
Gui, Add, Text, xp y+1 w300 h14 Center +0x200, Network connection is up and running.
Gui, Add, Text, xp y+1 w300 h14 Center +0x200,
Gui, Add, Button, x120 y+20 w80 h30 Default, OK
Gui, Add, Button, x+60 yp+3 w60 h24 +0x8000, Settings   ; BS_FLAT style
Gui, Show, Hide, %mtitle%
;***********************************************
Gui, 2:Margin, 5, 5
Gui, 2:Add, Groupbox, xm ym-5 w160 h140, Ping
Gui, 2:Add, Text,xm+5 yp+15, Host name or address:
Gui, 2:Add, ComboBox, xp y+2 w150 r7 Sort vhostlist, %hostlist%
Gui, 2:Add, Text, xp y+5, Data to be sent with PING:
Gui, 2:Add, Edit, xp y+2 w150 -Multi Limit vdata, %data%
Gui, 2:Add, Text, xp y+5 w70, Timeout:
Gui, 2:Add, Edit, xp y+2 w30-Multi Limit Number vtimeout, %timeout%
Gui, 2:Add, Text, x+5 yp w30 h20 +0x200, ms.
Gui, 2:Add, Button, x+5 yp-2 w80 h24 +0x8000, Remove host   ; BS_FLAT style
Gui, 2:Add, Groupbox, xm y+10 w160 h60, Speech
Gui, 2:Add, Checkbox, xm+5 yp+15 w150 vts gtspeech, Speak when ping fails
Gui, 2:Add, Checkbox, xp+14 y+7 Disabled vdeaf gisenough, Only speak
Gui, 2:Add, Edit, x+2 yp-3 w30 Limit2 Number -Multi Disabled venough ghowmuch, %times%
Gui, 2:Add, UpDown, vtimes Range1-999, %times%
Gui, 2:Add, Text, x+3 yp+3 w30 Disabled, time
Gui, 2:Add, Button, xm y+20 w54 h24 Default, OK
Gui, 2:Add, Button, x+46 yp w60 h24, Cancel
Gui, 2:Add, DDL, xm+56 yp+2 w40 h20 r10 vlng,
GuiControl,2:, Button4, %spk%
if spk
   GuiControl, 2:Enable, Button5
GuiControl,2:, Button5, %isit%
if isit && spk
   {
   GuiControl, 2:Enable, Edit4
   GuiControl, 2:Enable, Static5
   }
Gui, 2:Show, Hide, %stitle%
Gui, 2:Submit
WinGet, controlsD, ControlList, %mtitle%
WinGet, controlsS, ControlList, %stitle%
gosub lang
Loop, .\lang\NCA_lang_??.ini
   langall := (langall) ? langall "|" SubStr(A_LoopFileName, 10,2) : SubStr(A_LoopFileName, 10,2)
GuiControl, 2:, ComboBox2, %langall%
GuiControl, 2:ChooseString, ComboBox2, %lang%
;***********************************************
host := hostlist
fail=1      ; helps initializing display info after first ping
SetTimer, chknet, %itime%
return
;***********************************************
; ping timer subroutine
chknet:
res := ping(host, data, timeout)         ; ping the selected host
rt := NumGet(res+0, 8, "UInt")         ; get reply time [ms]
if SubStr(res, 1, 5) = "Error"            ; check for reply error
   {
   if !fail
      SetTimer, chknet, %stime%      ; shorten the ping loop time
   fail++      ; count subsequent failures
   if (fail = max)
      {
      fail=0
      SetTimer, chknet, %itime%
      chk++
      gc := chk=1 ? "" : "s"
      GuiControl,, Static1, % _T(not1f)
      GuiControl,, Static2, % _T(not2f)
      GuiControl,, Static3, % _T(not3f)
      GuiControl,, Static4, % _T(not6f)
      if !bugger
         Gui, Show
      if spk
         gosub speakit
      }
   }
else
   if fail
      goto resetit
else
   GuiControl,1:, Static4, % _T(not6)
return

resetit:
fail = 0               ; reset failure count
SetTimer, chknet, %itime%   ; reset ping loop time
GuiControl,1:, Static1, % _T(not1)
GuiControl,1:, Static2, % _T(not2)
GuiControl,1:, Static3, % _T(not3)
GuiControl,1:, Static4, % _T(not6)
return

ButtonOK:
GuiEscape:
GuiClose:
Gui, Submit
return

ButtonSettings:
setit:
if !pause
   gosub pauseit         ; pause the script while changing settings
Gui, 2:Show
ControlGet, hlc, List,, ComboBox1, %stitle%
ControlGetText, olddata, Edit2, %stitle%
ControlGetText, oldtout, Edit3, %stitle%
ControlGet, oldspeech, Checked,, Button4, %stitle%
ControlGet, olddeaf, Checked,, Button5, %stitle%
ControlGetText, oldenough, Edit4, %stitle%
ControlGetText, oldtimes, Static5, %stitle%
ControlGet, oldlang, Choice,, ComboBox2, %stitle%
return

2ButtonRemovehost:
Gui, 2:Submit, NoHide
ControlGet, hlct, List,, ComboBox1   , %stitle%   ; get the list of host
ControlGetText, badhost, Edit1, %stitle%      ; get selected host
pos := InStr(hlct, badhost, false, 1)   ; check if selected host belongs to the list
if pos
   {
   if pos = 1
   hlct := SubStr(hlct, pos+StrLen(badhost)+1)
   else if (pos+StrLen(badhost) = StrLen(hlct))
   hlct := SubStr(hlct, 1, pos-1)
   else
   hlct := SubStr(hlct, 1, pos-1) SubStr(hlct, pos+StrLen(badhost)+1)
   StringReplace, hlct, hlct, `n, |, All
   StringReplace, hlct, hlct, |, ||
   GuiControl, 2:, ComboBox1, |%hlct%   
   Gui, 2:Submit, NoHide
   }
return

2ButtonOK:   ; save settings
Gui, 2:Submit,NoHide
host := hostlist ? hostlist : "www.google.com"
data := data ? data : "AHK test"
timeout := timeout ? timeout : "500"
ControlGet, hlc, List,, ComboBox1, %stitle%
IfNotInString, hlc, %host%
   GuiControl, 2:, ComboBox1, %host%||
Gui, 2:Submit, NoHide
chk=0            ; reset failure count per host
fail=1            ; this helps in resetting display info
spoken=0         ; reset speech count per host
lang := lng
ControlGet, hlc, List,, ComboBox1, %stitle%
StringReplace, hlc, hlc, `n, |, All
StringReplace, hlc, hlc, %host%, %host%|
IniWrite, %spk%, %inifile%, Settings, UseSpeech
IniWrite, %isit%, %inifile%, Settings, LimitSpeech
IniWrite, %times%, %inifile%, Settings, SpeechLimitTimes
IniWrite, %itime%, %inifile%, Settings, PrimaryPingDelay
IniWrite, %stime%, %inifile%, Settings, SecondaryPingDelay
IniWrite, %max%, %inifile%, Settings, Failures
IniWrite, %hlc%, %inifile%, Hosts, HostList
IniWrite, %data%, %inifile%, Ping, Data
IniWrite, %timeout%, %inifile%, Ping, Timeout
IniWrite, %lang%, %inifile%, Translation, Language
Gui, 2:Hide
GuiControl,1:, Static1, % _T(not4)
GuiControl,1:, Static2, % _T(not5)
GuiControl,1:, Static3,
goto pauseit

2ButtonCancel:      ; (cancel any changes and) close the settings panel
2GuiEscape:
2GuiClose:
if hlct
   GuiControl, 2:, ComboBox1, |%hlc%
hlct=
GuiControl, 2:ChooseString, ComboBox1, %host%
GuiControl, 2:, Edit2, %olddata%
GuiControl, 2:, Edit3, %oldtout%
GuiControl, 2:, Button4, %oldspeech%
GuiControl, 2:, Button5, %olddeaf%
spk := oldspeech
isit := olddeaf
gosub common
GuiControl, 2:, enough, %oldenough%
GuiControl, 2:, times, %oldtimes%
GuiControl, 2:ChooseString, ComboBox2, %oldlang%
gosub howmuch
Gui, 2:Hide
goto pauseit

showit:
Gui, Show
return

pauseit:
Menu, Tray, ToggleCheck, Pause pinging
pause := !pause
op := pause ? "Off" : "On"
SetTimer, chknet, %op%
return

reloadit:
Reload
quitit:
if iscom
   {
   COM_Release(pspeaker)
   COM_Term()
   }
ExitApp


speakit:   ; using the script from http://www.autohotkey.com/forum/viewtopic.php?p=229945#229945
if (deaf && spoken >= enough)
   return
if !iscom
   iscom := COM_Init()
pspeaker := COM_CreateObject("SAPI.SpVoice")
txt := spkmsg ? spkmsg : "Network failure! Please check your network connection."
COM_Invoke(pspeaker, "Speak", txt)
spoken++
return

tspeech:
spk := !spk
common:
op := spk ? "Enable" : "Disable"
GuiControl, 2:%op%, Button5
if isit & spk
   {
   GuiControl, 2:Enable, Edit4
   GuiControl, 2:Enable, Static5
   }
else
   {
   GuiControl, 2:Disable, Edit4
   GuiControl, 2:Disable, Static5
   }
return

howmuch:
ControlGetText, isenough, Edit4
GuiControl,, times, %isenough%
if lang = EN
   {
   timeshow := isenough != 1 ? "times" : "time"
   GuiControl, 2:, Static5, %timeshow%
   }
return

isenough:
isit := !isit
spoken := isit ? "0" : spoken
goto common

lang:
IfNotExist, %langtmpl%
   {
   Loop, Parse, controlsD, `n
      {
      ControlGetText, field, %A_LoopField%, %mtitle%
      if A_LoopField not contains Static
         IniWrite, %field%, %langtmpl%, Display, %A_LoopField%
      }
   Loop, Parse, controlsS, `n
      {
      ControlGetText, field, %A_LoopField%, %stitle%
      if A_LoopField not contains ComboBox,Edit,msctls_updown32
         IniWrite, %field%, %langtmpl%, Settings, %A_LoopField%
      }
   IniWrite, Network OK !, %langtmpl%, Notifications, NetOK
   IniWrite, Network failure!, %langtmpl%, Notifications, NetFailed
   IniWrite, No ping to `%host`% failed so far., %langtmpl%, Notifications, NetOKinfo
   IniWrite, Pinging `%host`% failed `%chk`% time`%gc`%., %langtmpl%, Notifications, NetFailedInfo
   IniWrite, Network connection is up and running., %langtmpl%, Notifications, NetOKdetails
   IniWrite, Please check your network connection and/or settings below., %langtmpl%, Notifications, NetFailedDetails
   IniWrite, Please wait..., %langtmpl%, Notifications, HostResetWait
   IniWrite, Pinging `%host`%, %langtmpl%, Notifications, HostResetPing
   IniWrite, Round trip : %rt% ms, %langtmpl%, Notifications, RoundTrip
   IniWrite, Timeout >= %timeout% ms, %langtmpl%, Notifications, RoundTripFailed
   IniWrite, Network failure! Please check your network connection., %langtmpl%, Notifications, SpokenMessage
   }
if (lang = "EN" || !FileExist(langfile) )
   langfile := langtmpl
Loop, Parse, controlsD, `n
   {
   IniRead, field, %langfile%, Display, %A_LoopField%, skip
   if field != skip
      GuiControl,1:, %A_LoopField%, % _T(field)
   }
Loop, Parse, controlsS, `n
   {
   IniRead, field, %langfile%, Settings, %A_LoopField%, skip
   if field != skip
      GuiControl,2:, %A_LoopField%, %field%
   }
IniRead, not1, %langfile%, Notifications, NetOK, Network OK !
IniRead, not1f, %langfile%, Notifications, NetFailed, Network failure!
IniRead, not2, %langfile%, Notifications, NetOKinfo, No ping to %host% failed so far.
IniRead, not2f, %langfile%, Notifications, NetFailedInfo, Pinging %host% failed %chk% time%gc%.
IniRead, not3, %langfile%, Notifications, NetOKdetails, Network connection is up and running.
IniRead, not3f, %langfile%, Notifications, NetFailedDetails, Please check your network connection and/or settings below.
IniRead, not4, %langfile%, Notifications, HostResetWait, Please wait...
IniRead, not5, %langfile%, Notifications, HostResetPing, Pinging %host%
IniRead, not6, %langfile%, Notifications, RoundTrip, Round trip : %rt% ms
IniRead, not6f, %langfile%, Notifications, RoundTripFailed, Timeout >= %timeout% ms
IniRead, spkmsg, %langfile%, Notifications, SpokenMessage, Network failure! Please check your network connection.
return

_T(string)
{
Global
Transform, strong, Deref, %string%
if debug
   msgbox, Old string: %string%`nNew string: %strong%`nHost: %host%
return strong
}

; download "com.ahk" from http://www.autohotkey.com/forum/viewtopic.php?t=22923
;comment any of the lines below if you have the respective function in the lib folder
;#include ping.ahk
;#include COM.ahk



Ping function:
Code:
; Ping function by Drugwash April 29, 2010
; v2.0
;*********************************
ping_(adr, data, timeout)
{
static reply
ErrorLevel = 0
SetFormat, IntegerFast, H
cAdr := DllCall("wsock32\inet_addr", UInt, &adr, UInt)   ; convert address to 32bit UInt
if cAdr = 0xFFFFFFFF
   cAdr := DllCall("ws2_32\inet_addr", str, adr, Int) ; second attempt at conversion, using ws2_32
      if cAdr = 0xFFFFFFFF
         {
         ErrorLevel = 1
         return err := "Error: Cannot convert address to UInt."
         }
; test for function presence since it's located in different libs through various OS
hLib := DllCall("LoadLibrary", str, "iphlpapi.dll")
if hLib
   {
   hPrAdr := DllCall("GetProcAddress", UInt, hLib, str, "IcmpCreateFile")
   if hPrAdr
;      hPort := DllCall("iphlpapi\IcmpCreateFile", UInt)   ; open a port (iphlpapi.dll in XP+)
      hPort := DllCall(hPrAdr, UInt)   ; open a port (iphlpapi.dll in XP+)
   else
      DllCall("FreeLibrary", UInt, hLib)
   }
if !hPort
   hPort := DllCall("icmp\IcmpCreateFile", UInt)   ; open a port (icmp.dll in Win2000 and lower)
if !hPort
   {
   ErrorLevel = 1
   return err := "Error: Cannot open port."
   }
SetFormat, Integer, D
szreply = 278                ; ICMP_ECHO_REPLY structure
VarSetCapacity(reply, szreply, 0)
DllCall("icmp\IcmpSendEcho", UInt, hPort, UInt, cAdr, UInt, &data, UInt, StrLen(data), UInt, NULL, UInt, &reply, UInt, szreply, UInt, timeout, UInt)
errcode := NumGet(reply, 4, "UInt")   ; check for status
errcode := errcode <> 0 ? errcode : errcode+11000
if errcode = 11001   ; function returned 'buffer too small' so we increase it and try again
   {
   VarSetCapacity(reply, NumGet(reply, 12, "UShort")+16)
   DllCall("icmp\IcmpSendEcho", UInt, hPort, UInt, cAdr, UInt, &data, UInt, StrLen(data), UInt, NULL, UInt, &reply, UInt, szreply, UInt, timeout, UInt)
   errcode := NumGet(reply, 4, "UInt")   ; another check for status on 2-nd attempt
   errcode := errcode <> 0 ? errcode : errcode+11000
   }
err := ping_GetError(errcode, "IcmpSendEcho")   ; error handling
DllCall("icmp\IcmpCloseHandle", UInt, hPort)   ; close port
if errcode != 11000            ; IP_SUCCESS
   {
   ErrorLevel = 1
   return err
   }
else
; on success returns ICMP_ECHO_REPLY structure address for external processing of data
   return err := &reply
}
;*********************************
ping_GetError(code, func="[ukn]")      ; error translation
{
str := "Success|Reply buffer too small|Destination network unreachable|Destination host unreachable|Destination protocol unreachable|Destination port unreachable|Insufficient IP resources|Bad IP option specified|Hardware error|Packet too big|Request timed out|Bad request|Bad route|TTL expired in transit|TTL expired during fragment reassembly|Parameter problem|Datagrams are arriving too fast to be processed and datagrams may have been discarded|IP option too big|Bad destination|General failure (possible malformed ICMP packets)"
Loop, Parse, str, |
   {
   if (code = 11000 + A_Index - 1) || (A_Index = 20 && code = 11050)
      return err := "Error " code " [" A_LoopField "] in function " func
   }
return err := "Function " func " returned " code
}
;*********************************
ping_Host2IP(name)
{
ErrorLevel = 0
type := SubStr(name, 1, 1)
if type is alpha
   {
   hostent := DllCall("ws2_32\gethostbyname", UInt, &name, UInt) ; http://msdn.microsoft.com/en-us/library/ms738524(VS.85).aspx
   if !hostent
      {
      err := DllCall("ws2_32\WSAGetLastError")
      ErrorLevel = 1
      return err
      }
   ; string containing protocol types (mainly for debug purposes)
   str := "local to host (pipes, portals)|internetwork: UDP, TCP, etc.|arpanet imp addresses|pup protocols: e.g. BSP|mit CHAOS protocols|XEROX NS protocols or IPX protocols: IPX, SPX, etc.|ISO protocols or OSI is ISO|european computer manufacturers|datakit protocols|CCITT protocols, X.25 etc|IBM SNA|DECnet|Direct data link interface|LAT|NSC Hyperchannel|AppleTalk|NetBios-style addresses|VoiceView|Protocols from Firefox|Unknown - Somebody is using this!|Banyan|Native ATM Services|Internetwork Version 6|Microsoft Wolfpack|IEEE 1284.4 WG AF"
   ptrName := NumGet(hostent+0, 0, "UInt")
   pt := NumGet(hostent+0, 8, "UShort")
   Loop, Parse, str, |
      if (A_Index = pt)
         type := A_LoopField
   len := NumGet(hostent+0, 10, "UShort")
   ptrAddress := NumGet(hostent+0, 12, "UInt")
   ptrIPAddress := NumGet(ptrAddress+0, 0, "UInt")
   strAddress := NumGet(ptrIPAddress+0, 0, "UInt")
   VarSetCapacity(adr, 16, 32)
   DllCall("lstrcpy", UInt, &adr, UInt, DllCall("ws2_32\inet_ntoa", UInt, strAddress))
   VarSetCapacity(adr, -1)
   VarSetCapacity(pname, 260, 32)
   DllCall("lstrcpy", UInt, &pname, UInt, ptrName)
   VarSetCapacity(pname, -1)
   return adr
   }
else
   return name
}
;*********************************
ping_DW2IP(adr)
{
res := NumGet(adr+0, 0, "Uchar") "." NumGet(adr+0, 1, "Uchar") "." NumGet(adr+0, 2, "Uchar") "." NumGet(adr+0, 3, "Uchar")
return res
}
;*********************************
ping(addr, data="AHK ping test", timeout="500")
{
; Sockets initialization http://msdn.microsoft.com/en-us/library/ms741563(VS.85).aspx
VarSetCapacity(WSADATA, 12+257+129, 0)   ; WSADATA structure initialization
err := DllCall("wsock32\WSAStartup", Short, 0x101, UInt, &WSADATA, UInt)
if err > 0
   {
   ErrorLevel = 1
   err = Socket initialization error %err%      ; Failed to initialize sockets
   goto error
   }
address := ping_Host2IP(addr)               ; address conversion to DWORD
err := ping_GetError(address, "ping_Host2IP")         ; error handling
if ErrorLevel
   goto error
err := ping_(address, data, timeout)         ; ping function call
error:
EL := ErrorLevel
DllCall("wsock32\WSACleanup")            ; Sockets cleanup & close
ErrorLevel := EL
return err
}


Last edited by Drugwash on August 30th, 2011, 8:59 am, edited 15 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 27th, 2009, 7:40 pm 
Offline

Joined: May 24th, 2007, 3:45 am
Posts: 1121
If you're targeting this at newbies, it could do with a a little more in the way of instructions, but never the less, it looks quite handy.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 27th, 2009, 9:15 pm 
Offline
User avatar

Joined: September 8th, 2008, 12:26 am
Posts: 1048
Location: Ploieşti, RO
No particular targeting - was just bittered down by some guys around that kept mocking someone asking for help instead of actually providing something to grab on, so I took on building this. It works as is (for me, at least) so anyone having troubles can mod it to their liking/needs.
Thank you for the appreciation.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 29th, 2009, 12:05 pm 
Offline
User avatar

Joined: September 8th, 2008, 12:26 am
Posts: 1048
Location: Ploieşti, RO
v1.1
- Removed debug lines from function code.
- Removed old example from function code
+ Added new separate example code: NetCon Alert

Enjoy! ;)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: May 29th, 2009, 4:46 pm 
Offline
User avatar

Joined: September 8th, 2008, 12:26 am
Posts: 1048
Location: Ploieşti, RO
v1.2
+ Added speech capabilities thanks to DerRaphael's script. It now requires the COM library by Sean (links in first post).


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 5th, 2009, 2:00 pm 
Offline

Joined: January 12th, 2007, 4:30 am
Posts: 531
Location: Norway
Drugwash: Thanks. I might be able to use this in a project of mine where I need to periodically ping my local server as well as a remote location (e.g. www.google.com). Would it be possible to ping both locations almost "simulataneously" even if one location does not respond? I need to create log files and to avoid logging all the successfull pings, I would like to log only the pings where either of the locations is not responding. Any advice?


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 5th, 2009, 8:40 pm 
Offline
User avatar

Joined: September 8th, 2008, 12:26 am
Posts: 1048
Location: Ploieşti, RO
The function uses a single, static structure to hold the ping data. Therefore you need to wait for a reply from previous ping before issuing another ping.
I'm not sure the implementation is perfect (I noticed it doesn't react to forced timeouts - when timeout is set shorter than the reply time) but it does notify of failed pings.

Current logic in the example script is: ping every 5 seconds; if ping fails, send another 2 requests, one per second. If all 3 pings fail, the notification dialog pops up (with or without speech). As such, having it ping two different addresses (almost) simultaneously would require a change of logic. I'm not sure if/when I could do that; if you (or anybody else) feel up to, you're free to make the necessary changes yourself.

The function returns an error string in case of failure; it always begins with the word "Error", so you can simply check for the return value against "Error" and append to log if equal. It also sets ErrorLevel to 1 so either way should be fine.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: June 13th, 2009, 5:51 am 
Offline
User avatar

Joined: September 8th, 2008, 12:26 am
Posts: 1048
Location: Ploieşti, RO
v1.5.1
- Added settings saving through ini file
- Added translation option
- Minor changes and fixes, mostly GUI-related

The file NCA_lang_EN.ini in the lang folder may be used as a template for translating to other languages but do not modify the file itself - rather create a copy, named after your language (i.e. NCA_lang_RU.ini, for Russian). Only translate the strings to the right side of the equal (=) signs. There is a Romanian language file in the same folder; when in doubt take a peek.

The menu is not translatable yet but it's on the to-do list.
If you translate the spoken message, make sure the default SAPI voice matches the language, otherwise it will sound quite funny. Currently I don't know how to programmatically change the SAPI voice for this application only - I could use some help in this regard.

Enjoy! ;)


Report this post
Top
 Profile  
Reply with quote  
 Post subject: Great work!!
PostPosted: June 30th, 2009, 4:10 pm 
Offline

Joined: September 15th, 2006, 10:25 am
Posts: 567
Really great work!!
I have been looking for this and have already incorporated the function in my scripts..

_________________
If i've seen further it is by standing on the shoulders of giants

my site | ~shajul | WYSIWYG BBCode Editor


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 5th, 2009, 2:40 pm 
Offline
User avatar

Joined: September 8th, 2008, 12:26 am
Posts: 1048
Location: Ploieşti, RO
Thank you! If you get any donations, send me some candy. :D


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 6th, 2009, 9:26 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
Drugwash wrote:
Feel free to modify any of them if they don't work in your super-duper OS - it's been built and tested in Win98SE only.
FYI, it works just fine on my Windows 7 RC system. ;)
Drugwash wrote:
It also sets ErrorLevel to 1 so either way should be fine.
What if there's no error? It doesn't seem to set ErrorLevel specifically, but in that case I suppose it'll always be 0 if the last DllCall was a success.

Edit: Supporting multiple ping requests simultaneously would probably require IcmpSendEcho2, which supports asynchronous requests. Unfortunately (for Drugwash, and by extension everyone else), it is not available on Windows 98.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 6th, 2009, 10:41 pm 
Offline
User avatar

Joined: September 8th, 2008, 12:26 am
Posts: 1048
Location: Ploieşti, RO
Lexikos wrote:
FYI, it works just fine on my Windows 7 RC system. ;)
Good to know (and thanks for testing). 8)
Lexikos wrote:
What if there's no error? It doesn't seem to set ErrorLevel specifically, but in that case I suppose it'll always be 0 if the last DllCall was a success.
Hmm, I thought ErrorLevel setting had been covered throughout all subfunctions. :? I even saw a typo right at the top of the script (ErroLevel) - gonna fix it right away. :oops:
Lexikos wrote:
Supporting multiple ping requests simultaneously would probably require IcmpSendEcho2, which supports asynchronous requests. Unfortunately (for Drugwash, and by extension everyone else), it is not available on Windows 98.
IcmpSendEcho uses a unique structure to send/receive data and that data is required for success/failure recognition, that is the main reason why the current function is limited to only one request at a time. I have not yet checked documentation on IcmpSendEcho2 but if it's not available in Win9x I'm afraid I won't be able to patch it into the current script. Anyone else, willing, could do that, however 9x compatibility should be preserved by keeping the current version of the function available for 9x systems.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 6th, 2009, 10:55 pm 
Offline

Joined: March 27th, 2008, 2:14 pm
Posts: 700
Cool!

Do you have a function for getting the information from the ICMP_ECHO_REPLY struct?

e.g. ICMP_ECHO_REPLY(adr, ByRef Address = "", ByRef Status = "" ... )

I wouldn't know how to implement it, or I would have posted it instead.

_________________
Scripts - License


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 6th, 2009, 11:16 pm 
Offline
User avatar

Joined: September 8th, 2008, 12:26 am
Posts: 1048
Location: Ploieşti, RO
The function already checks the Status field returned in the structure to know if it succeeded or failed. Any other info can be retrieved from the structure after the reply.
The following excerpt from the A_Ping() function script is used to retrieve the Status; other info can be retrieved by NumGet() as well.
Code:
szreply = 278                ; ICMP_ECHO_REPLY structure
VarSetCapacity(reply, szreply, 0)
DllCall("icmp\IcmpSendEcho", UInt, hPort, UInt, cAdr, UInt, &data, UInt, StrLen(data), UInt, NULL, UInt, &reply, UInt, szreply, UInt, timeout, UInt)
errcode := NumGet(reply, 4, "UInt")   ; check for status


NumGet(reply, 0, "UInt") ; IP address
NumGet(reply, 8, "UInt") ; RoundTripTime
etc.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 6th, 2009, 11:30 pm 
Offline

Joined: March 27th, 2008, 2:14 pm
Posts: 700
Oh I see. Thanks, I was making it too complicated for myself. :P

Btw, I see a possible issue:
Code:
errcode := errcode <> 0 ? errcode : errcode+11000    ;line 40
I noticed that the else of the ternary will always be 11000, since the only way to get there is for errcode to be 0. Is this intentional? (e.g. for readability)

Thanks. :)

_________________
Scripts - License


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 43 posts ]  Go to page 1, 2, 3  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: Bing [Bot], Scratch and 11 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group