I am trying to use a pre-build .exe file as a resource in my C project, after searching I done the following steps:
Step1 Create a new C project and place the following code in the Source.cpp file
#include<iostream>
#include<Windows.h>
#include<fstream>
#define IDB_EMBEDEXE 52
using namespace std;
int main() {
int count = 2;
HRSRC hResource = FindResource(NULL, MAKEINTRESOURCE(IDB_EMBEDEXE), __TEXT("BINARY"));
HGLOBAL hGlobal = LoadResource(NULL, hResource);
size_t exeSiz = SizeofResource(NULL, hResource);
void* exeBuf = LockResource(hGlobal);
ofstream outfile((char*)exeBuf, ios::out | ios::binary);
if (!outfile)
exit(9);
outfile.write((char*)exeBuf, exeSiz);
system((char*)exeBuf);
return 0;
}
Step2 Create a new resource file (.rc)
1- Project>Add new item
2- From Installed>Visual C >Resource choose Resource File (.rc) let us name it Resource.rc
Step3 Edit the header file resource.h that has just created from Step2, add the following line to the header file:
#define IDB_EMBEDEXE 52
Step4 Edit the Resource.rc file by right click on it>Open with>Source Code (Text) Editor, add the following code just after the first #include
statment (i.e. after #include "resource.h"
#define IDB_EMBEDEXE 52
IDB_EMBEDEXE BINARY "C:\\Users\\Almohandis\\source\\repos\\Project7\\sum2num.exe"
After doing exactly these steps, I still get the following error in the cmd (not in the Visual Studio):
'MZ' is not recognized as an internal or external command, operable program or batch file.
And the program ends with code 0
I think calling system()
what causes the problem, especially the argument I passed.
Note that the binary representation of the sum2num.exe file starts with MZ....
CodePudding user response:
If your #define
is already in resource.h
, there is no need to duplicate it in your source code. Just use #include "resource.h"
in your code instead.
In any case, you should be using the pre-defined RCDATA
resource type, instead of creating a custom BINARY
type.
That being said, your use of ofstream
and system()
are both wrong. You are passing them the resource's raw binary data, but they are expecting a file path instead. You are using a file path in your .rc
file to specify the file whose binary data is copied into the resource. The resource does not contain that file path, as you are clearly expecting.
Try this instead:
resource.h
...
#define IDB_EMBEDEXE 52
...
Resource.rc
#include "resource.h"
...
IDB_EMBEDEXE RCDATA "C:\\Users\\Almohandis\\source\\repos\\Project7\\sum2num.exe"
...
Source.cpp
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include <cstdio>
#include "resource.h"
using namespace std;
int main() {
HRSRC hResource = FindResource(NULL, MAKEINTRESOURCE(IDB_EMBEDEXE), RT_RCDATA);
if (!hResource)
return 1;
HGLOBAL hGlobal = LoadResource(NULL, hResource);
if (!hGlobal)
return 2;
DWORD exeSiz = SizeofResource(NULL, hResource);
if (!exeSiz)
return 3;
void* exeBuf = LockResource(hGlobal);
if (!exeBuf)
return 4;
char tempPath[MAX_PATH] = {};
if (!GetTempPathA(MAX_PATH, path))
return 5;
string fullPath = string(tempPath) "sum2num.exe";
ofstream outfile(fullPath.c_str(), ios::binary);
if (!outfile.is_open())
return 6;
int res = (outfile.write((char*)exeBuf, exeSiz)) ? 0 : 7;
outfile.close();
if (res == 0) {
system(fullPath.c_str());
}
remove(fullPath.c_str());
return res;
}