Leaderboard
Popular Content
Showing content with the highest reputation on 05/21/2023 in all areas
-
Keypress simulation with WinAPI functions directly
argumentum and 2 others reacted to TheXman for a topic
The example below works in 32 bit and 64 bit environments. INPUT is a struct that contains a union. Since the original post only asked about keyboard input, I did not include what the MOUSEINPUT and HARDWAREINPUT unions would look like. There are alignment issues that have to be taken into account when running 32 bit or 64 bit. The example shows one way of handling it. #AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d ;~ #AutoIt3Wrapper_UseX64=N #include <Constants.au3> #include <Array.au3> #include <WinAPIDiag.au3> Enum Step *2 _ $KEYEVENTF_EXTENDEDKEY = 1, _ $KEYEVENTF_KEYUP, _ $KEYEVENTF_UNICODE, _ $KEYEVENTF_SCANCODE Const $INPUT_KEYBOARD = 1 Const $VK_SHIFT = 0x10 Const $VK_A = 0x41 Const $tagKeyInput = _ "dword type;" & _ (@AutoItX64 ? "byte alignment_pad[4];" : "") & _ "struct;" & _ " word wVk;" & _ " word wScan;" & _ " dword dwFlags;" & _ " dword time;" & _ " ulong_ptr dwExtraInfo;" & _ " byte reserved[8];" & _ "endstruct;" example() Func example() #cs ========================================================= Using the SendInput win32 API, this example sends "AbC" to the last active notepad instance (if it exists). Note: "A" is sent by using virtual key code and "C" is sent using a scan code. It was done just to show the 2 different ways of sending keyboard input. #ce ========================================================= Local $tKeyInput, _ $tInputArray Local $aResult Local $iNumberOfInputs = 8 ;Create a struct to get size $tKeyInput = DllStructCreate($tagKeyInput) ;Create an inputs array buffer $tInputArray = DllStructCreate(StringFormat("byte bytes[%i];", DllStructGetSize($tKeyInput) * $iNumberOfInputs)) ;Load input array[0] $tKeyInput = DllStructCreate($tagKeyInput, DllStructGetPtr($tInputArray) + (0 * DllStructGetSize($tKeyInput))) $tKeyInput.type = $INPUT_KEYBOARD $tKeyInput.wVk = $VK_SHIFT ;Load input array[1] $tKeyInput = DllStructCreate($tagKeyInput, DllStructGetPtr($tInputArray) + (1 * DllStructGetSize($tKeyInput))) $tKeyInput.type = $INPUT_KEYBOARD $tKeyInput.wVk = $VK_A ;Load input array[2] $tKeyInput = DllStructCreate($tagKeyInput, DllStructGetPtr($tInputArray) + (2 * DllStructGetSize($tKeyInput))) $tKeyInput.type = $INPUT_KEYBOARD $tKeyInput.wvk = $VK_A $tKeyInput.dwFlags = $KEYEVENTF_KEYUP ;Load input array[3] $tKeyInput = DllStructCreate($tagKeyInput, DllStructGetPtr($tInputArray) + (3 * DllStructGetSize($tKeyInput))) $tKeyInput.type = $INPUT_KEYBOARD $tKeyInput.wVk = $VK_SHIFT $tKeyInput.dwFlags = $KEYEVENTF_KEYUP ;Load input array[4] $tKeyInput = DllStructCreate($tagKeyInput, DllStructGetPtr($tInputArray) + (4 * DllStructGetSize($tKeyInput))) $tKeyInput.type = $INPUT_KEYBOARD $tKeyInput.wScan = AscW("b") $tKeyInput.dwFlags = $KEYEVENTF_UNICODE ;Load input array[5] $tKeyInput = DllStructCreate($tagKeyInput, DllStructGetPtr($tInputArray) + (5 * DllStructGetSize($tKeyInput))) $tKeyInput.type = $INPUT_KEYBOARD $tKeyInput.wScan = AscW("b") $tKeyInput.dwFlags = $KEYEVENTF_UNICODE + $KEYEVENTF_KEYUP ;Load input array[6] $tKeyInput = DllStructCreate($tagKeyInput, DllStructGetPtr($tInputArray) + (6 * DllStructGetSize($tKeyInput))) $tKeyInput.type = $INPUT_KEYBOARD $tKeyInput.wScan = AscW("C") $tKeyInput.dwFlags = $KEYEVENTF_UNICODE ;Load input array[7] $tKeyInput = DllStructCreate($tagKeyInput, DllStructGetPtr($tInputArray) + (7 * DllStructGetSize($tKeyInput))) $tKeyInput.type = $INPUT_KEYBOARD $tKeyInput.wScan = AscW("C") $tKeyInput.dwFlags = $KEYEVENTF_UNICODE + $KEYEVENTF_KEYUP ;Activate notepad window If Not WinActivate("[CLASS:Notepad]") Then Exit MsgBox($MB_ICONERROR, "WinActivate Error", "Notepad window not found.") ;Send input $aResult = DllCall('user32.dll', 'uint', 'SendInput', _ 'uint' , $iNumberOfInputs, _ 'struct*', $tInputArray, _ 'int' , DllStructGetSize($tKeyInput)) If $aResult[0] = 0 Then MsgBox(0, "GetLastError", _WinAPI_GetLastErrorMessage()) EndFunc3 points -
1 point
-
Open the Helpfile that comes with the version and you will find that you have the syntax all wrong. It should be: Opt("OnExitFunc", "Encerrar")1 point
-
Hmm, totaly overlooked that. Thanks @TheXman and @Jos for helping1 point
-
Why not use the Number() function for such a simple transformation? ConsoleWrite(Number("000.96*A") & @CRLF) ConsoleWrite(Number("001.96*A") & @CRLF) ConsoleWrite(Number("005*A") & @CRLF) Outputs: 0.96 1.96 51 point
-
@TheXman Great example, thanks a lot! It would be great if you could post examples on these too! Maybe directly to "Examples"?1 point
-
OnAutoItExitRegister() in version 3.2.12.1 or earlier
Belini reacted to pixelsearch for a topic
@Belini AutoIt 3.2.10.0, help file dated Dec 25, 2007 Func OnAutoItExit ()...EndFunc Defines a user-defined function that will be called when the script exit. Func OnAutoItExit ( ) ... EndFunc Parameters None. Remarks Inside the function, @ExitCode can be used to retrieve the code set by the exit statement. The mode of exit can be retrieved with @ExitMethod. 0 Natural closing. 1 close by Exit function. 2 close by clicking on exit of the systray. 3 close by user logoff. 4 close by Windows shutdown. Related Func OnAutoItStart (), OnExitFunc (Option) Example Opt("OnExitFunc", "endscript") MsgBox(0,"","first statement") Func endscript() MsgBox(0,"","after last statement " & @EXITMETHOD) EndFunc Edit: same syntax in Autoit 3.2.12.0 (May 16, 2008)1 point -
For what it's worth, I tend to agree with @AndyG. Identifying and fixing the root cause of an issue is almost always better than time spent patching or working around the issue. If you fix (or at least mitigate) the issue, then you hopefully don't have to waste time dealing with it again and again or risk it causing additional problems. I have found WMI much more reliable in getting process info than some of the WinAPI UDF's that use Win32 API's. I haven't dug into why, but when using the WinAPI UDF's, WMI returns some information that the WinAPI UDF's do not. Here's a quick script that displays selected process info (including CPU time) for all running processes: #AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d #include <Constants.au3> #include <WinAPILocale.au3> #include <Array.au3> list_process_info() ;========================================================================== Func list_process_info() ;========================================================================== Enum $PROCESS_PID, $PROCESS_NAME, $PROCESS_EXE_PATH, $PROCESS_CPU_TIME, $PROCESS_COLS Local $aProcesses[0][$PROCESS_COLS] Local $oComError = ObjEvent("AutoIt.Error", "com_error_handler"), _ $oProcesses = "" Local $sTotalCpuTime = "" With ObjGet("winmgmts:") ;Get list of currently running processes $oProcesses = .ExecQuery("SELECT Handle, Name, ExecutablePath, KernelModeTime, UserModeTime FROM Win32_Process") ;If no processes found, then return with message If $oProcesses.Count = 0 Then Return MsgBox($MB_ICONWARNING, "Warning", "No processes found.") If @error Then Return MsgBox($MB_ICONERROR, "WMI ExecQuery Error", $oComError.Description) ;For each process For $oProcess in $oProcesses With $oProcess ;Calculate total cpu time duration and convert to hh:mm:ss $sTotalCpuTime = _WinAPI_GetDurationFormat($LOCALE_USER_DEFAULT, .KernelModeTime + .UserModeTime, "hh:mm:ss") ;Add process info to the array _ArrayAdd($aProcesses, .Handle & "|" & .Name & "|" & .ExecutablePath & "|" & $sTotalCpuTime) EndWith Next EndWith ;Display process info _ArraySort($aProcesses, 1, 0, 0, $PROCESS_CPU_TIME) ;Sort by cpu time in descending order _ArrayDisplay($aProcesses, "List of processes", "", 0, Default, "PID|NAME|PATH|CPU TIME") EndFunc ;========================================================================== Func com_error_handler($oError) ;========================================================================== #forceref $oError Return ; Return so @error can be trapped by the calling function EndFunc Resulting array:1 point
-
Keypress simulation with WinAPI functions directly
TheXman reacted to pixelsearch for a topic
@TheXman great example in your script above, it explains a lot, thanks I would like to discuss the part where "you're sending 'C' using a scan code" with these lines : $tKeyInput.wScan = AscW("C") $tKeyInput.dwFlags = $KEYEVENTF_UNICODE We could also use the scan code for another purpose, as read on msdn Keyboard Input Overview (scan codes paragraph) which stipulates : The scan code is the value that the system generates when the user presses a key. It is a value that identifies the key pressed regardless of the active keyboard layout, as opposed to the character represented by the key. For example, if we replace array[6] and array[7] in your script with these ones... ;Load input array[6] $tKeyInput = DllStructCreate($tagKeyInput, DllStructGetPtr($tInputArray) + (6 * DllStructGetSize($tKeyInput))) $tKeyInput.type = $INPUT_KEYBOARD $tKeyInput.wScan = 0x10 ; key location #17 (q on Qwerty kbd, a on Azerty kbd etc...) got a Scan 1 Make = 0x10 $tKeyInput.dwFlags = $KEYEVENTF_SCANCODE ;Load input array[7] $tKeyInput = DllStructCreate($tagKeyInput, DllStructGetPtr($tInputArray) + (7 * DllStructGetSize($tKeyInput))) $tKeyInput.type = $INPUT_KEYBOARD $tKeyInput.wScan = 0x10 ; key location #17 (reuse Scan 1 Make, no need of deprecated Scan 1 Break) $tKeyInput.dwFlags = $KEYEVENTF_SCANCODE + $KEYEVENTF_KEYUP ...then a letter (not depending on the keyboard layout) will be displayed in NotePad. It may be a 'q' (if qwerty keyboard) or an 'a' (my azerty keyboard) or whatever. Key location #17 can be found on the keyboard picture at the msdn link above, with its corresponding "Scan 1 Make". We just need to indicate the correct flag $KEYEVENTF_SCANCODE in the structure. Maybe this could answer the question asked in this topic ?1 point -
He also provide Bans.1 point
-
Txt split to ini file
Zedna reacted to pixelsearch for a topic
@ioa747 I tried to improve the processing time of the script, in case there are plenty of users (100, 500 you name it) and a big datalar.txt file, like the one provided by mucitbey last year, which had 6.535 lines and generated 75 ini files (from 30/05/2022 to 12/08/2022 included) In my precedent script (and probably yours) I found the 2 instructions that slowed the damn thing : * IniWrite is slow, when there are plenty of sections, probably because the file is opened and closed for each Iniwrite, idk. * _ArraySearch is slow too (e.g GetUserIndex) Retrieving constantly a user name (while providing his ID) is slow when we have to loop through all rows of an array, again and again. _ArrayBinarySearch would certainly retrieve the name faster So, this is what I did to get super quick results, even on thousands of lines in Datalar.txt * No more IniWrite, but FileWriteLine, as you will notice in the script below. * Scripting.Dictionary object (instead of _ArraySearch) which retrieves a username at the speed of light. Also, Scripting.Dictionary can be used for other interesting purposes (like $oData in the script) Here are some notes concerning the 2 major arrays and 2 dictionaries objects found in the script below : $aUser[ ][4] ============ $aUser[ ][0] = User ID (unique) $aUser[ ][1] = User Name (unique, as Name is also, unfortunately, a unique section in daily .ini files) $aUser[ ][2] = Time1 (if empty, then user was absent this day, this will be useful to add absents in LV) $aUser[ ][3] = Time2 (if filled, then Time1 is already filled, e.g user ID found twice in $adata for same day) $oUser() ======== Key = User ID (unique) . Same number of Keys as $aUser number of rows Item = Index of this User in $aUser, it will allow an immediate search in $aUser, instead of slow _ArraySearch $aData[ ][5] ============ $aData[ ][0] = unused $aData[ ][1] = User ID (not unique, usually same ID found twice each day) $aData[ ][2] = unused $aData[ ][3] = Date (same date on contiguous rows, processed day by day) $aData[ ][4] = Time1 OR Time2 (this column is already sorted for same day) $oData() ======== Key = User ID (unique). Used when day changes, to add at once in LV all daily workers, sorted by day & time. Item = Index of this User in $aUser, it will allow an immediate search in $aUser, instead of slow _ArraySearch #include <File.au3> #include <MsgBoxConstants.au3> #include <SendMessage.au3> Opt("MustDeclareVars", 1) Global $g_iLinesUser, $g_idListview Main() Func Main() Local $aUser, $aUserBackup, $oUser, $aData, $oData Local $WM_SETREDRAW = 0x000B, $LVM_GETITEMCOUNT = 0X1004, $GUI_EVENT_CLOSE = -3 _FileReadToArray(@ScriptDir & "\" & "Users.txt", $aUser, $FRTA_NOCOUNT, "=") ; 2D array If @error Then Exit MsgBox($MB_TOPMOST, "_FileReadToArray error = " & @error, "Users.txt") $g_iLinesUser = UBound($aUser) ReDim $aUser[$g_iLinesUser][4] ; add 2 empty columns at the right (to update time1 and time2 per user for 1 working day) $aUserBackup = $aUser ; keep a copy with last 2 empty columns for all users. Reuse this backup when date changes. $oUser = ObjCreate("Scripting.Dictionary") Fill_oUser($aUser, $oUser) _FileReadToArray(@ScriptDir & "\" & "Datalar.txt", $aData, $FRTA_NOCOUNT) ; 1D array If @error Then Exit MsgBox($MB_TOPMOST, "_FileReadToArray error = " & @error, "Datalar.txt") $oData = ObjCreate("Scripting.Dictionary") Local $hGUI = GUICreate("", 470, 500, -1, -1) ; title later, to include number of rows in it $g_idListview = GUICtrlCreateListView("CART ID | DATE|TIME-1 |TIME-2 |NAME AND SURNAME ", 10, 10, 450, 480) Local $hListview = GUICtrlGetHandle($g_idListview) _SendMessage($hListview, $WM_SETREDRAW, False) ; _GUICtrlListView_BeginUpdate . False = don't redraw after a change Local $sDate = "", $aTemp, $iEmptyRows, $UserIndex For $li = 0 To UBound($aData) - 1 $aTemp = StringSplit(StringStripWS($aData[$li], 1+2), ", ", $STR_NOCOUNT) ; strip leading (1) and trailing (2) eventual white space If @error Then ContinueLoop ; eliminate accidental blank lines. Help file StringSplit: "@error = 1 when no delimiters were found" If StringLen($aTemp[3]) < 10 Then $aTemp[3] = "0" & $aTemp[3] ; days "1" to "9" will become "01" to "09" everywhere in the script. If $sDate <> $aTemp[3] Then ; $sDate is the old date, $aTemp[3] is the new date. If $sDate Then ; always False when $li = 0 (first data line processed) ; Update LV : add all working users for 1 day, then add all absents for 1 day . Prepare ini file for 1 day (all users) DayChange($sDate, $aUser, $oData) ; Reuse $aUserBackup (before processing a new date) $aUser = $aUserBackup ; reuse backup, e.g. blank columns 2 & 3 in $aUser, for all users, when date changes. $g_iLinesUser = UBound($aUser) ; as it may have increased in Func GetUserIndex (if an eventual ID wasn't found in $aUser) ; If undefined ID's had been added to $oUser, then re-generate $oUser (this shouldn't happen, according to mucitbey) If $oUser.Count <> $g_iLinesUser Then $oUser.RemoveAll() Fill_oUser($aUser, $oUser) EndIf ; remove all keys in $oData (before processing a new date) $oData.RemoveAll() ; add 1 empty line between each day processed in LV (sort of vertical separator) GUICtrlCreateListViewItem("", $g_idListview) $iEmptyRows += 1 ; don't count this line in the total number of lines in LV (displayed later in GUI title) EndIf $sDate = $aTemp[3] ; old date = new date EndIf $UserIndex = GetUserIndex($aTemp[1], $aUser, $oUser) ; user index (row) in $aUser If Not $oData.Exists($aTemp[1]) Then ; 1st entry for this ID (will update column Time1 in $aUser) $aUser[$UserIndex][2] = $aTemp[4] ; time1 $oData.Add($aTemp[1], $UserIndex) ; key = User ID, item = User index in $aUser Else ; 2nd entry for this ID (it will update column Time2 in $aUser) $aUser[$UserIndex][3] = $aTemp[4] ; time2 EndIf Next If $sDate Then DayChange($sDate, $aUser, $oData) _SendMessage($hListview, $WM_SETREDRAW, True) ; _GUICtrlListView_EndUpdate . True = redraw after a change Local $iNbRows = GUICtrlSendMsg($g_idListview, $LVM_GETITEMCOUNT, 0, 0) WinSetTitle($hGUI, "", "_ank_ File Splitting (" & ($iNbRows - $iEmptyRows) & " rows)") GUISetState(@SW_SHOW, $hGUI) Do Until GUIGetMsg() = $GUI_EVENT_CLOSE ; Cleaning (not really necessary but ok) $oUser = 0 ; force Object deletion (AutoIt help file, topic "Obj/COM Reference") $oData = 0 ; ditto GUIDelete($hGUI) EndFunc ;==>Main ;================================================ Func GetUserIndex($ID, ByRef $aUser, ByRef $oUser) If $oUser.Exists($ID) Then Local $iIndex = $oUser.Item($ID) ; $iIndex in $aUser of regular ID Else ; this should never happen (mucitbey) but better prevent it, just in case... Local $iIndex = $g_iLinesUser ; $iIndex in $aUser of Undefined ID ; add the Undefined ID in $aUser $g_iLinesUser += 1 ReDim $aUser[$g_iLinesUser][4] ; not really fast but as it should never happen... $aUser[$iIndex][0] = $ID $aUser[$iIndex][1] = "Undefined ID " & $ID ; this creates a unique "name" (+++) ; add the Undefined ID in $oUser $oUser.Add($ID, $iIndex) ; key = User Undefined ID, item = User index in $aUser EndIf Return $iIndex ; 0+ EndFunc ;==>GetUserIndex ;================================================ Func DayChange($sDate, ByRef $aUser, ByRef $oData) ; Update LV : add all working users for 1 day ; Color eventually background of LV rows Local $aPresent = $oData.Keys(), $iIndex For $i = 0 To Ubound($aPresent) - 1 $iIndex = $oData.Item($aPresent[$i]) ; $iIndex in $aUser of an ID GUICtrlCreateListViewItem($aUser[$iIndex][0] &"|"& $sDate &"|"& _ $aUser[$iIndex][2] &"|"& $aUser[$iIndex][3] &"|"& $aUser[$iIndex][1], $g_idListview) ; color eventually background of this LV row If StringLeft($aUser[$iIndex][1], 12) = "Undefined ID" Then GUICtrlSetBkColor(-1, 0xFF0000) ; red ElseIf ($aUser[$iIndex][2] > "08:10:00" And $aUser[$iIndex][2] < "17:00:00") _ OR ($aUser[$iIndex][3] > "08:10:00" And $aUser[$iIndex][3] < "17:00:00") Then GUICtrlSetBkColor(-1, 0xC0FFFF) ; light blue EndIf Next ; Prepare .ini file for 1 day (all users) ; Update LV : add all absents for 1 day Local $sIniFile = @ScriptDir & "\" & $sDate & ".ini" Local $hIni = FileOpen($sIniFile, $FO_OVERWRITE + $FO_UNICODE) ; more reliable than $FO_ANSI If $hIni = -1 Then Exit MsgBox($MB_TOPMOST, "FileOpen error", $sIniFile) For $i = 0 To $g_iLinesUser - 1 FileWriteLine($hIni, _ "[" & $aUser[$i][1] & "]" & @crlf & _ ; ini section = [User Name] "Value01=" & $aUser[$i][0] & @crlf & _ ; User ID "Value02=" & $sDate & @crlf & _ ; Date "Value03=" & $aUser[$i][2] & @crlf & _ ; Time1 "Value04=" & $aUser[$i][3] & @crlf) ; Time2 If Not $aUser[$i][2] Then ; user was absent that day (as he got no time1) ; add 1 line in ListView for the absent user (with blank time1 & time2) GUICtrlCreateListViewItem($aUser[$i][0] &"|"& $sDate &"|"& "" &"|"& "" &"|"& $aUser[$i][1], $g_idListview) EndIf Next FileClose($hIni) EndFunc ;==>DayChange ;================================================ Func Fill_oUser(ByRef $aUser, ByRef $oUser) For $i = 0 To $g_iLinesUser - 1 $oUser.Add($aUser[$i][0], $i) ; key = User ID, item = User index in $aUser (immediate retrieve of a user in $aUser, instead of slow _ArraySearch) Next EndFunc ;==>Fill_oUser My only regret ? I wish I used the Scripting.Dictionary Object a long time ago, it's damn quick and easy to use1 point -
Hi guys, there is no UDF wrappers for GetAdaptersAddresses API... till now Here you are: ; #FUNCTION# ==================================================================================================================== ; Name...........: _WinAPI_GetAdaptersAddresses ; Description ...: Retrieves the addresses associated with the adapters on the local computer. ; Syntax.........: _WinAPI_GetAdaptersAddresses($iFamily = 2, $iShowAll = 1, $iShowTunnel = 0) ; Parameters ....: $iFamily - IP type. ; |0 - Both ; |2 - IPv4 (default) ; |23 - IPv6 ; $iShowAll - Presentation mode ; |0 - Short: only Unicast address(es) and Friendly Name columns are returned ; |1 - Long (default): all columns are returned but Anycast and Multicast columns return only the first address (it is not an array) ; |2 - Complete: all columns are returned, Anycast and Multicast columns return an array with the complete list of addresses ; $iShowTunnel - Shows or not tunnel interfaces ; |0 - Don't show (default) ; |1 - Show ; Return values .: On success it returns a bidimensional array: on rows there is the adapter list, these are the columns ; |0 - Preferred unicast address(es), it returns an array of addresses only if $iFamily == 0 ; |1 - Friendly name ; |2 - Anycast addresses: if $iShowAll == 1 it returns the first anycast address of the list, ; if $iShowAll == 2 it returns an array with the complete list of anycast addresses ; |3 - Multicast addresses: if $iShowAll == 1 it returns the first multicast address of the list, ; if $iShowAll == 2 it returns an array with the complete list of multicast addresses ; |4 - DNS Server 1 address ; |5 - DNS Server 2 address ; |6 - Adapter Name ; |7 - Description ; |8 - MAC address ; |9 - Interface Type ; for example $array[2][8] represents the MAC address of the third adapter ; ; On failure it returns 0 and sets @error to non zero (these values are useful only for debugging reasons): ; |1 - incorrect parameters ; |2 - DllOpen error ; |3 - DllCall error ; |4 - _WinAPI_GetString error ; |5 - Query for IPv6 addresses and IPv6 is not installed on the OS ; Author ........: j0kky ; Modified ......: 1.1.3 13/02/15 ; Remarks .......: This function is fully compatible with all OS from Windows XP onwards, there can be some problem using this function ; with $iFamily == 23 if the OS is prior to Windows XP SP1 ; Link ..........: https://msdn.microsoft.com/en-us/library/windows/desktop/aa365915(v=vs.85).aspx ; =============================================================================================================================== #include <WinAPIMisc.au3> Func _WinAPI_GetAdaptersAddresses($iFamily = 2, $iShowAll = 1, $iShowTunnel = 0) If Not ($iFamily == 0 Or $iFamily == 2 Or $iFamily == 23) Or _ Not ($iShowAll == 0 Or $iShowAll == 1 Or $iShowAll == 2) Or _ Not ($iShowTunnel == 0 Or $iShowTunnel == 1) Then Return SetError(1, 0, 0) Local $aRet If $iFamily == 23 Then $aRet = DllCall("Ws2_32.dll", "int", "WSCEnumProtocols", "ptr", Null, "ptr", Null, "dword*", Null, "ptr", Null) Local $tlpProtocolBuffer = DllStructCreate("byte[" & $aRet[3] & "]") Local $plpProtocolBuffer = DllStructGetPtr($tlpProtocolBuffer) $aRet = DllCall("Ws2_32.dll", "int", "WSCEnumProtocols", "ptr", Null, "ptr", $plpProtocolBuffer, "dword*", $aRet[3], "ptr", Null) Local $tagWSAPROTOCOL_INFOW = "dword dwServiceFlags1; dword dwServiceFlags2; dword dwServiceFlags3; dword dwServiceFlags4; dword dwServiceFlags5; byte ProviderId[16]; " & _ "dword dwCatalogEntryId; " & _ "STRUCT; int ChainLen; dword ChainEntries[7]; ENDSTRUCT;" & _ ;ProtocolChain "int iVersion; int iAddressFamily; int iMaxSockAddr; int iMinSockAddr; int iSocketType; int iProtocol; int iProtocolMaxOffset; int iNetworkByteOrder; " & _ "int iSecurityScheme; dword dwMessageSize; dword dwProviderReserved; wchar szProtocol[256]" Local $tWSAPROTOCOL_INFOW, $size For $i = 0 To $aRet[0] - 1 If $i == 0 Then $tWSAPROTOCOL_INFOW = DllStructCreate($tagWSAPROTOCOL_INFOW, $plpProtocolBuffer) Else $tWSAPROTOCOL_INFOW = DllStructCreate($tagWSAPROTOCOL_INFOW, $plpProtocolBuffer + $size) EndIf If DllStructGetData($tWSAPROTOCOL_INFOW, "iAddressFamily") == 23 Then ExitLoop If $i == ($aRet[0] - 1) Then Return SetError(5, 0, 0) ;if IPv6 is not installed on the system $size += DllStructGetSize($tWSAPROTOCOL_INFOW) Next EndIf $hIphlpapi = DllOpen("Iphlpapi.dll") If @error Then Return SetError(2, 0, 0) $aRet = DllCall($hIphlpapi, "ULONG", "GetAdaptersAddresses", "ULONG", $iFamily, "ULONG", 0, "ptr", Null, "ptr", Null, "dword*", 0) If @error Then DllClose($hIphlpapi) Return SetError(3, 0, 0) EndIf Local $tbuffer_AdapterAddresses = DllStructCreate("byte[" & $aRet[5] & "]") Local $pbuffer_AdapterAddresses = DllStructGetPtr($tbuffer_AdapterAddresses) DllCall($hIphlpapi, "ULONG", "GetAdaptersAddresses", "ULONG", $iFamily, "ULONG", 0, "ptr", Null, "ptr", $pbuffer_AdapterAddresses, "dword*", $aRet[5]) If @error Then DllClose($hIphlpapi) Return SetError(3, 0, 0) EndIf DllClose($hIphlpapi) Local Const $tagIP_ADAPTER_ADDRESSES = "ulong Length; dword IfIndex; ptr Next; ptr AdapterName; ptr FirstUnicastAddress; ptr FirstAnycastAddress; " & _ "ptr FirstMulticastAddress; ptr FirstDnsServerAddress; ptr DnsSuffix; ptr Description; ptr FriendlyName; byte PhysicalAddress[8]; dword PhysicalAddressLength; " & _ "dword Flags; dword Mtu; dword IfType; int OperStatus" ;valid on Windows XP #cs "dword Ipv6IfIndex; dword ZoneIndices[16]; ptr FirstPrefix; " & _ ;added on WinXP SP1 "uint64 TransmitLinkSpeed; uint64 ReceiveLinkSpeed; ptr FirstWinsServerAddress; ptr FirstGatewayAddress; ulong Ipv4Metric; ulong Ipv6Metric; uint64 Luid; " & _ "STRUCT; ptr Dhcpv4ServerlpSockaddr; int Dhcpv4ServeriSockaddrLength; ENDSTRUCT; " & _ ;Dhcpv4Server "uint CompartmentId; byte NetworkGuid[16]; int ConnectionType; int TunnelType; " & _ "STRUCT; ptr Dhcpv6ServerlpSockaddr; int Dhcpv6ServeriSockaddrLength; ENDSTRUCT; " & _ ;Dhcpv6Server "byte Dhcpv6ClientDuid[130]; ulong Dhcpv6ClientDuidLength; ulong Dhcpv6Iaid; " & _ ;added on WinVista "ptr FirstDnsSuffix" ;added on WinVista SP1 #ce Local Const $tagIP_ADAPTER_UNICAST_ADDRESS = "ulong Length; dword Flags; ptr Next; " & _ "STRUCT; ptr AddresslpSockaddr; int AddressiSockaddrLength; ENDSTRUCT; " & _ ;Address "int PrefixOrigin; int SuffixOrigin; int DadState; ulong ValidLifetime; ulong PreferredLifetime; ulong LeaseLifetime" #cs "byte OnLinkPrefixLength" ;added on WinVista #ce Local $tIP_ADAPTER_ADDRESSES = DllStructCreate($tagIP_ADAPTER_ADDRESSES, $pbuffer_AdapterAddresses) Local $nAdapter = 0, $pUnicastAddress, $tIP_ADAPTER_UNICAST_ADDRESS, $plpSockaddr, $iSockaddrLength, $tbuffer_lpszAddressString, $pbuffer_lpszAddressString Local Const $IfOperStatusUp = 1, $IF_TYPE_SOFTWARE_LOOPBACK = 24, $IF_TYPE_TUNNEL = 131, $IpDadStatePreferred = 4, $pNull = Ptr(0) If $iShowAll Then Local $nColumns = 10 Local Const $tagIP_ADAPTER_ANYCAST_ADDRESS = "ulong Length; dword Flags; ptr Next; " & _ "STRUCT; ptr AddresslpSockaddr; int AddressiSockaddrLength; ENDSTRUCT" ;Address Local Const $tagIP_ADAPTER_MULTICAST_ADDRESS = $tagIP_ADAPTER_ANYCAST_ADDRESS Local Const $tagIP_ADAPTER_DNS_SERVER_ADDRESS = "ulong Length; dword Reserved; ptr Next; " & _ "STRUCT; ptr AddresslpSockaddr; int AddressiSockaddrLength; ENDSTRUCT" ;Address Local $pAnycastAddress, $tIP_ADAPTER_ANYCAST_ADDRESS, $pMulticastAddress, $tIP_ADAPTER_MULTICAST_ADDRESS, $pDnsServerAddress, $tADAPTER_DNS_SERVER_ADDRESS, $sMAC Local Const $IF_TYPE_ETHERNET_CSMACD = 6, $IF_TYPE_IEEE80211 = 71, $IF_TYPE_IEEE1394 = 144 Else Local $nColumns = 2 EndIf Local $aResult[$nAdapter][$nColumns] $hWs2_32 = DllOpen("Ws2_32.dll") If @error Then Return SetError(2, 0, 0) TCPStartup() Do If DllStructGetData($tIP_ADAPTER_ADDRESSES, "OperStatus") == $IfOperStatusUp And _ Not (DllStructGetData($tIP_ADAPTER_ADDRESSES, "IfType") == $IF_TYPE_SOFTWARE_LOOPBACK) And _ (Not (DllStructGetData($tIP_ADAPTER_ADDRESSES, "IfType") == $IF_TYPE_TUNNEL) Or $iShowTunnel) Then ;if it's connected and it is not a loopback and it is a tunnel interface (only if $iShowTunnel == 1) $nAdapter += 1 ReDim $aResult[$nAdapter][$nColumns] ;Unicast address(es) $pUnicastAddress = DllStructGetData($tIP_ADAPTER_ADDRESSES, "FirstUnicastAddress") $tIP_ADAPTER_UNICAST_ADDRESS = DllStructCreate($tagIP_ADAPTER_UNICAST_ADDRESS, $pUnicastAddress) If Not $iFamily Then Local $aAddresses[0], $iCounter = -1 Do ;write the PREFERRED address for this adapter, it writes both IPV4 and IPV6 preferred addresses in an array if $iFamily == 0 If DllStructGetData($tIP_ADAPTER_UNICAST_ADDRESS, "DadState") == $IpDadStatePreferred Then $plpSockaddr = DllStructGetData($tIP_ADAPTER_UNICAST_ADDRESS, "AddresslpSockaddr") $iSockaddrLength = DllStructGetData($tIP_ADAPTER_UNICAST_ADDRESS, "AddressiSockaddrLength") $aRet = DllCall($hWs2_32, "int", "WSAAddressToString", "ptr", $plpSockaddr, "int", $iSockaddrLength, "ptr", Null, "byte*", Null, "dword*", 0) If @error Then DllClose($hWs2_32) Return SetError(3, 0, 0) EndIf $tbuffer_lpszAddressString = DllStructCreate("wchar[" & $aRet[5] & "]") $pbuffer_lpszAddressString = DllStructGetPtr($tbuffer_lpszAddressString) $aRet = DllCall($hWs2_32, "int", "WSAAddressToStringW", "ptr", $plpSockaddr, "int", $iSockaddrLength, "ptr", Null, "ptr", $pbuffer_lpszAddressString, "dword*", $aRet[5]) If @error Then DllClose($hWs2_32) Return SetError(3, 0, 0) EndIf If $iFamily Then $aResult[$nAdapter - 1][0] = _WinAPI_GetString($pbuffer_lpszAddressString) If @error And @error <> 10 Then DllClose($hWs2_32) Return SetError(4, 0, 0) EndIf ExitLoop Else $iCounter = UBound($aAddresses) ReDim $aAddresses[$iCounter + 1] $aAddresses[$iCounter] = _WinAPI_GetString($pbuffer_lpszAddressString) If @error And @error <> 10 Then DllClose($hWs2_32) Return SetError(4, 0, 0) EndIf EndIf EndIf $pUnicastAddress = DllStructGetData($tIP_ADAPTER_UNICAST_ADDRESS, "Next") If Not ($pUnicastAddress == $pNull) Then $tIP_ADAPTER_UNICAST_ADDRESS = DllStructCreate($tagIP_ADAPTER_UNICAST_ADDRESS, $pUnicastAddress) EndIf Until $pUnicastAddress == $pNull If Not $iFamily Then If $iCounter < 0 Then ReDim $aAddresses[1] ;if there is no preferred unicast addresses for this adapter, I don't know if it can happens $aResult[$nAdapter - 1][0] = $aAddresses EndIf ;FriendlyName $aResult[$nAdapter - 1][1] = _WinAPI_GetString(DllStructGetData($tIP_ADAPTER_ADDRESSES, "FriendlyName")) If @error And @error <> 10 Then DllClose($hWs2_32) Return SetError(4, 0, 0) EndIf If $iShowAll Then ;Anycast address, it shows only the first one if $iShowAll == 1 $pAnycastAddress = DllStructGetData($tIP_ADAPTER_ADDRESSES, "FirstAnycastAddress") If Not ($pAnycastAddress == $pNull) Then $tIP_ADAPTER_ANYCAST_ADDRESS = DllStructCreate($tagIP_ADAPTER_ANYCAST_ADDRESS, $pAnycastAddress) If $iShowAll == 2 Then Local $aAddresses[0] While $pMulticastAddress <> $pNull $plpSockaddr = DllStructGetData($tIP_ADAPTER_ANYCAST_ADDRESS, "AddresslpSockaddr") $iSockaddrLength = DllStructGetData($tIP_ADAPTER_ANYCAST_ADDRESS, "AddressiSockaddrLength") $aRet = DllCall($hWs2_32, "int", "WSAAddressToString", "ptr", $plpSockaddr, "int", $iSockaddrLength, "ptr", Null, "byte*", Null, "dword*", 0) If @error Then DllClose($hWs2_32) Return SetError(3, 0, 0) EndIf $tbuffer_lpszAddressString = DllStructCreate("wchar[" & $aRet[5] & "]") $pbuffer_lpszAddressString = DllStructGetPtr($tbuffer_lpszAddressString) $aRet = DllCall($hWs2_32, "int", "WSAAddressToStringW", "ptr", $plpSockaddr, "int", $iSockaddrLength, "ptr", Null, "ptr", $pbuffer_lpszAddressString, "dword*", $aRet[5]) If @error Then DllClose($hWs2_32) Return SetError(3, 0, 0) EndIf If $iShowAll == 2 Then $iCounter = UBound($aAddresses) ReDim $aAddresses[$iCounter + 1] $aAddresses[$iCounter] = _WinAPI_GetString($pbuffer_lpszAddressString) If @error And @error <> 10 Then DllClose($hWs2_32) Return SetError(4, 0, 0) EndIf Else $aResult[$nAdapter - 1][2] = _WinAPI_GetString($pbuffer_lpszAddressString) If @error And @error <> 10 Then DllClose($hWs2_32) Return SetError(4, 0, 0) EndIf ExitLoop EndIf $pAnycastAddress = DllStructGetData($tIP_ADAPTER_ANYCAST_ADDRESS, "Next") If Not ($pAnycastAddress == $pNull) Then $tIP_ADAPTER_ANYCAST_ADDRESS = DllStructCreate($tagIP_ADAPTER_ANYCAST_ADDRESS, $pAnycastAddress) EndIf WEnd If $iShowAll == 2 Then If $aAddresses[0] Then $aResult[$nAdapter - 1][2] = $aAddresses EndIf EndIf ;Multicast address, it shows only the first one if $iShowAll == 1 $pMulticastAddress = DllStructGetData($tIP_ADAPTER_ADDRESSES, "FirstMulticastAddress") If Not ($pMulticastAddress == $pNull) Then $tIP_ADAPTER_MULTICAST_ADDRESS = DllStructCreate($tagIP_ADAPTER_MULTICAST_ADDRESS, $pMulticastAddress) If $iShowAll == 2 Then Local $aAddresses[0] While $pMulticastAddress <> $pNull $plpSockaddr = DllStructGetData($tIP_ADAPTER_MULTICAST_ADDRESS, "AddresslpSockaddr") $iSockaddrLength = DllStructGetData($tIP_ADAPTER_MULTICAST_ADDRESS, "AddressiSockaddrLength") $aRet = DllCall($hWs2_32, "int", "WSAAddressToString", "ptr", $plpSockaddr, "int", $iSockaddrLength, "ptr", Null, "byte*", Null, "dword*", 0) If @error Then DllClose($hWs2_32) Return SetError(3, 0, 0) EndIf $tbuffer_lpszAddressString = DllStructCreate("wchar[" & $aRet[5] & "]") $pbuffer_lpszAddressString = DllStructGetPtr($tbuffer_lpszAddressString) $aRet = DllCall($hWs2_32, "int", "WSAAddressToStringW", "ptr", $plpSockaddr, "int", $iSockaddrLength, "ptr", Null, "ptr", $pbuffer_lpszAddressString, "dword*", $aRet[5]) If @error Then DllClose($hWs2_32) Return SetError(3, 0, 0) EndIf If $iShowAll == 2 Then $iCounter = UBound($aAddresses) ReDim $aAddresses[$iCounter + 1] $aAddresses[$iCounter] = _WinAPI_GetString($pbuffer_lpszAddressString) If @error And @error <> 10 Then DllClose($hWs2_32) Return SetError(4, 0, 0) EndIf Else $aResult[$nAdapter - 1][3] = _WinAPI_GetString($pbuffer_lpszAddressString) If @error And @error <> 10 Then DllClose($hWs2_32) Return SetError(4, 0, 0) EndIf ExitLoop EndIf $pMulticastAddress = DllStructGetData($tIP_ADAPTER_MULTICAST_ADDRESS, "Next") If Not ($pMulticastAddress == $pNull) Then $tIP_ADAPTER_MULTICAST_ADDRESS = DllStructCreate($tagIP_ADAPTER_MULTICAST_ADDRESS, $pMulticastAddress) EndIf WEnd If $iShowAll == 2 Then If $aAddresses[0] Then $aResult[$nAdapter - 1][3] = $aAddresses EndIf EndIf ;DnsServer 1 and 2 $pDnsServerAddress = DllStructGetData($tIP_ADAPTER_ADDRESSES, "FirstDnsServerAddress") If Not ($pDnsServerAddress == $pNull) Then $tADAPTER_DNS_SERVER_ADDRESS = DllStructCreate($tagIP_ADAPTER_DNS_SERVER_ADDRESS, $pDnsServerAddress) For $iCounter = 4 To 5 $plpSockaddr = DllStructGetData($tADAPTER_DNS_SERVER_ADDRESS, "AddresslpSockaddr") $iSockaddrLength = DllStructGetData($tADAPTER_DNS_SERVER_ADDRESS, "AddressiSockaddrLength") $aRet = DllCall($hWs2_32, "int", "WSAAddressToString", "ptr", $plpSockaddr, "int", $iSockaddrLength, "ptr", Null, "byte*", Null, "dword*", 0) If @error Then DllClose($hWs2_32) Return SetError(3, 0, 0) EndIf $tbuffer_lpszAddressString = DllStructCreate("wchar[" & $aRet[5] & "]") $pbuffer_lpszAddressString = DllStructGetPtr($tbuffer_lpszAddressString) $aRet = DllCall($hWs2_32, "int", "WSAAddressToStringW", "ptr", $plpSockaddr, "int", $iSockaddrLength, "ptr", Null, "ptr", $pbuffer_lpszAddressString, "dword*", $aRet[5]) If @error Then DllClose($hWs2_32) Return SetError(3, 0, 0) EndIf $aResult[$nAdapter - 1][$iCounter] = _WinAPI_GetString($pbuffer_lpszAddressString) If @error And @error <> 10 Then DllClose($hWs2_32) Return SetError(4, 0, 0) EndIf $pDnsServerAddress = DllStructGetData($tADAPTER_DNS_SERVER_ADDRESS, "Next") If Not ($pDnsServerAddress == $pNull) Then $tADAPTER_DNS_SERVER_ADDRESS = DllStructCreate($tagIP_ADAPTER_DNS_SERVER_ADDRESS, $pDnsServerAddress) Else ExitLoop EndIf Next EndIf ;AdapterName $aResult[$nAdapter - 1][6] = _WinAPI_GetString(DllStructGetData($tIP_ADAPTER_ADDRESSES, "AdapterName"), False) If @error And @error <> 10 Then DllClose($hWs2_32) Return SetError(4, 0, 0) EndIf ;Description $aResult[$nAdapter - 1][7] = _WinAPI_GetString(DllStructGetData($tIP_ADAPTER_ADDRESSES, "Description")) If @error And @error <> 10 Then DllClose($hWs2_32) Return SetError(4, 0, 0) EndIf ;MAC $sMAC = String(DllStructGetData($tIP_ADAPTER_ADDRESSES, "PhysicalAddress")) $aResult[$nAdapter - 1][8] = StringRegExpReplace( _ StringTrimRight(StringTrimLeft($sMAC, 2), _ ;0x StringLen($sMAC) - ((DllStructGetData($tIP_ADAPTER_ADDRESSES, "PhysicalAddressLength") * 2) + 2)), _ "(.{2})(?!$)", "$1-") ;from 0xG4V4B5B4V2N2000000 to G4-V4-B5-B4-V2-N2 ;IfType Switch DllStructGetData($tIP_ADAPTER_ADDRESSES, "IfType") Case $IF_TYPE_ETHERNET_CSMACD Switch @OSVersion Case "WIN_XP", "WIN_XPe", "WIN_2003" $aResult[$nAdapter - 1][9] = "Ethernet or wireless network interface" Case Else $aResult[$nAdapter - 1][9] = "Ethernet network interface" EndSwitch Case $IF_TYPE_IEEE80211 $aResult[$nAdapter - 1][9] = "Wireless network interface" Case $IF_TYPE_TUNNEL $aResult[$nAdapter - 1][9] = "Tunnel type encapsulation network interface" Case $IF_TYPE_IEEE1394 $aResult[$nAdapter - 1][9] = "Firewire network interface" Case Else $aResult[$nAdapter - 1][9] = "Other type of network interface" EndSwitch EndIf EndIf $pbuffer_AdapterAddresses = DllStructGetData($tIP_ADAPTER_ADDRESSES, "Next") If Not ($pbuffer_AdapterAddresses == $pNull) Then $tIP_ADAPTER_ADDRESSES = DllStructCreate($tagIP_ADAPTER_ADDRESSES, $pbuffer_AdapterAddresses) EndIf Until $pbuffer_AdapterAddresses == $pNull TCPShutdown() DllClose($hWs2_32) Return $aResult EndFunc ;==>_WinAPI_GetAdaptersAddresses It is really useful because it can retrieve all informations needed for every adapters and it works with IPv6 too (opposite of GetAdaptersInfo, that supports only IPv4). I've made it compatible with every OS (from Windows XP). Test it and report any bug in this topic, please! I've attached an example about how it can be used, enjoy it EDIT: Last UDF version: 13th February 2015 GetAdaptersAddresses.au31 point