Advert
guillermoares
Members-
Posts
9 -
Joined
-
Last visited
guillermoares's Achievements
Seeker (1/7)
0
Reputation
-
AutoIT x64 problem
guillermoares replied to guillermoares's topic in AutoIt General Help and Support
Found the solution! I was having a buffer overrun when calling GetMenuString. Apparently it only caused trouble with some spanish string... Here's the corrected code, for posterity: ; Usage example: ConsoleWriteLine(GetHotkeyFromResource("C:\\Windows\\System32\\ieframe.dll", 334, 41025)) ; ================= Main functions ==================== Func GetHotkeyFromResource($dllPath, $menuId, $stringId) Local $string = GetStringFromResource($dllPath, $menuId, $stringId) Local $charArray = StringSplit($string, "") For $n = 1 To $charArray[0] If $charArray[$n] = chr(38) Then return $charArray[$n + 1] EndIf Next EndFunc Func GetStringFromResource($dllPath, $menuId, $stringId) Local $ieframeHandle = LoadLibraryEx($dllPath) Local $menuHandle = LoadMenu($ieframeHandle, $menuId) Local $stringLength = GetMenuStringLength($menuHandle, $stringId) return GetMenuString($menuHandle, $stringId, $stringLength) EndFunc ; ================= kernel32.dll functions ==================== Func LoadLibraryEx($muiPath) Local $result = DllCall("kernel32.dll", "ptr", "LoadLibraryEx", "str", $muiPath, "ptr", 0, "UINT", 0x2) CheckDllCallError("LoadLibraryEx") Return $result[0] EndFunc Func GetLastError() Local $GetLastError = DllCall("kernel32.dll", "long", "GetLastError") CheckDllCallError("GetLastError") Return $GetLastError[0] EndFunc ;==>_WinAPI_GetLastErrorEx ; ================= user32.dll functions ==================== Func LoadMenu($dllHandle, $menuID) Local $result = DllCall("user32.dll", "ptr", "LoadMenu", "ptr", $dllHandle, "int", $menuID) CheckDLLCallError("LoadMenu") Return $result[0] EndFunc Func GetMenuStringLength($menuHandle, $itemID) Local $result = DllCall("user32.dll", "int", "GetMenuStringW", "ptr", $menuHandle, "UINT", $itemID, "ptr", 0, "int", 0, "UINT", 0) CheckDllCallError("GetMenuStringLength") return $result[0] EndFunc Func GetMenuString($menuHandle, $itemID, $stringLength) $result = DllCall("user32.dll", "int", "GetMenuStringW", "ptr", $menuHandle, "UINT", $itemID, "wstr", "", "int", 10000, "UINT", 0) return $result[3] EndFunc ; ================= Utils ==================== Func PrintLastError() ConsoleWriteLine("LastError: " & Hex(GetLastError())) EndFunc Func ConsoleWriteLine($text) ConsoleWrite($text & @CRLF) EndFunc Func ConsoleWriteIfNull($var, $message) If not $var Then ConsoleWriteLine($message) EndIf EndFunc Func CheckDLLCallError($functionName) Switch @error Case 0 ;ConsoleWriteLine("DLL call successful") ;GetLastError() Case 1 ConsoleWriteLine("Status for " & $functionName & ": Unable to use the DLL file") GetLastError() Exit Case 2 ConsoleWriteLine("Status for " & $functionName & ": Unknown return type") GetLastError() Exit Case 3 ConsoleWriteLine("Status for " & $functionName & ": Function not found in the DLL file") GetLastError() Exit Case 4 ConsoleWriteLine("Status for " & $functionName & ": Bad number of parameters") GetLastError() Exit Case 5 ConsoleWriteLine("Status for " & $functionName & ": Bad parameter") GetLastError() Exit Case Else EndSwitch Thanks again! -
AutoIT x64 problem
guillermoares replied to guillermoares's topic in AutoIt General Help and Support
Well, I guess I'll try to reproduce this in an english environment and come back if I have any luck. Thanks! -
AutoIT x64 problem
guillermoares replied to guillermoares's topic in AutoIt General Help and Support
Hmmm... weird. The exact environment is Windows 7 Ultimate SP1 x64 in spanish. Probably you are not testing on a spanish OS, but... is there any other difference between our environments? Also, is it working fine? My code is supposed to get the hotkey regardless of the program/OS language. The example code I posted gets the hotkey for the "File" menu in Internet Explorer 9, so in an english version of IE you should get "F" and in a spanish version you should get "A" ("File" = "Archivo"). -
AutoIT x64 problem
guillermoares replied to guillermoares's topic in AutoIt General Help and Support
Ooops... No, I'm running my tests on an x64 environment. My bad. Just to be sure... When I say "Running the script in x86/x64 mode[...]" I'm referring to the "Run script (x86)" and "Run script (x64)" options displayed when right-clicking on an AutoIT script. -
AutoIT x64 problem
guillermoares replied to guillermoares's topic in AutoIt General Help and Support
Up! -
Hi! I wrote an AutoIT which is supposed to get a hotkey from a .dll resource file and use it. It seems to run fine in an x86 environment, but i'm having problems in an x64 one. This is the behavior I noticed: (always in an x86 environment) 1 - Running the script in x86 mode makes AutoIT crash. 2 - Running the script in x64 mode works fine. 3 - Compiling the script as an x64 executable and then running the executable makes AutoIT crash. Here's the code: #include <ResourceStrings.au3> Global $ieframeDll = "C:\\Windows\\System32\\ieframe.dll" Global $Ctrl = "^" Global $Alt = "!" OpenFileMenu() Func OpenFileMenu() Local $k = GetHotkeyFromResource($ieframeDll, 267, 32768) ConsoleWriteLine($k) Local $keys = $Alt & $k Send($keys) EndFunc ; Usage example: ;ConsoleWriteLine(GetHotkeyFromResource("C:\\Windows\\System32\\ieframe.dll", 334, 41025)) ; ================= Main functions ==================== Func GetHotkeyFromResource($dllPath, $menuId, $stringId) Local $string = GetStringFromResource($dllPath, $menuId, $stringId) Local $charArray = StringSplit($string, "") For $n = 1 To $charArray[0] If $charArray[$n] = chr(38) Then return $charArray[$n + 1] EndIf Next EndFunc Func GetStringFromResource($dllPath, $menuId, $stringId) Local $ieframeHandle = LoadLibraryEx($dllPath) Local $menuHandle = LoadMenu($ieframeHandle, $menuId) Local $stringLength = GetMenuStringLength($menuHandle, $stringId) return GetMenuString($menuHandle, $stringId, $stringLength) EndFunc ; ================= kernel32.dll functions ==================== Func LoadLibraryEx($muiPath) Local $result = DllCall("kernel32.dll", "ptr", "LoadLibraryEx", "str", $muiPath, "ptr", 0, "UINT", 0x2) CheckDllCallError("LoadLibraryEx") Return $result[0] EndFunc Func GetLastError() Local $GetLastError = DllCall("kernel32.dll", "long", "GetLastError") CheckDllCallError("GetLastError") Return $GetLastError[0] EndFunc ;==>_WinAPI_GetLastErrorEx ; ================= user32.dll functions ==================== Func LoadMenu($dllHandle, $menuID) Local $result = DllCall("user32.dll", "ptr", "LoadMenu", "ptr", $dllHandle, "int", $menuID) CheckDLLCallError("LoadMenu") Return $result[0] EndFunc Func GetMenuStringLength($menuHandle, $itemID) Local $result = DllCall("user32.dll", "int", "GetMenuString", "ptr", $menuHandle, "UINT", $itemID, "ptr", 0, "int", 0, "UINT", 0) CheckDllCallError("GetMenuStringLength") return $result[0] EndFunc Func GetMenuString($menuHandle, $itemID, $stringLength) Local $str = "char msgArray[" & $stringLength & "]" Local $dllStruct = DllStructCreate($str) Local $msgBufferSize = DllStructGetSize($dllStruct) Local $msgBufferPtr = DllStructGetPtr($dllStruct) $result = DllCall("user32.dll", "int", "GetMenuString", "ptr", $menuHandle, "UINT", $itemID, "ptr", $msgBufferPtr, "int", $stringLength + 1, "UINT", 0) CheckDllCallError("GetMenuString") return DllStructGetData($dllStruct, 1) EndFunc ; ================= Utils ==================== Func PrintLastError() ConsoleWriteLine("LastError: " & Hex(GetLastError())) EndFunc Func ConsoleWriteLine($text) ConsoleWrite($text & @CRLF) EndFunc Func ConsoleWriteIfNull($var, $message) If not $var Then ConsoleWriteLine($message) EndIf EndFunc Func CheckDLLCallError($functionName) Switch @error Case 0 ;ConsoleWriteLine("DLL call successful") ;GetLastError() Case 1 ConsoleWriteLine("Status for " & $functionName & ": Unable to use the DLL file") GetLastError() Exit Case 2 ConsoleWriteLine("Status for " & $functionName & ": Unknown return type") GetLastError() Exit Case 3 ConsoleWriteLine("Status for " & $functionName & ": Function not found in the DLL file") GetLastError() Exit Case 4 ConsoleWriteLine("Status for " & $functionName & ": Bad number of parameters") GetLastError() Exit Case 5 ConsoleWriteLine("Status for " & $functionName & ": Bad parameter") GetLastError() Exit Case Else EndSwitch EndFunc Also, when combined with other code (which is very long therefore I will not post it unless required...), the script crashes even in x64 mode. I think that solving the above issue will probably enough to fix this one too. Thanks in advance!
-
Problems with DllCall function
guillermoares replied to guillermoares's topic in AutoIt General Help and Support
Bump. -
Problems with DllCall function
guillermoares replied to guillermoares's topic in AutoIt General Help and Support
We are making test scripts for IE9. The company in which I'm working is making compatibility layers for different versions of IE (i.e. these layers could let you run IE6 in Windows 7). We were also asked to ship a (weak) test suit in AutoIT. These test suit should try every possibility that the IE UI gives (i.e. Try doing File -> open, Try doing Edit -> Select all, etc, etc, etc). I'm using the hotkeys to simulate these user inputs. You're right about that function. I'm pretty lost messing around with the Windows API . Anyway, I can't figure out how to translate the (darn confusing) data types I see in the WinAPI documentation to the data types specified in the DllCall function documentation. Also, yes, I know that the arguments I used in the code for the LoadAccelerators are obviously wrong and will never ever work... I tried several other things before, that was just testing. -
Hi! I'm building some automated tests for Internet Explorer 9 with AutoIT. I'm currently using keyboard shortcuts to control IE9, but I need these tests to run under any language. Since the shortcuts vary through different languages, I'm trying not to hardcode the key combinations but to take them from the IE9 .mui (internationalization) files. The file I'm trying to use right now is ieframe.dll.mui (which is under %windows%\%system32%\En-us). Supposedly, I should be able to get the information I want from this file using Windows API functions such as LoadAccelerators (MSDN). I'm not very C nor C++ experienced, so I'm having trouble both with the Windows API and with the AutoIT function DllCall. This what I have so far: Global $kernel32 = OpenDll("kernel32.dll") Global $user32 = OpenDll("user32.dll") Global $ieframe = OpenDll("ieframe.dll") Local $accelerators = LoadAccelerators($ieframe, "") ConsoleWrite($accelerators & @LF) ; ================= user32.dll functions ==================== Func LoadAccelerators($moduleHandle, $acceleratorTable) Local $result = DllCall($user32, "HANDLE", "LoadAccelerators", "HANDLE", $moduleHandle, "str", $acceleratorTable) CheckDllCallError(@error) ConsoleWriteIfNull($result, "The accelerator is null") Return $result EndFunc ; ================= kernel32.dll functions ==================== Func FindResource($moduleHandle, $resourceId, $resourceType) Local $result = DllCall($kernel32, "HANDLE", "FindResource", "HANDLE", $moduleHandle, "int", $resourceId, "int", $resourceType) CheckDLLCallError(@error) ConsoleWriteIfNull($result, "The resource handle is null") Return $result EndFunc Func LoadResource($moduleHandle, $resourceHandle) Local $result = DllCall($kernel32, "HANDLE", "LoadResource", "HANDLE", $ieframe, "HANDLE", $resourceHandle) CheckDLLCallError(@error) ConsoleWriteIfNull($resource, "The resource is null") Return $result EndFunc ; ================= Utils ==================== Func ConsoleWriteIfNull($var, $message) If not $var Then ConsoleWriteError($message & @LF) EndIf EndFunc Func CheckDLLCallError($error) Switch $error Case 1 ConsoleWriteError("Unable to use the DLL file" & @LF) Case 2 ConsoleWriteError("Unknown return type" & @LF) Case 3 ConsoleWriteError("Function not found in the DLL file" & @LF) Case 4 ConsoleWriteError("Bad number of parameters" & @LF) Case 5 ConsoleWriteError("Bad parameter" & @LF) Case Else EndSwitch EndFunc Func OpenDll($dllName) Local $dll = DllOpen($dllName) If ($dll = -1) Then ConsoleWriteError("Could not load " & $dllName & @LF) EndIf Return $dll EndFunc It seems that LoadAccelerators is returning a null value. I guess that I'm not passing the right argument/argument types, but I already tried several things to no avail. Any help would be appreciated!