zeshrek Posted February 2, 2011 Posted February 2, 2011 Hello everybodyI want to use text files to store datas for a script I make.So i created a first file, called FILE0.TXT containing the following lines :File0 line1 File0 Line2Then I created a second file called FILE1.TXT containing the following lines :File1 line1 File1 Line2Then I created a DLL (see attached file) containing 2 RCDATA named FILE0 and FILE1.Then I created the following script :#include "resources.au3" $text=_ResourceGetAsString("FILE0", $RT_RCDATA, 1033, "AsciiFiles.dll") ConsoleWrite(@crlf&$text&@CRLF&@CRLF)My problem is that when I run this script I get a Windows error message saying Autoit crashed and must be closed.I tryed to replace "1033" with zero or $ResLang, without success.Can someone tell me what I did wrong ?AsciiFiles.dll
Zedna Posted February 2, 2011 Author Posted February 2, 2011 (edited) #include "resources.au3" $text=_ResourceGetAsString("FILE0", $RT_RCDATA, 1033, "AsciiFiles.dll") ConsoleWrite(@crlf&$text&@CRLF&@CRLF) My problem is that when I run this script I get a Windows error message saying Autoit crashed and must be closed. I tryed to replace "1033" with zero or $ResLang, without success. With your DLL it crashed on my WIN XP too. I don't know why. You can include TXT files directly to EXE without any problems. This works OK: #AutoIt3Wrapper_Res_File_Add=FILE0.TXT, rt_rcdata, FILE0 #AutoIt3Wrapper_Res_File_Add=FILE1.TXT, rt_rcdata, FILE1 #include "resources.au3" $text=_ResourceGetAsString("FILE0") MsgBox(0,'',$text) EDIT: How exactly did you compile your DLL? EDIT2:Â I tried it also with modified UDF using _WinAPI_LoadLibraryEx($DLL, $LOAD_LIBRARY_AS_DATAFILE) instead of _WinAPI_LoadLibrary($DLL) with the same result Edited February 2, 2011 by Zedna Resources UDF Â ResourcesEx UDF Â AutoIt Forum Search
zeshrek Posted February 3, 2011 Posted February 3, 2011 Hi Zedna,Thank you for investigating on this problem.So Yes, I know I can include files in the EXE, and i will do it if I have no other solution.ButI want to minimize memory occupation of my script, and the resource file will embed things like image & icon sets for themes, translations sets (FR/EN/DE/IT & SP)... etc witch are not all required together at the same time. The idea is to have them stored in one resource file instead of several files, and to pick the set chosen by user (theme & language).To your EDIT :I tryed 2 solutions to build my DLL. I first tryed with Visual Basic 2010 Express, then I tryed a utility called RDG issued by Tlem (Admin of Autoit French forum) (I think I joined this last one, but the result was the same with both)To your EDIT2 :It's a bit weird, isn't it ? This UDF works perfectly with icons, bitmap, sound...etc and not with something as basic as text.Do you expect a positive issue or sould i start thinking about including files in my script, or keep them around the EXE in a (sub) folder ?
Zedna Posted February 3, 2011 Author Posted February 3, 2011 (edited) I identified where is problem, but I don't know why is it and how to overcome this. In _ResourceGetAsString() it crashes on DllStructGetData($struct, 1) My UDF loads resource and gets pointer to that reource memory. Then it creates structure over that memory and get data from structure. Maybe we need to apply the same princip as In GDI+ sections (_ResourceGetAsImage), there is allocated/copied memory instead of direct access to resource memory. I will try this if it helps. EDIT: doesn't help Func _ResourceGetAsString($ResName, $ResType = 10, $ResLang = 0, $DLL = -1) ; $RT_RCDATA = 10 Local $ResPointer, $ResSize, $struct $ResPointer = _ResourceGet($ResName, $ResType, $ResLang, $DLL) If @error Then SetError(1, 0, 0) Return '' EndIf $ResSize = @extended $hData = _MemGlobalAlloc($ResSize,2) $pData = _MemGlobalLock($hData) _MemMoveMemory($ResPointer,$pData,$ResSize) _MemGlobalUnlock($hData) $struct = DllStructCreate("char[" & $ResSize & "]", $pData) ;~ $struct = DllStructCreate("char[" & $ResSize & "]", $ResPointer) Return DllStructGetData($struct, 1) ; returns string EndFunc Edited February 3, 2011 by Zedna Resources UDF  ResourcesEx UDF  AutoIt Forum Search
Tlem Posted February 4, 2011 Posted February 4, 2011 It work with this old version of _ResourcesGet() : expandcollapse popupFunc _ResourceGet($ResName, $ResType = 10, $ResLang = 0, $DLL = -1) ; $RT_RCDATA = 10 Local Const $IMAGE_BITMAP = 0 Local $hInstance, $hBitmap, $InfoBlock, $GlobalMemoryBlock, $MemoryPointer, $ResSize If $DLL = -1 Then $hInstance = DllCall("kernel32.dll", "int", "GetModuleHandleA", "int", 0) Else $hInstance = DllCall("kernel32.dll", "int", "LoadLibrary", "str", $DLL) EndIf $hInstance = $hInstance[0] If $hInstance = 0 Then Return SetError(1, 0, 0) If $ResType = $RT_BITMAP Then $hBitmap = DllCall("user32.dll", "hwnd", "LoadImage", "hwnd", $hInstance, "str", $ResName, _ "int", $IMAGE_BITMAP, "int", 0, "int", 0, "int", 0) If @error Then Return SetError(2, 0, 0) $hBitmap = $hBitmap[0] Return $hBitmap ; returns handle to Bitmap EndIf If $ResLang <> 0 Then $InfoBlock = DllCall("kernel32.dll", "int", "FindResourceExA", "int", $hInstance, "long", $ResType, "str", $ResName, "short", $ResLang) Else $InfoBlock = DllCall("kernel32.dll", "int", "FindResourceA", "int", $hInstance, "str", $ResName, "long", $ResType) EndIf If @error Then Return SetError(3, 0, 0) $InfoBlock = $InfoBlock[0] If $InfoBlock = 0 Then Return SetError(4, 0, 0) $ResSize = DllCall("kernel32.dll", "dword", "SizeofResource", "int", $hInstance, "int", $InfoBlock) If @error Then Return SetError(5, 0, 0) $ResSize = $ResSize[0] If $ResSize = 0 Then Return SetError(6, 0, 0) $GlobalMemoryBlock = DllCall("kernel32.dll", "int", "LoadResource", "int", $hInstance, "int", $InfoBlock) If @error Then Return SetError(7, 0, 0) $GlobalMemoryBlock = $GlobalMemoryBlock[0] If $GlobalMemoryBlock = 0 Then Return SetError(8, 0, 0) $MemoryPointer = DllCall("kernel32.dll", "int", "LockResource", "int", $GlobalMemoryBlock) If @error Then Return SetError(9, 0, 0) $MemoryPointer = $MemoryPointer[0] If $MemoryPointer = 0 Then Return SetError(10, 0, 0) If $DLL <> -1 Then DllCall("Kernel32.dll","int","FreeLibrary","str",$hInstance) If @error Then Return SetError(11, 0, 0) SetExtended($ResSize) Return $MemoryPointer EndFunc Best Regards.Thierry
zeshrek Posted February 4, 2011 Posted February 4, 2011 YES !!! It works perfectly with this 'new' version of _ResourcesGet() Many thanks to you guys.
rover Posted February 4, 2011 Posted February 4, 2011 @Tlem, zeshrek that older version works because it has an error in the call to FreeLibrary(). str is used instead of handle or ptr, so the FreeLibrary() call failed. and without a working FreeLibrary() there is a growing memory leak with every call to _ResourceGet() if you use that code... @Zedna, All the crashing is caused by calling FreeLibrary() before DllStructGetData() in _ResourceGetAsString() I've modified _ResourceGet() for LoadLibraryEx with $LOAD_LIBRARY_AS_DATAFILE LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE and LOAD_LIBRARY_AS_IMAGE_RESOURCE only work for Vista/7 I've added the three macros to _ResourceGet() that test the returned handle Re: LOAD_LIBRARY_AS_DATAFILE/LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE Article ID: 241856 - Last Review: December 11, 2003 - Revision: 3.0 PRB: Crash in DllMain After FreeLibrary is Called on a Resource DLL http://support.microsoft.com/kb/241856 any update to the udf could check OS and use the two flags for Vista/7 and LOAD_LIBRARY_AS_DATAFILE for server 2003 on down. if you are using Vista/7 then use LL_FLAG in in _ResourceGet() _WinAPI_LoadLibraryEx() this code fixes the memory leak or crash with a resource dll and _ResourceGetAsString() the other functions in the udf need to be modified so FreeLibrary can be called, or the module handle returned for user to close and free up resources. expandcollapse popup#AutoIt3Wrapper_Res_File_Add=AsciiFiles.dll, rt_rcdata, FILE0 #include-once #include <WinAPI.au3> #include <Memory.au3> Global Const $RT_RCDATA = 10 Global Const $RT_BITMAP = 2 Global $hInstance $text=_ResourceGetAsString("FILE0", $RT_RCDATA, 1033, "AsciiFiles.dll") MsgBox(262144,'Debug line ~' & @ScriptLineNumber,'Selection:' & @lf & '$text' & @lf & @lf & 'Return:' & @lf & $text) ;### Debug MSGBOX $text=_ResourceGetAsString("FILE1", $RT_RCDATA, 1033, "AsciiFiles.dll") MsgBox(262144,'Debug line ~' & @ScriptLineNumber,'Selection:' & @lf & '$text' & @lf & @lf & 'Return:' & @lf & $text) ;### Debug MSGBOX Func _ResourceGet($ResName, $ResType = 10, $ResLang = 0, $DLL = -1) ; $RT_RCDATA = 10 Local Const $IMAGE_BITMAP = 0 Local $hBitmap, $InfoBlock, $GlobalMemoryBlock, $MemoryPointer, $ResSize If $DLL = -1 Then $hInstance = _WinAPI_GetModuleHandle("") Else Local Const $LOAD_LIBRARY_AS_DATAFILE = 0x00000002 Local Const $LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040 Local Const $LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020 Local Const $LL_FLAG = $LOAD_LIBRARY_AS_IMAGE_RESOURCE + $LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE $hInstance = _WinAPI_LoadLibraryEx($DLL, $LOAD_LIBRARY_AS_DATAFILE) ;Vista/7/Server 2003-2008/XP/2000/98 ;$hInstance = _WinAPI_LoadLibraryEx($DLL, $LL_FLAG) ;Vista/7 - Untested ;If this macro returns TRUE, the module was loaded with LOAD_LIBRARY_AS_DATAFILE or LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE. ;Local $LDR_IS_DATAFILE = BitAND($hInstance, 0x00000001) <> 0 ;If this macro returns TRUE, the module was loaded with LOAD_LIBRARY_AS_IMAGE_RESOURCE. ;Local $LDR_IS_IMAGEMAPPING = BitAND($hInstance, 0x00000002) <> 0 ;If this macro returns TRUE, the module was loaded with LOAD_LIBRARY_AS_IMAGE_RESOURCE and either LOAD_LIBRARY_AS_DATAFILE or LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE. ;Local $LDR_IS_RESOURCE = ($LDR_IS_DATAFILE And $LDR_IS_IMAGEMAPPING) EndIf If $hInstance = 0 Then Return SetError(1, 0, 0) If $ResType = $RT_BITMAP Then $hBitmap = _WinAPI_LoadImage($hInstance, $ResName, $IMAGE_BITMAP, 0, 0, 0) If @error Then Return SetError(2, 0, 0) Return $hBitmap ; returns handle to Bitmap EndIf If $ResLang <> 0 Then $InfoBlock = DllCall("kernel32.dll", "int", "FindResourceExA", "int", $hInstance, "long", $ResType, "str", $ResName, "short", $ResLang) Else $InfoBlock = DllCall("kernel32.dll", "int", "FindResourceA", "int", $hInstance, "str", $ResName, "long", $ResType) EndIf If @error Then Return SetError(3, 0, 0) $InfoBlock = $InfoBlock[0] If $InfoBlock = 0 Then Return SetError(4, 0, 0) $ResSize = DllCall("kernel32.dll", "dword", "SizeofResource", "int", $hInstance, "int", $InfoBlock) If @error Then Return SetError(5, 0, 0) $ResSize = $ResSize[0] If $ResSize = 0 Then Return SetError(6, 0, 0) $GlobalMemoryBlock = DllCall("kernel32.dll", "int", "LoadResource", "int", $hInstance, "int", $InfoBlock) If @error Then Return SetError(7, 0, 0) $GlobalMemoryBlock = $GlobalMemoryBlock[0] If $GlobalMemoryBlock = 0 Then Return SetError(8, 0, 0) $MemoryPointer = DllCall("kernel32.dll", "int", "LockResource", "int", $GlobalMemoryBlock) If @error Then Return SetError(9, 0, 0) $MemoryPointer = $MemoryPointer[0] If $MemoryPointer = 0 Then Return SetError(10, 0, 0) SetExtended($ResSize) Return $MemoryPointer EndFunc ;==>_ResourceGet ; for ANSI strings Func _ResourceGetAsString($ResName, $ResType = 10, $ResLang = 0, $DLL = -1) ; $RT_RCDATA = 10 Local $ResPointer, $ResSize, $struct $ResPointer = _ResourceGet($ResName, $ResType, $ResLang, $DLL) If @error Then SetError(1, 0, 0) Return '' EndIf $ResSize = @extended $struct = DllStructCreate("char[" & $ResSize & "]", $ResPointer) Local $sTemp = DllStructGetData($struct, 1) ; returns string If $DLL <> -1 Then _WinAPI_FreeLibrary($hInstance) Return SetError(@error, 0, $sTemp) EndFunc ;==>_ResourceGetAsString I see fascists...
Potarski Posted February 16, 2011 Posted February 16, 2011 Hi zenda play sound not working. I use your example and your includes but the sound dont working, autoit not found error etc but not play sound why? First: #AutoIt3Wrapper_Res_File_Add=G:\WINDOWS\Media\tada.wav, SOUND, MYWAV _ResourcePlaySound("MYWAV") _ResourcePlaySound("MYWAV", $SND_ASYNC) Second: #AutoIt3Wrapper_Res_File_Add=G:\WINDOWS\Media\tada.wav, SOUND, MYWAV Global Const $SND_RESOURCE = 0x00040004 Global Const $SND_ASYNC = 1 DllCall("winmm.dll", "int", "PlaySound", "str", "MYWAV", "hwnd", 0, "int", $SND_RESOURCE) DllCall("winmm.dll", "int", "PlaySound", "str", "MYWAV", "hwnd", 0, "int", BitOR($SND_RESOURCE, $SND_ASYNC)) It add file but not play sound
Zedna Posted February 18, 2011 Author Posted February 18, 2011 #AutoIt3Wrapper_Res_File_Add=G:\WINDOWS\Media\tada.wav, SOUND, MYWAV It add file but not play sound Are you sure about the correct path? G:\WINDOWS\Media\tada.wav C:\WINDOWS\Media\tada.wav Resources UDF Â ResourcesEx UDF Â AutoIt Forum Search
Developers Jos Posted February 18, 2011 Developers Posted February 18, 2011 (edited) AutoIt3Wrapper gives an error during compilation when the file isn't found.- Skipping #AutoIt3Wrapper_Res_File_Add because the file is not found:G:\WINDOWS\Media\tada.wav, SOUND, MYWAVThe #include "resources.au3" is missing in the posted code as well.... is it in? Edited February 18, 2011 by Jos SciTE4AutoIt3 Full installer Download page  - Beta files    Read before posting   How to post scriptsource   Forum etiquette Forum Rules  Live for the present, Dream of the future, Learn from the past.Â
Shanheavel Posted February 26, 2011 Posted February 26, 2011 Hello. I'm trying to add *.DLL to my program.EXE ... #include "resources.au3" ;Add MyLib.dll #AutoIt3Wrapper_Res_File_Add=MyLib.dll, rt_rcdata, LIB ;Get MyLib.dll as string $LibAsString = _ResourceGetAsString("LIB") ;Try to open this DLL DllOpen($LibAsString) ... ;Use DLL I doesn't work. Can someone tell me how to do it, please?
Mallie99 Posted March 9, 2011 Posted March 9, 2011 (edited) Hello. I'm trying to add *.DLL to my program.EXE ... #include "resources.au3" ;Add MyLib.dll #AutoIt3Wrapper_Res_File_Add=MyLib.dll, rt_rcdata, LIB ;Get MyLib.dll as string $LibAsString = _ResourceGetAsString("LIB") ;Try to open this DLL DllOpen($LibAsString) ... ;Use DLL I doesn't work. Can someone tell me how to do it, please? Get your hands on Resource Hacker and add the following line to your WRAPPER: #AutoIt3Wrapper_Run_After=<<<** PATH TO **>>>ResHacker.exe -add %out%, %out%, <<<** PATH TO **>>>.dll, rcdata, LIB, 0 Edited March 9, 2011 by Mallie99 Are you telling me something I need to know or something I want to know?
Mallie99 Posted March 9, 2011 Posted March 9, 2011 I would also recommend you NOT use GetResourceAsString, but rather use ResourceGet or ResourceSaveToFile Are you telling me something I need to know or something I want to know?
Zedna Posted March 10, 2011 Author Posted March 10, 2011 (edited) Hello.I'm trying to add *.DLL to my program.EXEI doesn't work. Can someone tell me how to do it, please? Look hereIt's mentioned also in my first post. Edited March 10, 2011 by Zedna Resources UDF Â ResourcesEx UDF Â AutoIt Forum Search
Homes32 Posted March 30, 2011 Posted March 30, 2011 using the demo script from the 1st post I can't get _GetResourceAsString to retrieve the contents of an embedded txt file. to work with a x64 bit compile. it works fine with 32bit. the problem seems to be in _ResourceGet() any ideas?
taietel Posted March 30, 2011 Posted March 30, 2011 Homes, I don't know if it helps, but take a look at posts #457 and #458. taietel Things you should know first...In the beginning there was only ONE! And zero... Progs: Create PDF(TXT2PDF,IMG2PDF) 3D Bar Graph DeskGadget Menu INI Photo Mosaic 3D Text
Homes32 Posted March 31, 2011 Posted March 31, 2011 Homes, I don't know if it helps, but take a look at posts #457 and #458.taietelyep #458 got me straightened out. thanks taietel!
hevoxer Posted April 1, 2011 Posted April 1, 2011 (edited) I have a problem with including resources into the exe file, I don't know what I'm doing wrong. Sample of code (very simple):#AutoIt3Wrapper_Res_File_Add=imie.txt, rt_rcdata, FILE0#include <resources.au3>$text=_ResourceGetAsString("FILE0")MsgBox(0,'',$text)Why this don't work?! Why why why???resources.au3 file is in "include" directory and in the same directory as the file imie.txt is.Thank you all for AutoIt Edited April 1, 2011 by hevoxer
taietel Posted April 1, 2011 Posted April 1, 2011 hevoxer, maybe if you compile the script (by pressing F7 key in Scite) and then run the resulting exe, it will work. Regards, taietel Things you should know first...In the beginning there was only ONE! And zero... Progs: Create PDF(TXT2PDF,IMG2PDF) 3D Bar Graph DeskGadget Menu INI Photo Mosaic 3D Text
hevoxer Posted April 2, 2011 Posted April 2, 2011 taietel, thanks for trying to help but this don't solve my problem. I checked the exe file with hex editor and there is no string from txt file so the conclusion is that the converter au3 2 exe didn't include resource.
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