Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 06/28/2020 in all areas

  1. After seeing a number of threads talking about how to exchange efficiently messages between processes (Inter Process Communication), I decided to create a framework using Windows Messages WM_COPYDATA. What is new with this UDF you ask ? Well it will depends how familiar you are with IPC. One thing is sure, the simplicity of use and the fabulous speed are amazing. This is based on a Clients-Server approach. You can have an unlimited number of clients talking with a single server. You will have to define the protocol of communication between them, but the code you have to create is incredibly low. The UDF proposes 2 simple message properties of communication. The first (called data) is based on a number. You can decide what value 1,2,3, etc. means between your client and server. Server will react upon the value of the data field. Second, there is a string field where you can inscribe additional information on request, and where the server will respond to client request (if necessary). Here are the functions that I have wrapped around this : Func _WCD_CreateServer Func _WCD_CreateClient Func _WCD_GetServerHandle Func _WCD_IsServerAvailable Func _WCD_Send Func _WCD_WM_COPYDATA_CLIENT_HANDLER Func _WCD_Client_GetResponse Func _WCD_WM_COPYDATA_SERVER_HANDLER Func _WCD_Server_PeekRequest Func _WCD_Server_GetRequest Func _WCD_Server_IsRequestAvail Here an example of the server : #include <Constants.au3> #include <GUIConstants.au3> #include "WCD_IPC.au3" Opt ("MustDeclareVars", 1) $_WCD_Verbose = False ; make it True if you want to follow the convos. False is by default. Local $hServer = _WCD_CreateServer () Local $aReq, $iData While True If _WCD_Server_IsRequestAvail () Then $aReq = _WCD_Server_GetRequest () $iData = @extended Switch $iData Case 1 ; who are you _WCD_Send($hServer, $aReq[0], $iData, @ComputerName) Case 2 Switch Number($aReq[1]) Case 1 _WCD_Send($hServer, $aReq[0], $iData, @IPAddress1) Case 2 _WCD_Send($hServer, $aReq[0], $iData, @IPAddress2) Case 3 _WCD_Send($hServer, $aReq[0], $iData, @IPAddress3) Case 4 _WCD_Send($hServer, $aReq[0], $iData, @IPAddress4) Case Else _WCD_Send($hServer, $aReq[0], $iData, "Invalid parameter") EndSwitch EndSwitch EndIf Sleep (100) WEnd And the client : #include <Constants.au3> #include <GUIConstants.au3> #include "WCD_IPC.au3" Opt ("MustDeclareVars", 1) $_WCD_Verbose = True ; as for the server, you can decide to make client verbose or not Global $hWnd = _WCD_CreateClient ("Test WCD Client") Global $hWndServer = _WCD_GetServerHandle () _WCD_Send($hWnd, $hWndServer, 1) ; simple request - who are you ? Local $sString = WaitForResponse () ConsoleWrite ($sString & @CRLF) _WCD_Send($hWnd, $hWndServer, 2, "5") ; adding text to a more complex request $sString = WaitForResponse () ConsoleWrite ($sString & @CRLF) Func WaitForResponse () Local $sResp While _WCD_IsServerAvailable () $sResp = _WCD_Client_GetResponse () If $sResp <> "" Then Return $sResp Sleep (100) WEnd EndFunc As always, let me know if you got issues, comments, suggestions. I will be glad to answer. Version 2020-06-27 * Allows processes with different levels of privilege to communicate with each other WCD_IPC.au3
    1 point
  2. Dan_555

    Simple Snippet Manager

    Hi, i'v just uploaded my latest project: Simple Snippet Manager to the Downloads. area : The intended usage is to select a Snippet, and to copy it's contents into your favorite Editor. The Copy/Paste process happens over the (windows)Clipboard. The previous clipboard content is not restored. There is a time limit of 60 seconds, in which the pasting of the text is allowed (starting when the App window gets inactive). The Hotkey is reenabled, when the main Window is activated. This is a File/Folder based manager. The App is configured to hold 4000 files and 400 folders with searching depth of 5 sub-folders. The root folder is freely selectable, but it should be a Folder with writing permission. Please install the App in a folder with Writing permission, too. This App only uses an .ini file to save it's configuration, which has to be in the same folder as the App. First configuration: 1. Open the config Window. 2. Enter the Language name, create or seek a root folder, enter an extension. 3. Click on Set button. 4. Click on the Exit button. The Language configuration is done, adding files or folders are needed: 1. Select the language from the dropbox list, and click on Get Lang button. 2a. Right Click on the root folder, chose New folder to add categories. 2b. or chose New/Edit file to open the builtin text editor 3. Paste or Write a snippet-code, enter a filename and save it. (Repeat the 3. as needed) Usage: Select a language, then click on Get Lang button. Choose a file with the left mouse button. Check if the code was loaded in the Textarea at the bottom. Switch to your Sourcecode editor, and press the Hotkey (default= Ctrl/Strg b) to copy and paste the text. There is a time limit of 60 seconds, after the main window gets inactive, in which the copy&pasting is allowed. Changelog: V1.02 (24.06.2020) Addition: Undocumented ini setting: StartLoadLastUsedLanguage Setting this to 1 (default value) will now reload the Last used language at start. Last used language counts for the Language, selected with [Get Lang] button. The [Config] button will delete the last used language. LastUsedLanguageNr, LastUsedLanguageName ini settings are used internaly for the above function. Added version string to the main Window title. V1.01 (23.06.2020) Bugfix : Starting the App without the ini file now sets the correct starting Hotkey (Ctrl b) Addition: Clipboard is saved, before pasting, and restored after pasting. (May work with text data only. p.s. untested!)
    1 point
  3. AutoIt MediaDevice Library Allows you to communicate with attached media and storage devices. What's MediaDevice Library? MediaDevice Allows you to communicate with attached media and storage devices. Features. List Files and Folders. Delete Files and Folders. Copy File From Device. Copy File To Device. Basic Usage: #include "..\MediaDevice.au3" Local $sDevice = _MD_DeviceGet() ;Get First Found Portable Device Local $oDevice = _MD_DeviceOpen($sDevice) Local $aDrives = _MD_DeviceGetDrives($oDevice) _ArrayDisplay($aDrives,"Storage Drives") _MD_DeviceClose($oDevice) More examples here. Check MediaDevice on GitHub. Saludos
    1 point
  4. IE is not new but newer versions are not emulated ( IE8+ ) so a function to expressly set the IE version to load when embedded was needed. Otherwise some technologies will not behave as expected of a modern browser. #include <GUIConstantsEx.au3> #include <IE.au3> #include <WindowsConstants.au3> Func _IEGetEmbeddedBrowserEmulation() Local $iRet = RegRead("HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION", _ StringTrimLeft(@AutoItExe, StringInStr(@AutoItExe, "\", 0, -1))) Return SetError(@error, @extended, $iRet) EndFunc ;==>_IEGetEmbeddedBrowserEmulation Func _IESetEmbeddedBrowserEmulation($FEATURE_BROWSER_EMULATION = Default) ; ..update as of 6/28/2020 If Not Int($FEATURE_BROWSER_EMULATION) And Not IsKeyword($FEATURE_BROWSER_EMULATION) Then RegDelete("HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION", _ StringTrimLeft(@AutoItExe, StringInStr(@AutoItExe, "\", 0, -1))) Return SetError(@error, 2, "") EndIf Local $iRet = _IEGetEmbeddedBrowserEmulation() If $FEATURE_BROWSER_EMULATION = Default Then $FEATURE_BROWSER_EMULATION = Int(FileGetVersion("ieframe.dll")) * 1000 If Int($FEATURE_BROWSER_EMULATION) = 0 Then Return SetError(10, 3, $iRet) If $iRet <> $FEATURE_BROWSER_EMULATION Then ; https://msdn.microsoft.com/en-us/library/ee330730(v=vs.85).aspx $iRet = RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION", _ StringTrimLeft(@AutoItExe, StringInStr(@AutoItExe, "\", 0, -1)), "REG_DWORD", $FEATURE_BROWSER_EMULATION) Return SetError(@error, 1, ($iRet = 1 ? $FEATURE_BROWSER_EMULATION : $iRet)) EndIf Return $iRet EndFunc ;==>_IESetEmbeddedBrowserEmulation Example() Func Example() ; https://www.autoitscript.com/forum/topic/203209-_iesetEmbeddedBrowserEmulation/ _IESetEmbeddedBrowserEmulation(0) ; remove setting. It'll default to IE 7. ;~ _IESetEmbeddedBrowserEmulation() ; set default to available IExplorer in the OS. ConsoleWrite("_IEGetEmbeddedBrowserEmulation(): " & _IEGetEmbeddedBrowserEmulation() & @CRLF) Local $oIE = _IECreateEmbedded() _IEErrorHandlerRegister() ; this is here so CheckError() get to kick in GUICreate("Embedded Web control Test", 640, 580, _ (@DesktopWidth - 640) / 2, (@DesktopHeight - 580) / 2, _ $WS_OVERLAPPEDWINDOW + $WS_CLIPSIBLINGS + $WS_CLIPCHILDREN) GUICtrlCreateObj($oIE, 10, 40, 600, 360) Local $idButton_Back = GUICtrlCreateButton("Back", 10, 420, 100, 30) Local $idButton_Forward = GUICtrlCreateButton("Forward", 120, 420, 100, 30) Local $idButton_Home = GUICtrlCreateButton("Home", 230, 420, 100, 30) Local $idButton_Stop = GUICtrlCreateButton("Stop", 340, 420, 100, 30) Global $g_idError_Message = GUICtrlCreateLabel("", 100, 500, 500, 30, -1, 0) GUICtrlSetColor(-1, 0xff0000) GUISetState(@SW_SHOW) ;Show GUI _IENavigate($oIE, "https://www.w3schools.com/js/tryit.asp?filename=tryjs_ajax_suggest_php") _IEAction($oIE, "stop") While 1 Local $iMsg = GUIGetMsg() Select Case $iMsg = $GUI_EVENT_CLOSE ExitLoop Case $iMsg = $idButton_Home _IENavigate($oIE, "https://www.w3schools.com/js/tryit.asp?filename=tryjs_ajax_suggest_php") _IEAction($oIE, "stop") CheckError("Home", @error, @extended) Case $iMsg = $idButton_Back _IEAction($oIE, "back") CheckError("Back", @error, @extended) Case $iMsg = $idButton_Forward _IEAction($oIE, "forward") CheckError("Forward", @error, @extended) Case $iMsg = $idButton_Stop _IEAction($oIE, "stop") CheckError("Stop", @error, @extended) EndSelect WEnd GUIDelete() EndFunc ;==>Example Func CheckError($sMsg, $iError, $iExtended) If $iError Then $sMsg = "Error using " & $sMsg & " button (" & $iExtended & ")" Else $sMsg = "" EndIf GUICtrlSetData($g_idError_Message, $sMsg) EndFunc ;==>CheckError if within a week no one came up with better code, I'll add these 2 functions to the trac, to be evaluated for adding it to IE.au3 on a next beta oh, ..do uncomment the _IESetEmbeddedBrowserEmulation() to see the difference between declared emulation and not. Your ideas are very much welcomed. PS: for now I guess this code is just an example. 6/27/2020 update: To look for the IE version and use that as the Default value. This way if you have, say v10.x.x.x, it will not try to emulate v11. The default browser value is the Int(version) & "000", so it does not need a lookup a table. Tested on XP, Win7 and Win10. 6/28/2020 update: Renamed the functions from *BrowserEmulation() to * EmbeddedBrowserEmulation() as it truly only applies to an Embedded Browser. Also changed the Version discovery form looking at the EXE to looking at the DLL. ( all this thanks to @Chimp's clues )
    1 point
  5. Nine

    CTRL SHIFT ALT Stuck Down

    That is really too bad. Since you are doomed to use Send (unless you want to tackle yourself with UIAutomation), maybe try something like this : While _IsPressed ("10") Or _IsPressed ("11") Or _IsPressed ("12") Sleep (50) WEnd at the beginning of each hotkey set (you can create a small func for it). See if that helps.
    1 point
  6. Nine

    memory mapped file questions

    Couple of small issues I foresee: 1- Sender needs to close handle when file map is not required anymore 2- Receiver should erase content of the file map after reading so sender knows that content has been well received
    1 point
  7. Jos

    question about winhttp

    This is an example script that will read your posted data from "data.txt" and then display 2 of the keys of which one is containing Unicode characters: #include "Json.au3" $data = FileRead("data.txt") Json_dump($data) $object = json_decode($data) $register_date=json_get($object, '.conversation.Starter.register_date') MsgBox(262144, 'Debug line ~' & @ScriptLineNumber, 'Selection:' & @CRLF & '$register_date' & @CRLF & @CRLF & 'Return:' & @CRLF & $register_date) ;### Debug MSGBOX $signature=json_get($object, '.conversation.Starter.signature') MsgBox(262144, 'Debug line ~' & @ScriptLineNumber, 'Selection:' & @CRLF & '$signature' & @CRLF & @CRLF & 'Return:' & @CRLF & $signature) ;### Debug MSGBOX The json.au3 can be found here: Jos
    1 point
  8. Hi @argumentum, shouldn't you also check whether to enable or disable the redirection of the WOW64 file system for 32-bit programs running on 64-bit systems so to avoid the not finding of those registry keys in that cases? (*) p.s. take a look here too: https://www.autoitscript.com/forum/topic/163492-ie-embedded-control-versioning-use-ie9-and-html5-in-a-gui/ https://weblog.west-wind.com/posts/2011/May/21/Web-Browser-Control-Specifying-the-IE-Version P.P.S. (*) edit: The above would only be true if you chose to set these keys at machine level in HKLM. Since you have chosen to act at the current user level HKCU, it is not necessary. sorry for my inaccuracy
    1 point
  9. hello again, i confermed that the problem from the xenforo api i conntacted them now i have a small problem with json i hope that i can find here a reply i have this data { "success": true, "conversation": { "can_edit": true, "can_invite": true, "can_reply": true, "can_upload_attachment": true, "conversation_id": 955, "conversation_open": true, "first_message_id": 1710, "is_starred": false, "last_message_date": 1593345206, "last_message_id": 1710, "last_message_user_id": 5, "open_invite": false, "recipient_count": 2, "recipients": { "2": "MesterPerfect" }, "reply_count": 0, "start_date": 1593345206, "Starter": { "activity_visible": false, "avatar_urls": { "o": "https://mx-blind.com/vb/data/avatars/o/0/5.jpg?1534192853", "h": "https://mx-blind.com/vb/data/avatars/h/0/5.jpg?1534192853", "l": "https://mx-blind.com/vb/data/avatars/l/0/5.jpg?1534192853", "m": "https://mx-blind.com/vb/data/avatars/m/0/5.jpg?1534192853", "s": "https://mx-blind.com/vb/data/avatars/s/0/5.jpg?1534192853" }, "can_ban": false, "can_converse": false, "can_edit": true, "can_follow": false, "can_ignore": false, "can_post_profile": true, "can_view_profile": true, "can_view_profile_posts": true, "can_warn": false, "custom_fields": { "facebook": "baaziznacer1", "gender": "male", "screen_readers": "2", "skype": "simple-blind", "twitter": "baaziznacer", "windows": "4" }, "custom_title": "", "is_admin": true, "is_banned": false, "is_discouraged": false, "is_followed": false, "is_ignored": false, "is_moderator": true, "is_staff": true, "is_super_admin": true, "last_activity": 1593287145, "location": "\u0627\u0644\u062c\u0632\u0627\u0626\u0631", "message_count": 597, "reaction_score": 569, "register_date": 1533642994, "secondary_group_ids": [ 3, 4 ], "signature": "\u2022 \u0627\u0644\u062f\u0646\u064a\u0627 \u062b\u0644\u0627\u062b\u0629 \u0623\u064a\u0627\u0645: \u0627\u0644\u0623\u0645\u0633 \u0639\u0634\u0646\u0627\u0647 \u0648\u0644\u0646 \u064a\u0639\u0648\u062f\u060c \u0627\u0644\u064a\u0648\u0645 \u0646\u0639\u064a\u0634\u0647 \u0648\u0644\u0646 \u064a\u062f\u0648\u0645\u060c \u0648\u0627\u0644\u063a\u062f: \u0644\u0627 \u0646\u062f\u0631\u064a \u0623\u064a\u0646 \u0633\u0646\u0643\u0648\u0646 \u0641\u0635\u0627\u0641\u062d\u060c \u0648\u0633\u0627\u0645\u062d\u060c \u0648\u062f\u0639 \u0627\u0644\u062e\u0644\u0642 \u0644\u0644\u062e\u0627\u0644\u0642\u060c \u0641\u0623\u0646\u0627 \u0648\u0623\u0646\u062a \u0648\u0647\u0645 \u0648\u0646\u062d\u0646 \u0631\u0627\u062d\u0644\u0648\u0646\u060c \u0641\u0645\u0646 \u0623\u0639\u0645\u0627\u0642 \u0642\u0644\u0628\u0643 \u0633\u0627\u0645\u062d \u0645\u0646 \u0623\u0633\u0627\u0621 \u0625\u0644\u064a\u0643.", "trophy_points": 210, "user_group_id": 2, "user_id": 5, "user_state": "valid", "user_title": "\u0639\u0636\u0648 \u0645\u062d\u062a\u0631\u0641", "username": "\u0646\u0627\u0635\u0631 \u0628\u0639\u0632\u064a\u0632", "visible": true, "warning_points": 0, "website": "http://mx-blind.com/" }, "title": "\u0623\u0646\u0627 \u0632\u0641\u062a", "user_id": 5, "username": "\u0646\u0627\u0635\u0631 \u0628\u0639\u0632\u064a\u0632" } } i need to decode it using json can we do that using autoit? because the utf8 text here is encoded thanks in advance
    1 point
  10. Hello. Just Make sure to review your code deeply. #NoTrayIcon #include <MsgBoxConstants.au3> #include <WinAPIFiles.au3> #include <WinAPIHObj.au3> Opt('WinWaitDelay', 0) _Receiver() Func _Receiver() Local $hMapping = _WinAPI_OpenFileMapping('Test') If Not $hMapping Then Return Local $pAddress = _WinAPI_MapViewOfFile($hMapping) Local $tData = DllStructCreate('byte[1000]', $pAddress) Sleep(2000) Local $bText = DllStructGetData($tData, 1) ;Get Text in Binary Local $tStr = DllStructCreate("char Str[100]", $pAddress + 56) ;Address+Offset where you write from C# //accessor.WriteArray(54 + 2, Buffer, 0, Buffer.Length); If $bText Then MsgBox(BitOR($MB_ICONINFORMATION, $MB_SYSTEMMODAL), "Show Binary (receiver)", $bText) If $tStr.Str Then MsgBox(BitOR($MB_ICONINFORMATION, $MB_SYSTEMMODAL), "Show Text (receiver)", $tStr.Str) _WinAPI_UnmapViewOfFile($pAddress) _WinAPI_CloseHandle($hMapping) EndFunc ;==>_Receiver Saludos
    1 point
  11. Efo74, I am but a hobbyist coder as well - but with perhaps just a little more experience than you . It was ~50 years ago I got my first experience of programming a computer to play Nim thanks to my very progressive 6th form maths master. We were using the mainframe of Imperial College - where a few years later I took my only formal programming classes (in Fortran) as part of my Aeronautical Engineering degree. Since then I have used various flavours of Sinclair home computers and then PCs, using Basic, assembly and AutoIt languages. It has given me a lot of pleasure over the years. M23
    1 point
  12. Melba23

    AutoIt v3.3.15.2 Beta

    mdanielm, While appreciating that the results do not appear to be what you would expect - especially in your second example - I would argue that you make a good argument for the use of parentheses to explicitly force the operators to be used in the order you require. M23 P.S. And you do realise that the latest version is actually 3.3.15.3?
    1 point
  13. unfortunately, the same problem i will try to use the delete with php and i will see the return, then i will tell you what the result
    1 point
  14. Nine

    CTRL SHIFT ALT Stuck Down

    I know I have been thru that. This is why I suggested using control* function. And btw, it is possible to reduce the number of lines of the script by 10+ times. No kidding.
    1 point
  15. TheXman

    Query Not displaying

    Thanks! I'm glad you were able to get it all sorted out.
    1 point
  16. TheXman

    WinHTTP functions

    Does the link not work for you?
    1 point
  17. An obvious use of ROT objects is in connection with tasks such as inter-process communication (IPC). The advantage of using ROT objects for these tasks is partly that you can handle large amounts of data and partly that you can handle the vast majority of AutoIt data types. This thread implements a UDF for inter-process communication between two AutoIt scripts based on ROT objects. Simple exampleExamples\0) Sample\ is a simple example. There are 4 files in the folder: Sender.au3: #include "..\..\Includes\IPCROT_Sender.au3" Example() Func Example() ; Create array Local $aArray[1000][10] For $i = 0 To 1000 - 1 For $j = 0 To 9 $aArray[$i][$j] = $i & "/" & $j Next Next ; Send array IPCROT_Sender( "Example", $aArray ) MsgBox( 0, "Sender", "@error = " & @error & ", @extended = " & @extended & @CRLF ) $aArray = 0 EndFunc Receiver.au3: #include <Array.au3> #include "..\..\Includes\IPCROT_Receiver.au3" Example() Func Example() ; Get array Local $aArray IPCROT_Receiver( "Example", $aArray ) MsgBox( 0, "Receiver", "@error = " & @error & ", @extended = " & @extended & @CRLF ) _ArrayDisplay( $aArray, "Receiver" ) $aArray = 0 EndFunc Start1.au3: Run( @AutoItExe & " /AutoIt3ExecuteScript Sender.au3", "" ) Run( @AutoItExe & " /AutoIt3ExecuteScript Receiver.au3", "" ) Start2.au3: Run( @AutoItExe & " /AutoIt3ExecuteScript Receiver.au3", "" ) Run( @AutoItExe & " /AutoIt3ExecuteScript Sender.au3", "" ) Start1.au3 and Start2.au3 shows that it doesn't matter if you start Sender.au3 first or Receiver.au3 first. Another way to start the programs is to double-click Receiver.au3 and then double-click Sender.au3 within 10 seconds. Or double-click Sender.au3 and then double-click Receiver.au3 within 10 seconds. 10 seconds because the default timeout for both IPCROT_Sender() and IPCROT_Receiver() functions is 10 seconds. Timeout can be set via a parameter. Debug exampleExamples\1) Debug\ is a debug example. There are 3 files in the folder: Sender.au3: #include "..\..\Includes\IPCROT_SenderDebug.au3" Example() Func Example() ; Create array Local $aArray[1000][10] For $i = 0 To 1000 - 1 For $j = 0 To 9 $aArray[$i][$j] = $i & "/" & $j Next Next ; Send array Local $hDebug IPCROT_Sender( $hDebug, "Debug", $aArray ) MsgBox( 0, "Sender", "@error = " & @error & ", @extended = " & @extended & @CRLF ) EndFunc Receiver.au3: #include <Array.au3> #include "..\..\Includes\IPCROT_ReceiverDebug.au3" Example() Func Example() ; Get array Local $aArray, $hDebug IPCROT_Receiver( $hDebug, "Debug", $aArray ) MsgBox( 0, "Receiver", "@error = " & @error & ", @extended = " & @extended & @CRLF ) _ArrayDisplay( $aArray, "Receiver" ) $aArray = 0 EndFunc Start.au3: Run( @AutoItExe & " /AutoIt3ExecuteScript Sender.au3", "" ) Run( @AutoItExe & " /AutoIt3ExecuteScript Receiver.au3", "" ) The difference between the debug and non-debug versions is the include files and the way the IPCROT_Sender() and IPCROT_Receiver() functions are called. The debug functions must be called with an initial $hDebug parameter that is a reference to the debug window. The Debug window contains an Edit control to display debug information. If you run Start.au3, debug information is generated in this way: Sender Debug output: Establish communication with Receiver() function Info - Check that the (hidden) window "DebugIPCROT_SenderGui" doesn't exist Checking... Info - The (hidden) window "DebugIPCROT_SenderGui" doesn't exist Checked OK Info - Create window to establish communication between Sender and Receiver Creating... Info - "DebugIPCROT_SenderGui" to establish communication is created 0x002003BE Info - Get $hReceiverGui from "DebugIPCROT_ReceiverGui" window Get $hReceiverGui... Info - Got $hReceiverGui from "DebugIPCROT_ReceiverGui" window 0x000503B8 Info - Verify communication with Receiver by sending $hSenderGui to Receiver Verifying... Info - Communication with Receiver has been verified so far Verified OK Info - Sender has been running for a total of (milliseconds) 340.758703766091 Pass data from Sender() to Receiver() through ROT object Info - Register ROT object: $sROTNameId = Debug-{43EDDFE3-7803-402A-AC63-A122164C1853} Info - ROT object is registered: $sROTNameId = Debug-{43EDDFE3-7803-402A-AC63-A122164C1853} Info - Copy $sROTNameId to Receiver Copying... Info - $sROTNameId is copied to Receiver Copied OK Info - Get the ROT object Get ROT object... Info - Got the ROT object ROT object OK Info - Store data in ROT object, may be time consuming for large amounts of data Store data... Info - Data is stored in ROT object, the storing time is (milliseconds) 8.8428446044186 Info - Send "Data is ready message" to Receiver Data ready... Info - "Data is ready message" is send to Receiver Data ready OK Info - Idle loop until data is received by Receiver or an error has occurred Waiting (max 100 sec)... Info - Informed by Receiver that data is received Data received OK Info - Removing ROT object Removed OK Info - Sender has been running for a total of (milliseconds) 550.850650732295 Receiver Debug output: Establish communication with Sender() function Info - Check that the (hidden) window "DebugIPCROT_ReceiverGui" doesn't exist Checking... Info - The (hidden) window "DebugIPCROT_ReceiverGui" doesn't exist Checked OK Info - Create window to establish communication between Sender and Receiver Creating... Info - "DebugIPCROT_ReceiverGui" to establish communication is created 0x000503B8 Info - Get $hSenderGui from "DebugIPCROT_SenderGui" window Get $hSenderGui... Info - Got $hSenderGui from "DebugIPCROT_SenderGui" window 0x002003BE Info - Verify communication with Sender by sending $hReceiverGui to Sender Verifying... Info - Communication with Sender has been verified so far Verified OK Info - Receiver has been running for a total of (milliseconds) 342.119567626512 Receive data from Sender() through ROT object Info - Idle loop until data is ready for Receiver or an error has occurred Waiting (max 100 sec)... Info - $sROTNameId is received: $sROTNameId = Debug-{43EDDFE3-7803-402A-AC63-A122164C1853} Info - Received "Data is ready message" from Sender Data ready OK Info - Get the ROT object Get ROT object... Info - Got the ROT object ROT object OK Info - Load data from ROT object Load data... Info - Data is loaded from ROT object, the loading time is (milliseconds) 36.1543184155466 Info - Inform Sender that data has been received Data received OK Info - Receiver has been running for a total of (milliseconds) 508.463010656406 Note that there is no message loop in the debug windows. It's the MsgBoxes that keeps the debug windows open. When you close the Receiver MsgBox, the array received from the Sender() function is displayed with _ArrayDisplay(). Now, the _ArrayDisplay() function keeps the Receiver debug window open. When you close the _ArrayDisplay() window, the Receiver debug window also closes. When you close the Sender() MsgBox, the Sender debug window also closes. If you double-click Sender.au3 and wait for 10 seconds until timeout, you'll see this information. Sender Debug output: Establish communication with Receiver() function Info - Check that the (hidden) window "DebugIPCROT_SenderGui" doesn't exist Checking... Info - The (hidden) window "DebugIPCROT_SenderGui" doesn't exist Checked OK Info - Create window to establish communication between Sender and Receiver Creating... Info - "DebugIPCROT_SenderGui" to establish communication is created 0x0005039C Info - Get $hReceiverGui from "DebugIPCROT_ReceiverGui" window Get $hReceiverGui... Error - Couldn't get $hReceiverGui from "DebugIPCROT_ReceiverGui" window @error = 2, @extended = 0 Error - Sender has been trying until timeout after 10 seconds If you double-click Receiver.au3 and wait for 10 seconds until timeout, you'll see this information. Receiver Debug output: Establish communication with Sender() function Info - Check that the (hidden) window "DebugIPCROT_ReceiverGui" doesn't exist Checking... Info - The (hidden) window "DebugIPCROT_ReceiverGui" doesn't exist Checked OK Info - Create window to establish communication between Sender and Receiver Creating... Info - "DebugIPCROT_ReceiverGui" to establish communication is created 0x000603A6 Info - Get $hSenderGui from "DebugIPCROT_SenderGui" window Get $hSenderGui... Error - Couldn't get $hSenderGui from "DebugIPCROT_SenderGui" window @error = 2, @extended = 0 Error - Receiver has been trying until timeout after 10 seconds How does it work?From the debug information it should be possible to get an impression of how the code works. The code in both the IPCROT_Sender() and IPCROT_Receiver() functions is divided into two sections. The first section is about establishing communication with the other function. The second section is about the actual data transfer. Function header for IPCROT_Sender(): ; Success: Returns 1 ; Failure: Returns 0 ; Sets @error and @extended ; @error = 1: SenderGui error ; @error = 2: $hReceiverGui error ; @error = 3: Communication with Receiver cannot be verified ; @error = 4: ROT_RegisterObject error ; @error = 5: IPCROT_SendCopyData error ; @error = 6: Get the ROT object error ; @error = 7: Data is ready message error ; @error = 8: Error occured in Receiver() function ; @error = 9: Idle loop timeout, most likely an error ; @extended = zero based error occurrence Func IPCROT_Sender( _ ; Pass data (usually an array or object) from Sender to Receiver through ROT object. $sNameId, _ ; $sNameId is a unique identifier to secure multiple concurrent data communications. $vData, _ ; $vData is the data to be sent from Sender to Receiver, usually an array or object. $iTimeOut = 10 ) ; Time window to establish communication between Sender() and Receiver() functions. ; Does not include time for the actual data transfer. Time setting in seconds. Function header for IPCROT_Receiver(): ; Success: Returns 1 ; Failure: Returns 0 ; Sets @error and @extended ; @error = 1: ReceiverGui error ; @error = 2: $hSenderGui error ; @error = 3: Communication with Sender cannot be verified ; @error = 4: Error occured in Sender() function ; @error = 5: Get the ROT object error ; @error = 6: Idle loop timeout, most likely an error ; @extended = zero based error occurrence Func IPCROT_Receiver( _ ; Pass data (usually an array or object) from Sender to Receiver through ROT object. $sNameId, _ ; $sNameId is a unique identifier to secure multiple concurrent data communications. ByRef $vData, _ ; $vData is the data to be sent from Sender to Receiver, usually an array or object. $iTimeOut = 10 ) ; Time window to establish communication between Sender() and Receiver() functions. ; Does not include time for the actual data transfer. Time setting in seconds. Note that the debug versions of the functions have an additional $hDebug parameter as the first parameter. It's a reference to the debug window. Establish communication Sender-Receiver communication is established through simple Window automation. IPCROT_Sender() creates a (hidden) window titled $sNameId & "IPCROT_SenderGui". IPCROT_Receiver() creates a (hidden) window titled $sNameId & "IPCROT_ReceiverGui". The other function establishes communication by identifying this window. To establish communication between multiple Sender-Receiver pairs at once, $sNameId must be unique for each Sender-Receiver pair. And both the Sender and Receiver window must be opened within the timeout period. Data transfer When communication is established, it's the Sender who plays the role of server. Sender creates the ROT object, sends $sROTNameId to Receiver via a WM_COPYDATA message, stores data in the ROT object and sends a "Data is ready message" to the Receiver. $sROTNameId is created uniquely in this way: $sROTNameId = $sNameId & ROT_CreateGUID(). The Receiver plays the role of client. Once the Receiver has received the "Data is ready message", the Receiver accesses the ROT object with ObjGet() and retrieves the data. Receiver informs Sender that data has been received, which terminates the communication. Internal communication Information in the form of integers sent via WM_USER messages controls the internal communication between Sender and Receiver. IPCROT_Messages.au3: #include-once ; WM_USER messages Global Const $IPCROTMSG_iMsgToSender = 0x7FFF Global Const $IPCROTMSG_iMsgToReceiver = $IPCROTMSG_iMsgToSender - 1 ; Messages to Sender from Receiver Global Const $IPCROTMSG_iReceiverHandle = 1 Global Const $IPCROTMSG_iReceiverDataReceived = 2 Global Const $IPCROTMSG_iReceiverError = 3 Global $IPCROTMSG_iReceiverErrorValue = 4 Global Const $IPCROTMSG_iCommnError = 1 ; ReceiverErrorValue Global Const $IPCROTMSG_iGetROTobject = 4 ; Messages to Receiver from Sender ; $WM_COPYDATA to send $sROTNameId Global Const $IPCROTMSG_iSenderHandle = 5 Global Const $IPCROTMSG_iDataIsReady = 6 Global Const $IPCROTMSG_iSenderError = 7 Global $IPCROTMSG_iSenderErrorValue = 8 ;Global Const $IPCROTMSG_iCommnError = 1 ; SenderErrorValues Global Const $IPCROTMSG_iRegisterROTobject = 2 Global Const $IPCROTMSG_iCopyROTNameId = 3 ;Global Const $IPCROTMSG_iGetROTobject = 4 ; Sender/Receiver errors Global Const $IPCROTMSG_aErrorValues = [ _ "RegisterROTobject", _ "CopyROTNameId", _ "GetROTobject" ] Data typesExamples\2) Data types\ is about data types. The example is based on the example for the VarGetType() function in the help file. DataTypes.au3 is a slightly modified version of this example. Note that all remaining examples run in debug mode so it's possible to see what's going on. In Sender.au3, the various data types are stored in a dictionary object and sent in this way: Local $oDict = ObjCreate( "Scripting.Dictionary" ) $oDict( "$aArray" ) = $aArray $oDict( "$dBinary" ) = $dBinary $oDict( "$bBoolean" ) = $bBoolean $oDict( "$pPtr" ) = $pPtr $oDict( "$hWnd" ) = $hWnd $oDict( "$iInt" ) = $iInt $oDict( "$fFloat" ) = $fFloat $oDict( "$oObject" ) = $oObject $oDict( "$sString" ) = $sString $oDict( "$tStruct" ) = $tStruct $oDict( "$vKeyword" ) = $vKeyword $oDict( "$fuMsgBox" ) = $fuMsgBox $oDict( "$fuFunc" ) = $fuFunc $oDict( "$fuUserFunc" ) = $fuUserFunc ; Send $oDict Local $hDebug IPCROT_Sender( $hDebug, "DataTypes", $oDict ) Receiver.au3: #include "..\..\Includes\IPCROT_ReceiverDebug.au3" Example() Func Example() ; Get $oDict Local $oDict, $hDebug IPCROT_Receiver( $hDebug, "DataTypes", $oDict ) MsgBox( 0, "Receiver: Variable Types", _ "$aArray : " & @TAB & @TAB & VarGetType( $oDict( "$aArray" ) ) & " variable type." & @CRLF & _ "$dBinary : " & @TAB & @TAB & VarGetType( $oDict( "$dBinary" ) ) & " variable type." & @CRLF & _ "$bBoolean : " & @TAB & VarGetType( $oDict( "$bBoolean" ) ) & " variable type." & @CRLF & _ "$pPtr : " & @TAB & @TAB & VarGetType( $oDict( "$pPtr" ) ) & " variable type." & @CRLF & _ "$hWnd : " & @TAB & @TAB & VarGetType( $oDict( "$hWnd" ) ) & " variable type." & @CRLF & _ "$iInt : " & @TAB & @TAB & VarGetType( $oDict( "$iInt" ) ) & " variable type." & @CRLF & _ "$fFloat : " & @TAB & @TAB & VarGetType( $oDict( "$fFloat" ) ) & " variable type." & @CRLF & _ "$oObject : " & @TAB & VarGetType( $oDict( "$oObject" ) ) & " variable type." & @CRLF & _ "$sString : " & @TAB & @TAB & VarGetType( $oDict( "$sString" ) ) & " variable type." & @CRLF & _ "$tStruct : " & @TAB & @TAB & "Not recognized as a valid variable type." & @CRLF & _ "$vKeyword : " & @TAB & VarGetType( $oDict( "$vKeyword" ) ) & " variable type." & @CRLF & _ "fuMsgBox : " & @TAB & "Not recognized as a valid variable type." & @CRLF & _ "$fuFunc : " & @TAB & @TAB & "Not recognized as a valid variable type." & @CRLF & _ "$fuUserFunc : " & @TAB & "Not recognized as a valid variable type." ) EndFunc And this is the text in the Receiver MsgBox: $aArray : Array variable type. $dBinary : Binary variable type. $bBoolean : Bool variable type. $pPtr : Int32 variable type. $hWnd : Int32 variable type. $iInt : Int32 variable type. $fFloat : Double variable type. $oObject : Object variable type. $sString : String variable type. $tStruct : Not recognized as a valid variable type. $vKeyword : Keyword variable type. fuMsgBox : Not recognized as a valid variable type. $fuFunc : Not recognized as a valid variable type. $fuUserFunc : Not recognized as a valid variable type. Only the $tStruct and the function data types are not received correctly by the Receiver function. The Int32 types for $pPtr and $hWnd can easily be converted to pointer and window handles with the Ptr() and HWnd() functions. DllStructThe DllStruct data type ($tStruct in the example above) isn't a COM compatible data type and is therefore not received correctly by the Receiver function. But the Binary data type is received correctly. One way to handle the DllStruct is to convert it to a Binary before it's sent by the Sender() function. And then convert the Binary back to a DllStruct after it's received by the Receiver() function. Examples\3) DllStruct\ is about the DllStruct data type. Binary data What is Binary data and how is Binary data stored in internal AutoIt code? in Accessing AutoIt Variables in Tests\Examples\1) Simple variables\Example3.au3 all the data types in the example for the VarGetType() function are examined. This is the result for the Binary data type: $dBinary Type = Binary ptr = 0x009C59A0 ($pVariant) vt = 0x2011 (VT_ARRAY+VT_UI1, array of 1 byte unsigned integers) data = 0x009DABF8 This means that Binary data is stored internally as a safearray of bytes (also known as a bytearray). When Binary data is passed to a COM method as a parameter, the pointer to this safearray is passed in a variant. Sender and Receiver Sender.au3: #include "AccVars.au3" #include "..\..\Includes\IPCROT_SenderDebug.au3" Example() Func Example() Local Const $tagStruct = "struct;int var1;byte var2;uint var3;char var4[128];endstruct" Local $tStruct1 = DllStructCreate( $tagStruct ) DllStructSetData( $tStruct1, "var1", -1 ) DllStructSetData( $tStruct1, "var2", 255 ) DllStructSetData( $tStruct1, "var3", -1 ) ; The -1 (signed int) will be typecasted to unsigned int. DllStructSetData( $tStruct1, "var4", "Hello" ) ; Change data of element var4 (char) in $tStruct1, DllStructSetData( $tStruct1, "var4", Asc( "h" ), 1 ) ; at the index 1 of the char array (1 based index). Local $dBinary AccVars_DllStructToBinary( $tStruct1, $dBinary ) ; Convert DllStruct to Binary Local $oDict = ObjCreate( "Scripting.Dictionary" ) $oDict( "$tagStruct" ) = $tagStruct $oDict( "$dBinary" ) = $dBinary ; Send $oDict Local $hDebug IPCROT_Sender( $hDebug, "DllStruct", $oDict ) Local $iError = @error, $iExtended = @extended If $iError Then MsgBox( 0, "Sender", "@error = " & $iError & ", @extended = " & $iExtended & @CRLF ) Return EndIf MsgBox( 0, "Sender: $tStruct1", _ "Struct Size: " & DllStructGetSize( $tStruct1 ) & @CRLF & _ "Struct pointer: " & DllStructGetPtr( $tStruct1 ) & @CRLF & _ "Data:" & @CRLF & _ " " & DllStructGetData( $tStruct1, "var1" ) & @CRLF & _ " " & DllStructGetData( $tStruct1, "var2" ) & @CRLF & _ " " & DllStructGetData( $tStruct1, "var3" ) & @CRLF & _ " " & DllStructGetData( $tStruct1, "var4" ) ) EndFunc The DllStruct is copied from the example for the DllStructCreate() function in the help file. AccVars_DllStructToBinary() converts the DllStruct to Binary using the techniques from Accessing AutoIt Variables. The function is discussed below. $tagStruct and $dBinary are stored in a dictionary object and sent using the Sender() function. The original data in $tStruct1 looks like this in a MsgBox: Struct Size: 140 Struct pointer: 0x00B64EA8 Data: -1 255 4294967295 hello Receiver.au3: #include "..\..\Includes\IPCROT_ReceiverDebug.au3" Example() Func Example() ; Get $oDict Local $oDict, $hDebug IPCROT_Receiver( $hDebug, "DllStruct", $oDict ) Local $iError = @error, $iExtended = @extended If $iError Then MsgBox( 0, "Receiver", "@error = " & $iError & ", @extended = " & $iExtended & @CRLF ) Return EndIf Local $tagStruct = $oDict( "$tagStruct" ) Local $dBinary = $oDict( "$dBinary" ) ; Convert Binary to DllStruct Local $iSize = BinaryLen( $dBinary ) Local $tBytes = DllStructCreate( "byte[" & $iSize & "]" ) DllStructSetData( $tBytes, 1, $dBinary ) Local $tStruct2 = DllStructCreate( $tagStruct, DllStructGetPtr( $tBytes ) ) MsgBox( 0, "Receiver: $tStruct2", _ "Struct Size: " & DllStructGetSize( $tStruct2 ) & @CRLF & _ "Struct pointer: " & DllStructGetPtr( $tStruct2 ) & @CRLF & _ "Data:" & @CRLF & _ " " & DllStructGetData( $tStruct2, "var1" ) & @CRLF & _ " " & DllStructGetData( $tStruct2, "var2" ) & @CRLF & _ " " & DllStructGetData( $tStruct2, "var3" ) & @CRLF & _ " " & DllStructGetData( $tStruct2, "var4" ) ) EndFunc The dictionary object is received by the Receiver() function and $tagStruct and $dBinary are extracted. Converting the Binary data back to a DllStruct is straightforward. The received data in $tStruct2 looks like this in a MsgBox: Struct Size: 140 Struct pointer: 0x00C80510 Data: -1 255 4294967295 hello AccVars_DllStructToBinary() AccVars_DllStructToBinary() is included in AccVars.au3, which is a mini version of Accessing AutoIt Variables UDF. The function is used to convert a DllStruct to Binary. Func AccVars_DllStructToBinary( ByRef $tStruct, ByRef $dBinary ) ; Convert $tStruct to a DllStruct of bytes Local $iSize = DllStructGetSize( $tStruct ) Local $tByteArray = DllStructCreate( "byte[" & $iSize & "]", DllStructGetPtr( $tStruct ) ) ; Create a safearray to store the $tByteArray struct Local $tsaBound = DllStructCreate( $tagSAFEARRAYBOUND ) DllStructSetData( $tsaBound, "cElements", $iSize ) ; Size of safearray = size of $tByteArray struct DllStructSetData( $tsaBound, "lLbound", 0 ) Local $pSafeArray = SafeArrayCreate( $VT_UI1, 1, $tsaBound ) ; $VT_UI1 = safearray of bytes ; Get access to safearray data Local $pArrayData, $tArrayData SafeArrayAccessData( $pSafeArray, $pArrayData ) ; Get access to safearray data through an AutoIt DllStruct $tArrayData = DllStructCreate( "byte[" & $iSize & "]", $pArrayData ) ; Store $tByteArray in the safearray data area DllStructSetData( $tArrayData, 1, DllStructGetData( $tByteArray, 1 ) ) ; Unaccess safearray data SafeArrayUnaccessData( $pSafeArray ) ; Convert the safearray to the native AutoIt binary data type AccessVariables02( AccVars_ByteArrayToBinary, $pSafeArray, $dBinary ) EndFunc Func AccVars_ByteArrayToBinary( $pvSafeArray, $pvBinary ) ; $pvSafeArray is a variant that contains a pointer to a safearray Local $pSafeArray = DllStructGetData( DllStructCreate( "ptr", $pvSafeArray + 8 ), 1 ) ; Set $pvBinary to match a standard COM bytearray. A standard ; COM bytearray is a safearray of bytes stored inside a variant. ; Set vt element to $VT_ARRAY + $VT_UI1 (safearray of bytes) DllStructSetData( DllStructCreate( "word", $pvBinary ), 1, $VT_ARRAY + $VT_UI1 ) ; Set data element to safearray pointer DllStructSetData( DllStructCreate( "ptr", $pvBinary + 8 ), 1, $pSafeArray ) ; On function exit, the standard COM bytearray is converted to the native AutoIt binary data type ; This conversion is performed by internal AutoIt functions implemented as compiled C/C++ code EndFunc AccessVariables02() is defined in AccVars.au3. The whole purpose of using the techniques of Accessing AutoIt Variables is to exploit the internal COM conversions implemented in compiled C/C++ code to do all the hard work. Alternatively, it's possible to make the same conversions in a loop in (slow) interpreted AutoIt code. The Variant and Safearray UDFs are copied directly from Variants and Safearrays. Large array In Examples\4) Large array\, an array of 250,000 rows and 10 columns is created and sent from Sender to Receiver. In the debug windows you can see how long each sub-task takes. At the Receiver, the array is displayed in a virtual ArrayDisplay. The array is created with the functions of Fast Array Sorting and Management Functions UDF. Although this example is mostly about compiled code, most functions are also implemented in pure AutoIt code. One of these functions, FAS_Random2DArrayAu3(), is used to create the array. The function is found in Examples\Data Display\Resources\. A few code lines have been added to generate progress bar information. Examples\8) Two concurrent data transfers\ is also about large arrays. Other examples5) Array of arrays\ and 6) Array of objects\ is about arrays with embedded data. You can also create an array of embedded DllStructs. But then the DllStructs must be converted to Binary before the array is sent from Sender to Receiver. Arrays in the examples are 1D and 2D arrays. But it can also be 3D and 4D arrays. All valid AutoIt arrays are likely to work. 7) Two way data transfer\ demonstrates how to implement two-way data transfer. 7z-fileThe 7z-file contains source code for the UDF and examples. You need AutoIt 3.3.12 or later. Tested on Windows 7 and Windows 10. Comments are welcome. Let me know if there are any issues. IPCviaROTobjects.7z
    1 point
×
×
  • Create New...