Sundance Posted October 21, 2013 Share Posted October 21, 2013 (edited) Hi all, after some month it's time for another problem that arises bevore my eyes... I try to explain it in short sentences: Script1 (S1) opens a DLL and call some functions inside it. Then S1 executes another Script (S2). S1 writes the DllOpen handle into a INI file. S2 now also needs to call some functions inside the same DLL using the same handle S1 got when calling OpenDLL. Problem: The DllCall within S2 fails with @error = 1 => unable to use the DLL file. It seems that S2 can't use the handle created from S1. I tried to start S2 from S1 with the help of _WinApi_CreateProcess and setting the $fInherit flag to true but it won't help. Local $tProcess = DllStructCreate($tagPROCESS_INFORMATION) Local $tStartup = DllStructCreate($tagSTARTUPINFO) DllStructSetData($tStartup, "Size", DllStructGetSize($tStartup)) _ WinAPI_CreateProcess("", '"' & @ScriptDir & 'Some.exe" ' & $sParameters, 0, 0, True, 0, 0, "", DllStructGetPtr($tStartup), DllStructGetPtr($tProcess)) In C languages it is possible to use handles given from other (parent) executables. So in AutoIt it surely is also possible but i haven't found the place where to dig... Has someone a little hint for me? thanks in advance Sundance Edited October 21, 2013 by Sundance Link to comment Share on other sites More sharing options...
JohnOne Posted October 21, 2013 Share Posted October 21, 2013 I'm not sure you can do what you're asking, but only half the code (Parent) will not help anyone to debug your problem if you can. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
jchd Posted October 21, 2013 Share Posted October 21, 2013 Why do you think you need to pass a dll handle in the first place? Don't confuse a Dll handle and a file handle (which indeed can be passed to children). This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
Sundance Posted October 21, 2013 Author Share Posted October 21, 2013 (edited) Hi John, thanks for a reply. The whole source code is to long to post and the problem is only a fragment of it. I surely could create a testscript but i thougth that someone knows if its possible to make a DllCall from script Y which where called by script X which already has opened the Dll. So its best to forget the lines of code i posted. Here are to scripts which show what i mean. expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Change2CUI=y #AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.8.0 Author: myName Script Function: Template AutoIt script. #ce ---------------------------------------------------------------------------- #include <WinApi.au3> #include "_DLLFunctions.au3" ; Script Start - Add your code below here Local $hDll = DllOpen("user32.dll") Local $sINIread Local $hLibraryHandle = _DLL_GetLoadedLibraryHandle("user32.dll") _DLL_ForcePermanentLoad("user32.dll") Local $tProcess = DllStructCreate($tagPROCESS_INFORMATION) Local $tStartup = DllStructCreate($tagSTARTUPINFO) DllStructSetData($tStartup, "Size", DllStructGetSize($tStartup)) ; delete old INIfile If FileExists(@ScriptDir & "\dlltest.ini") Then FileDelete(@ScriptDir & "\dlltest.ini") EndIf ; writing the DLL handle to the INI so script2 can read the handle IniWrite(@ScriptDir & "\dlltest.ini", "COMMON", "HANDLE", $hLibraryHandle) ; consoleoutput ConsoleWrite(@CRLF & "--------------------------------------------------------------------------------" & @CRLF) ConsoleWrite(@ScriptName & ": handle from DllOpen : " & $hDll & @CRLF) ConsoleWrite(@ScriptName & ": handle from getLoadedLibrary: " & $hLibraryHandle & @CRLF) $bResult = _WinAPI_CreateProcess("", '"' & @ScriptDir & '\script2.exe"', 0, 0, True, 0, 0, "", DllStructGetPtr($tStartup), DllStructGetPtr($tProcess)) If Not $bResult Then ConsoleWrite(@ScriptName & ": " & "error creating process script2.exe! Exiting..." & @CRLF) Exit EndIf ConsoleWrite(@ScriptName & ": " & "created process script2.exe" & @CRLF) $sINIread = "error" While $sINIread = "error" $sINIread = IniRead(@ScriptDir & "\dlltest.ini", "COMMON", "EXITED","error") Sleep(500) WEnd ConsoleWrite(@CRLF & "--------------------------------------------------------------------------------" & @CRLF) ConsoleWrite(@CRLF) DllClose($hDll) #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Change2CUI=y #AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.8.0 Author: myName Script Function: Template AutoIt script. #ce ---------------------------------------------------------------------------- ; Script Start - Add your code below here Local $result Local $hDll = IniRead(@ScriptDir & "\dlltest.ini", "COMMON", "HANDLE", "error") If $hDll = "error" Then ConsoleWrite(@ScriptName & ": error reading Dll handle from INI file. Exiting..." & @CRLF) Else ConsoleWrite(@CRLF & @ScriptName & ": read handle value from INI: " & $hDll & @CRLF) EndIf ; now call the DLL $result = DllCall($hDll , "int", "MessageBox", "hwnd", 0, "str", "DllCall", "str", "using parent Dll handle", "int", 0) ConsoleWrite(@CRLF & @ScriptName & ": " & "DllCall finished with @error value of " & @error & @CRLF & @CRLF) IniWrite(@ScriptDir & "\dlltest.ini", "COMMON", "EXITED","finished") Exit Put both scripts in a directory, compile script2 and run script1. Hope that explains it better. @jchd: I don't need a file handle its really a Dll handle :-) EDIT: 22.10: added Ascend4nt's Dll functions au3. The Dlls are part of a bigger project and programmed by someone else. But i see the problem is not an easyy one. Will also further think about a possible solution... thanks guys Sundance Edited October 22, 2013 by Sundance Link to comment Share on other sites More sharing options...
KaFu Posted October 21, 2013 Share Posted October 21, 2013 Did you check the value of the dll "handle" written to the ini file? I think the quotation marks are there for a reason in the help-file article for dllopen(). I'm not quite sure, but I think the dll-handle stuff is done in the background and not really user accessible in AutoIt, maybe worth a question in the Dev-Chat ? OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2022-Nov-26) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Feb-16) HMW - Hide my Windows (2018-Sep-16) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2023-Jun-03) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
Sundance Posted October 21, 2013 Author Share Posted October 21, 2013 Hi KaFu, i tried it with INT($hDll) and creating a Dll structure using it within the DllCall but the error stays the same. I will use those two scripts to try it again. If i can't find a solution i will go to the Dev-Chat. The only thing i know is that our programmer who wrote the DLLs says in C++ it no prob. I will report back. Thanks guys. Sundance PS: if someone can bring some light into it i still would be happy :-) Link to comment Share on other sites More sharing options...
trancexx Posted October 21, 2013 Share Posted October 21, 2013 Fire your programmer then. Dll is loaded in memory space of the process. Two different processes have two separated memory spaces. One process can't use dll-s of the other process, it has to load them for itself. That's the whole point of dlls. ♡♡♡ . eMyvnE Link to comment Share on other sites More sharing options...
funkey Posted October 22, 2013 Share Posted October 22, 2013 AutoIt hides the real DLL handle. DllOpen just returnes an integer to work with. Sometimes it would be nice, when AutoIt does not hide things from you. Same thing with FileOpen. Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
Sundance Posted October 22, 2013 Author Share Posted October 22, 2013 (edited) Hi trance, your statement was also my opinion . Can be that the programmer doesn't know the limitations of AutoIt (threads, multitasking,...). I took a look at Ascend4nt's Process_Create_Thread functions but i think that won't do the trick. Ascend4nt uses a binary string as a representation of code. I would need to convert a au3 script into this binary representation (au3->exe->string). I know there is a possibility of running an au3 script as a string representation. I did that ~3 years ago. I will take a look and see if i can use this in combination with Ascend4nt's Thread functions. Edited October 22, 2013 by Sundance Link to comment Share on other sites More sharing options...
Sundance Posted October 22, 2013 Author Share Posted October 22, 2013 (edited) Just a short info funkey. You can use Ascend4nt's Dllfunctions au3 to get the handle of a opened DLL. But using the 'real' Dll handle obviously won't bring me any further. Digging more... :-) Edited October 22, 2013 by Sundance Link to comment Share on other sites More sharing options...
JohnOne Posted October 22, 2013 Share Posted October 22, 2013 Perhaps if you outlined your endgame, some suggestions might arise. At the moment, only info is that you want/need to do this. If it's not a secret, can you explain why you want to do this? I'm struggling to think of one. AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
Sundance Posted October 22, 2013 Author Share Posted October 22, 2013 The problem is that we need to call the DLL several times with a function in it which calls a CallBack function in the au3 file. The DllCall won't return and continuously calls the CallBack function so that the CallBack function can write infos to some INI files. So we need to make this DllCall from outside the main script cause the main script needs to run further. Like calling a Run command ... Our programmer says that its essential that the DLL only will be called once. Seems he creates some data structures within the DLL. I think i need to ask him how we can prevent that issue. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now