guillermoares Posted July 20, 2012 Share Posted July 20, 2012 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 expandcollapse popup; 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! Link to comment Share on other sites More sharing options...
guillermoares Posted July 20, 2012 Author Share Posted July 20, 2012 Up! Link to comment Share on other sites More sharing options...
Moderators JLogan3o13 Posted July 20, 2012 Moderators Share Posted July 20, 2012 guillermoares, please don't bump your threads in less than 24 hours. That gives us all plenty of time to research your issue and try to assist "Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball How to get your question answered on this forum! Link to comment Share on other sites More sharing options...
BrewManNH Posted July 20, 2012 Share Posted July 20, 2012 What EXACTLY do you mean by this part?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. Are you running this as an x64 executable in an x86 OS? Because that just won't ever work. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator Link to comment Share on other sites More sharing options...
guillermoares Posted July 20, 2012 Author Share Posted July 20, 2012 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. Link to comment Share on other sites More sharing options...
BrewManNH Posted July 20, 2012 Share Posted July 20, 2012 I can't duplicate the crash issues, I compiled as both an x64 and an x86 executable and both ran without a problem. I also ran it from SciTE in both modes and it worked there as well. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator Link to comment Share on other sites More sharing options...
guillermoares Posted July 20, 2012 Author Share Posted July 20, 2012 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"). Link to comment Share on other sites More sharing options...
BrewManNH Posted July 20, 2012 Share Posted July 20, 2012 (edited) Windows 7 x64 here, it gets the File menu regardless of which program is running. If I run the code from SciTE, it gets the File menu in SciTE, if I'm running the executable from Windows Explorer it opens the File menu in that program. Also, if I run either of the executables from the console in SciTE, it opens the file menu in Scite. EDIT: English version of Windows BTW. Edited July 20, 2012 by BrewManNH If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator Link to comment Share on other sites More sharing options...
guillermoares Posted July 20, 2012 Author Share Posted July 20, 2012 Well, I guess I'll try to reproduce this in an english environment and come back if I have any luck. Thanks! Link to comment Share on other sites More sharing options...
guillermoares Posted July 23, 2012 Author Share Posted July 23, 2012 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: expandcollapse popup; 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! 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