Yusuke
Members-
Posts
10 -
Joined
-
Last visited
Yusuke's Achievements
Seeker (1/7)
0
Reputation
-
Hi, Thanks for your answer. It doesn't seem to be behave as you say it is and as it is currently documented, though... which corresponds to my definition of a bug. ;-) From Child.Au3 from the reproducer. #include <IE.au3> Global $objIE = _IEAttach("Main Script", "embedded") MsgBox(64, "Message", "After _IEAttach") _IEBodyWriteHTML($objIE, "I am the Child Script !") Unless I am missing something, isn't it what I am doing already ? Actually, it does, even if it doesn't use explicitely the result in this case, it still chokes when the function is called... Func _IEAttach($s_string, $s_mode = "Title") $s_mode = StringLower($s_mode) Local $o_Shell = ObjCreate("Shell.Application") Local $o_ShellWindows = $o_Shell.Windows(); collection of all ShellWindows (IE and File Explorer) It crashes on the line below and doesn't execute code any further because of the error occuring at that line: Local $o_ShellWindows = $o_Shell.Windows(); collection of all ShellWindows (IE and File Explorer) As the Windows' collection isn't used when attaching to embedded IEs, then may I suggest you move the faulty line only before the For loop so it doesn't crash anymore for people using the embedded mode in this context. I did on my local file and it works fine, but it would be great if you could amend this so it stays that way in the next AutoIt releases and for people wanting to use it in the same context as me. May I suggest you amend the documentation page of the _IEAttach function to include this ? I agree that the GUIRunOnce situation is rare (but is frequent enough when you do unattended software deployments, which is what AutoIT was created for originally), but there are a lot of people around here that run with alternative shells. People creating AutoIT script using this feature would probably like it to behave fine in whatever shell is being used as it may result in strange bugs. You're the one to decide, but please think over it again : it doesn't happen in just a rare case. At any rate, if you only support explorer.exe as the Shell and require it running for some cases where the function is running, please state it in the documentation so it avoid confusion and misuses of this function. Thanks a lot.
-
Hi, I am using AutoIT to build a script launching an installation console running before the Shell (explorer.exe) has started (GUIRunOnce)... My main script creates an Embedded IE Window inside its own GUI to use as a console. Other scripts are launched from this main script and they reuse the IE Console created to print their own messages on it, using _IEAttach. While this work fine when the Shell (Explorer.exe) is running, it doesn't work when the Shell isn't running (I assume it also applies if the user uses alternative shells than explorer.exe like BlackBox or AstonShell). My IE Console is created but the child scripts can't attach to it. The error is get is : Actually, after some debugging, it looks like that _IEAttach has a problem on this line. Local $o_ShellWindows = $o_Shell.Windows (); collection of all ShellWindows (IE and File Explorer) I think that the o_Shell.Windows() method ( http://msdn2.microsoft.com/en-us/library/bb774107.aspx ) fails because the Shell is not running and hence the method can't find the windows that are children to the Shell. The collection is then reused in a loop that is crucial for the _IEAttach to run successfully. I think the solution is to use something else than Shell.Windows(), but I am not sure which... FindWindow API perhaps ? Is there a way for you to fix this function ? Reproduce Code attached. Reproduce Steps 1°) Open Archive in WinZip/WinRAR, etc... 2°) Kill all instances of Explorer.exe so it doesn't run anymore 3°) Launch Main.au3 4°) Launch Child.au3 Thanks in advance. -- Versions : AutoIt : 3.2.8.1 (fails with latest beta as well) IE.au3 Version: V2.3-1 Last Update: 8/13/07 Script used on WinXP SP2 (bug also happens on Windows Server 2003) Reproduce.zip
-
Well, after one night, I got the idea to make some benchmarking using the DllCall function and GetTickCount API function which returns the number of milliseconds since the system has started. By calling it twice at different spots and making the difference, you can roughly estimate how long a part of code takes to execute. I ran it on my message loop/GUIGetMsg loop and I got 0 ms with occasionnals 16 ms, which seems to indicate that the message loop isn't the culprit. I then ran it inside the _IEDocInsertHTML function of the IE3.au3 header and the results are surprising. Here is the code Func _IEDocInsertHTML(ByRef $o_object, $s_string, $s_where = "beforeend") Local $iTicksBegin = DllCall("kernel32.dll", "long", "GetTickCount") If Not IsObj($o_object) Then __IEErrorNotify("Error", "_IEDocInsertHTML", "$_IEStatus_InvalidDataType") SetError($_IEStatus_InvalidDataType, 1) Return 0 EndIf If Not __IEIsObjType($o_object, "browserdom") Or __IEIsObjType($o_object, "documentcontainer") Or __IEIsObjType($o_object, "document") Then __IEErrorNotify("Error", "_IEDocInsertHTML", "$_IEStatus_InvalidObjectType", "Expected document element") SetError($_IEStatus_InvalidObjectType, 1) Return 0 EndIf Local $iTicksEnd = DllCall("kernel32.dll", "long", "GetTickCount") FileWriteLine("ticks.txt", $iTicksEnd[0] - $iTicksBegin[0]) Local $iTicksBegin = DllCall("kernel32.dll", "long", "GetTickCount") $s_where = StringLower($s_where) Select Case $s_where = "beforebegin" $o_object.insertAdjacentHTML ($s_where, $s_string) SetError($_IEStatus_Success) Return 1 Case $s_where = "afterbegin" $o_object.insertAdjacentHTML ($s_where, $s_string) SetError($_IEStatus_Success) Return 1 Case $s_where = "beforeend" $o_object.insertAdjacentHTML ($s_where, $s_string) SetError($_IEStatus_Success) ; Local $iTicksEnd = DllCall("kernel32.dll", "long", "GetTickCount") ; FileWriteLine("ticks.txt", $iTicksEnd[0] - $iTicksBegin[0]) Return 1 Case $s_where = "afterend" $o_object.insertAdjacentHTML ($s_where, $s_string) SetError($_IEStatus_Success) Return 1 Case Else ; Unsupported Where __IEErrorNotify("Error", "_IEDocInsertHTML", "$_IEStatus_InvalidValue", "Invalid where value") SetError($_IEStatus_InvalidValue, 3) Return 0 EndSelect EndFunc ;==>_IEDocInsertHTML I've benchmarked two parts of this function, the first part being the part before the cases and then the one after. When running it from my child script, I guess these times (in milliseconds) for each call : First part (beginning of function up to Select) Second part of the code (Select -> beforeend) While the times on the second part of the function aren't stellar, the first part seems slow since this part for each call takes 1/3 of seconds (on a Dual Core 2.3 GHz). What's surprising, is that it only happens when running it from my second script. If run this function from the main script, I get 0 ms for most calls ! I'm very confused by this problem and it is really weird. I tried the same with a listbox (adding items from my second script to a listbox created from a "main" script) and the items get added quickly enough, so it seems to be related to the IE library. Can somebody please help ? Thanks in advance;
-
Hi, I have a main script with an embedded IE control. Code is like this : #include <GUIConstants.au3> #include <IE.au3> _IEErrorHandlerRegister () $oIE = _IECreateEmbedded () $Gui = GUICreate("Embedded Web control Test", 640, 580, _ (@DesktopWidth - 640) / 2, (@DesktopHeight - 580) / 2, _ $WS_OVERLAPPEDWINDOW + $WS_VISIBLE + $WS_CLIPSIBLINGS) $GUIActiveX = GUICtrlCreateObj($oIE, 0, 10, 640, 360) $GUI_Button_Back = GUICtrlCreateButton("Back", 10, 420, 100, 30) $GUI_Button_Forward = GUICtrlCreateButton("Forward", 120, 420, 100, 30) $GUI_Button_Home = GUICtrlCreateButton("Home", 230, 420, 100, 30) $GUI_Button_Stop = GUICtrlCreateButton("Stop", 340, 420, 100, 30) GUICtrlSetResizing($GUIActiveX, $GUI_DOCKTOP) GUISetState() ;Show GUI _IENavigate ($oIE, "about:blank") ; Waiting for user to close the window While 1 $msg = GUIGetMsg() Select Case $msg = $GUI_EVENT_CLOSE ExitLoop Case $msg = $GUI_Button_Home _IENavigate ($oIE, "about:blank") Case $msg = $GUI_Button_Back $oBody = _IETagNameGetCollection($oIE, "body", 0) Local $i For $i = 0 To 10 _IEDocInsertHTML($oBody, "<b>Hello</b><br>") Next $iVisibleHeight = $oIE.document.body.clientHeight $oIE.document.parentwindow.scrollBy(0,$iVisibleHeight) Case $msg = $GUI_Button_Forward _IEAction ($oIE, "forward") MsgBox(64, "Test", _IEDocReadHTML($oIE)) Case $msg = $GUI_Button_Stop _IEAction ($oIE, "stop") EndSelect WEnd GUIDelete() Exit If you click the back button, it will write then times "Hello" in bold. So far, no problem and it does this quickly. Now, I need a second script to interact with the GUI of the main script, and write things to the IE control of this window (I plan to use IE like a console and display logs stuff in there). Code of this second script is like this : #include <IE.au3> $oIE = _IEAttach("Embedded Web control Test", "embedded") ;$oIE = _IEAttach("about:blank", "embedded") $oBody = _IETagNameGetCollection($oIE, "body", 0) Local $i For $i = 0 To 10 _IEDocInsertHTML($oBody, "<b>Hello</b><br>") Next Which is supposed to write Hello ten times to the IE control in main window if you run them side by side, which it indeed does. The problem is that the insertions made by the second script are very slow while the ones made on the main script are instantaneous. I thought it was something with the IE.au3 library perhaps, like a parameter to set, but after having checked the source code, I couldn't find anything strange. I used the second script against a real IE window that I first navigated manually to about:blank, and there the insertions were instantaneous. So, I wonder if the problem doesn't come from the message loop which may be not fast enough and may be why the insertions seem slow. Can you confirm it is so ? I am rather new to AutoIt (I did some C/Win32 in the past though) and do not know it is limitations yet. And if so, how can I speed it up. Event Mode GUI seems even worse. Any trick or advice is very welcome. Thanks in advance.
-
Thanks everyone. To explain a bit more what I wanted to do, I have a main GUI in a script that runs other scripts in subdirectories (the main script looks for *.au3 and launch them) and I wanted these child script to communicate with the GUI, and mostly an embedded IE Control. I have seen _IEAttach which allows me to get the object of the IE in my main window, so that's not too bad and will use that for now. It is a pity though that the Execute function is so limited.... VBScript's ExecuteGlobal was great for that. It is really handy to be able to access all the variables from the parent script from a child script without setting up WM_COPYDATA or TCP client/server. Just out of curiousity, anybody knows the reason for the Execute function to be so limited ? Security, I guess ?
-
Thanks, but sorry, it is not exactly what I want : I know how to run another script, but what I would like to know if it is possible to to launch a child script and that this script can access the variables and functions of the parent script.
-
Hi, Is there a way to launch an AutoIt script from another AutoIt script but that the child script can access the variables of the parent script ? Basically, I'm looking for something similar to the CALL command in batch scripting. VBScript also had something similar with ExecuteGlobal and I was happy with it, but I'm looking to completely switch to AutoIt now. Execute isn't what I want since it severely limits the usefulness of the child scripts. Thanks a lot in advance.
-
Sorry, I fixed my problem myself. Please can someone delete this ?
-
Hi, First, thanks to PaulIA for this great and powerful lib. I am using the Event Logs functions to clear the event log and have a little problem when I don't want to backup the event log. The library documentation says this in regard to _EventLog_Clear's parameters : What does "blank" mean in this context ? I assumed it was meaning an empty string like this "" as in many other languages. I am right about it being the same in AutoIt ? When I pass such a blank string, the function doesn't work and the event log isn't cleared, but if I supply a valid filename, it works fine, but I don't want to make any backup of my event log when calling this function. So, I've looked at the function implementation and the code is this : ; #FUNCTION# ==================================================================================================== ================ ; Description ...: Clears the event log ; Parameters ....: $hEventLog - Handle to the event log ; $sFileName - The name of the backup file. If the name is blank, the current event log is not backed up. ; Return values .: Success - True ; Failure - False ; Author ........: Paul Campbell (PaulIA) ; Remarks .......: This function fails if the event log is empty or a file already exists with the same name as sFileName. After ; this function returns, any handles that reference the cleared event log cannot be used to read the log. ; Related .......: _EventLog_Open ; ==================================================================================================== =========================== Func _EventLog_Clear($hEventLog, $sFileName) Local $aResult $aResult = DllCall("AdvAPI32.dll", "int", "ClearEventLogA", "hwnd", $hEventLog, "str", $sFileName) Return SetError($aResult[0], 0, $aResult[0]<>0) EndFunc The MSDN function reference for the ClearEventLog functions states this : The backup parameter is expecting a NULL when we do not want to backup the event log before clearing it, but the Auto3Lib function seems to be passing a pointer to an empty string, hence not NULL. If I amend the AutoIT implementation like this (change last parameter type from str to int so I can pass a 0 (NULL) to it) : Func _EventLog_Clear($hEventLog, $sFileName) Local $aResult $aResult = DllCall("AdvAPI32.dll", "int", "ClearEventLogA", "hwnd", $hEventLog, "int", $sFileName) Return SetError($aResult[0], 0, $aResult[0]<>0) EndFunc and call it like this $hEventLog = _EventLog_Open("", "Application") _EventLog_Clear($hEventLog, 0) _EventLog_Close($hEventLog) then it works fine without doing any backup. I could amend the function to check whether the backup filename string is empty and use the first DllCall or the second version of it depending on its value, but maybe there is a better way (I only really started using AutoIt yesterday) and if there is a bug, I think that everyone would like to get the fixed version, hence my post. That said, maybe I didn't understand how this function should be called and doing a mistake somewhere ? Thanks a lot in advance and keep up the good work, Yusuke.