Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate

FileExtract / FileExtract_ToMem Examples for Unicode Builds


  • Please log in to reply
34 replies to this topic
  • Guests
  • Last active:
  • Joined: --
I'd like to try this function. I ran the demo script with the Unicode build but as it is stated in the post, the script is not compatible with it. I'm not sure if the library itself is compatible with the Unicode and 64 bit build.

Can somebody provide a simple example of using it? Something like, install a text file in a compiled script and extract it to memory when necessary.

Thanks.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
Those functions are not compatible with recent versions of AutoHotkey_L.

With v1.1.01 or later, FileInstall stores the data as a Win32 resource, so you can retrieve the data using the Win32 Resource APIs. For example:
; LoadResourceDemo.ahk
SelfCompile()

; Load resource and retrieve address and size.
if data := LoadScriptResource("LoadResourceDemo.ahk", size)
{
    ; Retrieve text, assuming UTF-8 encoding.
    text := StrGet(data, size, "UTF-8")
    ; Display text in GUI.
    Gui Add, Edit, ReadOnly W600 H400, %text%
    Gui Show
    return
}
else
    MsgBox 16,, Failed to load resource.

GuiClose:
GuiEscape:
ExitApp

LoadScriptResource(Name, ByRef DataSize = 0, Type = 10)
{
    lib := DllCall("GetModuleHandle", "ptr", 0, "ptr")
    res := DllCall("FindResource", "ptr", lib, "str", Name, "ptr", Type, "ptr")
    DataSize := DllCall("SizeofResource", "ptr", lib, "ptr", res, "uint")
    hresdata := DllCall("LoadResource", "ptr", lib, "ptr", res, "ptr")
    return DllCall("LockResource", "ptr", hresdata, "ptr")
}

SelfCompile()
{
    if A_IsCompiled
        return
    ; Self-compile-and-run.
    RunWait, %A_AhkPath%\..\Compiler\Ahk2Exe.exe /in "%A_ScriptFullPath%"
    Run LoadResourceDemo.exe
    ExitApp
   
    ; Not executed by AutoHotkey, but interpreted by Ahk2Exe:
    FileInstall, LoadResourceDemo.ahk, ~
}


  • Guests
  • Last active:
  • Joined: --
This is great. So simple. Thank you so much. Personally I think this functionality should be built in. I'll post the idea in Wish Lists.

  • Guests
  • Last active:
  • Joined: --
Lexikos, this part is little bit difficult for me to use it in my actual scripts (I know it is provided for demonstration purpose) because I'd like to also run non-compiled script normally for testing.
if A_IsCompiled
        return
    ; Self-compile-and-run.
    RunWait, %A_AhkPath%\..\Compiler\Ahk2Exe.exe /in "%A_ScriptFullPath%"
    Run LoadResourceDemo.exe
    ExitApp
   
    ; Not executed by AutoHotkey, but interpreted by Ahk2Exe:
    FileInstall, LoadResourceDemo.ahk, ~
In order to work around this, is it possible to evaluate whether the script is read by the interpreter or not? I mean is it possible to write a function something like, IsReadByInterpreter(), which returns false when the script launched regularly and returns true when AHK2Exe sees the line.

  • Guests
  • Last active:
  • Joined: --
Sorry, I just realized that this is sufficient for non-compiled script.
if !A_IsCompiled
   FileInstall, LoadResource01.ahk, ~
The created ~ file doesn't matter for me to run the script for testing other parts of the script.

Rseding91
  • Members
  • 703 posts
  • Last active: Apr 02 2016 05:05 AM
  • Joined: 07 Jun 2010
As an alternative you could try this: <!-- m -->http://www.autohotke...topic69372.html<!-- m -->

  • Guests
  • Last active:
  • Joined: --

As an alternative you could try this: <!-- m -->http://www.autohotke...topic69372.html<!-- m -->

Wao. That's an amazing piece of script. I didn't know it. However, it doesn't seem to be compatible with the 64bit build. Although it is stated it is, I ran it with the 64 bit build and the extracted picture could not be displayed in Windows Photo Viewer while it was possible with the x86 build. I looked into the code roughly and found Ptr is not used in DllCall() for pointers and handles and return types are not specified. So it is likely not to be compatible with the 64bit build. Otherwise, a great script. Also it would be great to have an option to extract the data into a variable. I'll post further responses in the script thread.

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

if !A_IsCompiled
FileInstall, LoadResource01.ahk, ~

In that case running the script uncompiled will create a copy of LoadResource01.ahk, named ~. As implied by my earlier comment in the code, even if a line can't possibly be executed while the script is running, it will be processed by Ahk2Exe. Thus, if you don't want the line to do anything when you run the script, simply put it somewhere that it won't be executed.
if false
    FileInstall, YourFile.ahk, (this part doesn't matter since it won't be executed)
ExitApp
FileInstall, YourFile.ahk, (same as above)

IsReadByInterpreter(), which (...) returns true when AHK2Exe sees the line.

Ahk2Exe doesn't evaluate or execute the script, so it is not possible for any function to return any value. It merely does some basic pre-processing.

Rseding91
  • Members
  • 703 posts
  • Last active: Apr 02 2016 05:05 AM
  • Joined: 07 Jun 2010

As an alternative you could try this: <!-- m -->http://www.autohotke...topic69372.html<!-- m -->

Wao. That's an amazing piece of script. I didn't know it. However, it doesn't seem to be compatible with the 64bit build. Although it is stated it is, I ran it with the 64 bit build and the extracted picture could not be displayed in Windows Photo Viewer while it was possible with the x86 build. I looked into the code roughly and found Ptr is not used in DllCall() for pointers and handles and return types are not specified. So it is likely not to be compatible with the 64bit build. Otherwise, a great script. Also it would be great to have an option to extract the data into a variable. I'll post further responses in the script thread.



Oops.. I fixed that. I've been working more on making my things work with x64 and that was one of my first attempts.

It should work on any build of AHK now. Basic, L ANSI L Unicode x86 + L Unicode x64.

  • Guests
  • Last active:
  • Joined: --

ExitApp
FileInstall, YourFile.ahk, (same as above)

This is something I never thought about. Thanks a lot.

Ahk2Exe doesn't evaluate or execute the script, so it is not possible for any function to return any value. It merely does some basic pre-processing.

Thanks for the answer.

It should work on any build of AHK now. Basic, L ANSI L Unicode x86 + L Unicode x64.

Very nice. Good work.

  • Guests
  • Last active:
  • Joined: --
Hi guys,

Now I'm trying to install and extract encrypted text data. Somehow the following code doesn't work. I'm guessing that it's a file encoding problem but UTF-8 is specified so I don't understand why this doesn't work. Could you check if there are some errors in the code?

Please run it as non-compiled first. It creates an encrypted file, sample.dat. And compile the script and run it again. The broken string will appear. When I tried without encryption, it just works fine.
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

if A_IsCompiled {
	data := LoadScriptResource(".\res\sample.dat", size)
	Crypt_AES(&data, size, "007", 256, False)
}
else {
	FileDelete, .\res\sample.txt
	FileDelete, .\res\sample.dat
	FileCreateDir, .\res
	FileAppend, Hello World!, .\res\sample.txt, UTF-8
	size := File_AES(".\res\sample.txt",".\res\sample.dat", "007", 256, True)
	FileRead, data, *c .\res\sample.dat
	Crypt_AES(&data, size, "007", 256, False)
}

msgbox % StrGet(&data, size, "UTF-8")

Return

LoadTextResource(Name, encoding="UTF-8") {
	data := LoadScriptResource(Name, size)
    return StrGet(data, size, encoding)
}
LoadScriptResource(Name, ByRef DataSize = 0, Type = 10)
{
    lib := DllCall("GetModuleHandle", "ptr", 0, "ptr")
    res := DllCall("FindResource", "ptr", lib, "str", Name, "ptr", Type, "ptr")
    DataSize := DllCall("SizeofResource", "ptr", lib, "ptr", res, "uint")
    hresdata := DllCall("LoadResource", "ptr", lib, "ptr", res, "ptr")
    return DllCall("LockResource", "ptr", hresdata, "ptr")
}
;AES Encrypt/Decrypt by Sean, modified by shajul
;http://www.autohotkey.com/forum/post-408586.html#408586
File_AES(sFileFr, sFileTo, sPassword, SID = 256, bEncrypt = True)
{
   hFileFr := FileOpen(sFileFr,"r -r")
   if not hFileFr
      Return   "File not found!"
   nSize := hFileFr.Length
   VarSetCapacity(sData, nSize + (bEncrypt ? 16 : 0))
   hFileFr.Seek(0)
   hFileFr.RawRead(sData, nSize)
   hFileFr.Close()
   hFileTo := FileOpen(sFileTo,"w -r")
   if not hFileTo
      Return   "File not created/opened!"
   nSize := Crypt_AES(&sData, nSize, sPassword, SID, bEncrypt)
   hFileTo.RawWrite(sData, nSize)
   hFileTo.Close()
      Return   nSize
}
Crypt_AES(pData, nSize, sPassword, SID = 256, bEncrypt = True)
{
   CALG_AES_256 := 1 + CALG_AES_192 := 1 + CALG_AES_128 := 0x660E
   CALG_SHA1 := 1 + CALG_MD5 := 0x8003
   DllCall("advapi32\CryptAcquireContext", "UPtr*", hProv, "UPtr", 0, "UPtr", 0, "UPtr", 24, "UPtr", 0xF0000000)
   DllCall("advapi32\CryptCreateHash", "UPtr", hProv, "UPtr", CALG_SHA1, "UPtr", 0, "UPtr", 0, "UPtr*", hHash)
   DllCall("advapi32\CryptHashData", "UPtr", hHash
   , "UPtr", &sPassword
   , "UPtr", (A_IsUnicode ? StrLen(sPassword)*2 : StrLen(sPassword)), "UPtr", 0)
   DllCall("advapi32\CryptDeriveKey", "UPtr", hProv, "UPtr", CALG_AES_%SID%, "UPtr", hHash, "UPtr", SID<<16, "UPtr*", hKey)
   DllCall("advapi32\CryptDestroyHash", "UPtr", hHash)
   bEncrypt
   ? DllCall("advapi32\CryptEncrypt", "UPtr", hKey, "UPtr", 0, "UPtr", True, "UPtr", 0
    , (A_PtrSize = 8 ? "UInt64" : "UInt"), pData, (A_PtrSize = 8 ? "UInt64P" : "UIntP"), nSize, "UPtr", nSize+16)
   : DllCall("advapi32\CryptDecrypt", "UPtr", hKey, "UPtr", 0, "UPtr", True, "UPtr", 0
    , (A_PtrSize = 8 ? "UInt64" : "UInt"), pData, (A_PtrSize = 8 ? "UInt64P" : "UIntP"), nSize)
   DllCall("advapi32\CryptDestroyKey", "UPtr", hKey)
   DllCall("advapi32\CryptReleaseContext", "UPtr", hProv, "UPtr", 0)
   Return   nSize
}

/*
	The Ahk2Exe interpreter section
*/
FileInstall, .\res\sample.dat, ~


  • Guests
  • Last active:
  • Joined: --
Okey, found it. The problem was passing a pointer of a pointer. This works.
if A_IsCompiled {
	pData := LoadScriptResource(".\res\sample.dat", size)
	; data := LoadTextResource(".\res\sample.dat", "UTF-8")
	Crypt_AES(pData, size, "007", 1, False)
}
else {
	FileDelete, .\res\sample.txt
	FileDelete, .\res\sample.dat
	FileCreateDir, .\res
	FileAppend, Hello World!, .\res\sample.txt, UTF-8
	size := File_AES(".\res\sample.txt",".\res\sample.dat", "007", 1, True)
	FileRead, data, *c .\res\sample.dat
	Crypt_AES(&data, size, "007", 1, False)
	pData := &data
}

msgbox % StrGet(pData, size, "UTF-8")
Return
(the functions are omitted.)

  • Guests
  • Last active:
  • Joined: --

Okey, found it. The problem was passing a pointer of a pointer. This works.

No, it wasn't. If I change the forth parameter, SID value, to other than 1 like 256, it doesn't work. Why is it? And 1 for SID value is just not encrypting data.

  • Guests
  • Last active:
  • Joined: --
At last got it working by copying the loaded resource data into another location of memory. I don't know why this is necessary. Does anybody happen to know why?
if A_IsCompiled {
	pData := LoadScriptResource(".\res\sample.dat", size)
	[color=red]VarSetCapacity(Data, size)
	DllCall("msvcrt\memcpy", "str", Data, "ptr", pData, "ptr", size)[/color]
	pData := &Data
}
else {
	FileDelete, .\res\sample.txt
	FileDelete, .\res\sample.dat
	FileCreateDir, .\res
	FileAppend, Hello World!, .\res\sample.txt, UTF-8
	size := File_AES(".\res\sample.txt",".\res\sample.dat", "mypass", 256, True)
	FileRead, data, *c .\res\sample.dat
	pData := &data
}

Crypt_AES(pData, size, "mypass", 256, False)
msgbox % StrGet(pData, size, "UTF-8") 
Return
(the functions are omitted)

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
I presume the block of memory which contains the resource data is read-only.