Embed Text File in a Resource in a native Windows Application
Since you're working on a native Windows application, what you want to do is to create a user-defined resource to embed the contents of the text file into the compiled resource.
The format of a user-defined resource is documented on MSDN, as are the functions for loading it.
You embed your text file in a resource file like this:
nameID typeID filename
where nameID
is some unique 16-bit unsigned integer that identifies the resource and typeID
is some unique 16-bit unsigned integer greater than 255 that identifies the resource type (you may define those integers in the resource.h
file). filename
is the path to the file that you want to embed its binary contents into the compiled resource.
So you might have it like this:
In resource.h
:
// Other defines...
#define TEXTFILE 256
#define IDR_MYTEXTFILE 101
In your resource file:
#include "resource.h"
// Other resource statements...
IDR_MYTEXTFILE TEXTFILE "mytextfile.txt"
Then you load it like this (error-checking code omitted for clarity):
#include <windows.h>
#include <cstdio>
#include "resource.h"
void LoadFileInResource(int name, int type, DWORD& size, const char*& data)
{
HMODULE handle = ::GetModuleHandle(NULL);
HRSRC rc = ::FindResource(handle, MAKEINTRESOURCE(name),
MAKEINTRESOURCE(type));
HGLOBAL rcData = ::LoadResource(handle, rc);
size = ::SizeofResource(handle, rc);
data = static_cast<const char*>(::LockResource(rcData));
}
// Usage example
int main()
{
DWORD size = 0;
const char* data = NULL;
LoadFileInResource(IDR_MYTEXTFILE, TEXTFILE, size, data);
/* Access bytes in data - here's a simple example involving text output*/
// The text stored in the resource might not be NULL terminated.
char* buffer = new char[size+1];
::memcpy(buffer, data, size);
buffer[size] = 0; // NULL terminator
::printf("Contents of text file: %s\n", buffer); // Print as ASCII text
delete[] buffer;
return 0;
}
Note that you don't actually have to free the resource since the resource resides in the binary of the executable and the system will delete them automatically when the program exits (the function FreeResource()
does nothing on 32-bit and 64-bit Windows systems).
Because the data resides in the executable binary, you can't modify it via the retrieved pointer directly (that's why the LoadFileInResource()
function implementation stores the pointer in a const char*
). You need to use the BeginUpdateResource()
, UpdateResource()
, and EndUpdateResource()
functions to do that.
Oliver Zheng
Updated on March 16, 2020Comments
-
Oliver Zheng about 4 years
I have a C++ Windows program. I have a text file that has some data. Currently, the text file is a separate file, and it is loaded at runtime and parsed. How is it possible to embed this into the binary as a resource?
-
IInspectable about 10 years-1 PE(+) files are already capable of storing custom resources, and the Windows build tools have everything you need. The resource script syntax is documented, and the OS provides APIs for accessing that data. This answer is the answer to another question.
-
utvecklare about 8 yearsI have one more general wondering asked here. Could you please answer to my second question that is related to your answer? Just how to have a dll file that has a function to contain the code that is in main in your answer.
-
Raindrop7 over 6 years" the system will delete them automatically when the program exits" Don't all program when exit the system free resources? Memory leak and resource leak occurs during the execution of an executable. So if this program loads n of the same resource it will issue in a resource leak.
-
Laurie Stearn about 6 yearsIn the properties of the resource file there's "Null Terminate Strings"
-
Programmer over 5 yearsI have a win32 application. Can I know where I can find the resource file and how I can create a user-defined resource file? I want to load an xml file during the build itself. File size is 20MB.