int main()
{
const LPCWSTR lpType = MAKEINTRESOURCE(135);
const LPCWSTR lpName = L"CPPFILEACCOUNTJSON";
wchar_t exePath[] = L"I:\\CPP\\project\\test\\bin\\test.exe";
LPWSTR lpExePath = exePath;
//GetModuleFileNameW(NULL, exePath, MAX_PATH);
HANDLE hUpdate = BeginUpdateResourceW(exePath, FALSE);
if (hUpdate == NULL) {
MessageBoxW(0, L"BeginUpdateResource failed.", 0, MB_OK | MB_ICONERROR);
return 1;
}
char newStr[] = "123456789";
wchar_t newStrW[sizeof(newStr)];
MultiByteToWideChar(CP_UTF8, 0, newStr, sizeof(newStr), newStrW, sizeof(newStrW) / sizeof(wchar_t));
size_t dataSize = (strlen(newStr)) * sizeof(wchar_t);
cout << dataSize << endl;
if (!UpdateResourceW(hUpdate, lpName, lpType, 0, newStrW, dataSize)) {
MessageBoxW(0, L"UpdateResource failed.", 0, MB_OK | MB_ICONERROR);
return 1;
}
if (!EndUpdateResourceW(hUpdate, FALSE)) {
DWORD errCode = GetLastError();
LPWSTR errBuffer = nullptr;
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, errCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&errBuffer, 0, nullptr);
MessageBoxW(nullptr, errBuffer, L"Error", MB_OK | MB_ICONERROR);
LocalFree(errBuffer);
return 1;
}
system("pause");
std::cout << "Hello World!\n";
return 0;
}
在上面的代码中我替换指定的资源文件的字符串内容为:"123456789"
代码执行成功后 test.exe被成功写入的字符只有"1" 这是为什么 我哪里写错了。。。求解答
BOOL UpdateResourceW(
[in] HANDLE hUpdate,
[in] LPCWSTR lpType,
[in] LPCWSTR lpName,
[in] WORD wLanguage,
[in, optional] LPVOID lpData,
[in] DWORD cb
);
你参数调用顺序好像有误,type在前面,name在后面,你好像反了
该回答引用ChatGPT
size_t dataSize = (wcslen(newStrW) + 1) * sizeof(wchar_t);
cout << dataSize << endl;
这里输出多少
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
这是一个编码问题,具体原因是在使用MultiByteToWideChar
将char类型的字符串newStr
转换成wchar_t类型的字符串newStrW
时出现了问题。
在使用sizeof(newStr)
的时候,返回的是字符数组newStr
的总长度,而实际上字符数组newStr
中的有效字符只有9个,也就是字符串"123456789"的长度。因此,在调用MultiByteToWideChar
时,需要传入字符串的实际长度,而不是字符数组的长度。
修改方式如下:
char newStr[] = "123456789";
int newStrLength = strlen(newStr);
// 计算出转换成宽字符后需要的缓冲区大小
int bufferLength = MultiByteToWideChar(CP_UTF8, 0, newStr, newStrLength, nullptr, 0);
// 分配缓冲区
wchar_t *newStrW = new wchar_t[bufferLength + 1];
// 将char类型的字符串转换成wchar_t类型的字符串
MultiByteToWideChar(CP_UTF8, 0, newStr, newStrLength, newStrW, bufferLength);
newStrW[bufferLength] = '\0'; // 最后加上一个结束符
if (!UpdateResourceW(hUpdate, lpName, lpType, 0, newStrW, bufferLength * sizeof(wchar_t))) {
MessageBoxW(0, L"UpdateResource failed.", 0, MB_OK | MB_ICONERROR);
return 1;
}
delete[] newStrW;
在这个修改后的代码中,首先计算了需要分配的缓冲区的大小,然后根据这个大小动态分配了一段wchar_t类型的内存。接着,调用了MultiByteToWideChar
将char类型的字符串转换成wchar_t类型的字符串,并将结果存入刚才分配的内存中。最后,在调用UpdateResourceW
时,需要传入的是实际字符的字节数,因此需要将计算出来的字符数乘以每个字符的字节数(在Windows下,wchar_t类型的字符是2个字节),才能得到需要传入的总字节数。
需要特别注意的是,在使用完分配的内存后需要调用delete[]
来释放它,避免内存泄漏。
如果我的回答解决了您的问题,请采纳!
引用chatGPT作答,在这个代码中出现问题的原因是对 newStrW 数组的长度估计错误。
在代码中, newStr 数组的长度为 10 (9 个字符和结尾的 null 字节),然后通过 MultiByteToWideChar 函数将其转换为宽字符集编码,存储到 newStrW 数组中。
newStrW 数组的长度被定义为 sizeof(newStrW),这个值通常是在编译时计算的,它等于数组所占用的内存字节数。在这里,这个值为 20 (10 个 wchar_t 类型,每个占用 2 个字节)。
然而,由于 newStr 数组中只有 9 个字符(8 个数字和结尾的 null 字节),因此调用 MultiByteToWideChar 函数后, newStrW 数组中只包含 9 个宽字符。
在调用 UpdateResourceW 函数时, dataSize 的值被计算为 strlen(newStr) * sizeof(wchar_t),也就是 18 个字节。这个值假设了 newStrW 数组中有 9 个宽字符,而实际上它包含了 10 个宽字符。
因此,UpdateResourceW 函数仅写入了 newStrW 数组中的前两个字节,即字符 "1",因为它们是存储在 newStrW 数组的前两个位置上。
要解决这个问题,可以使用 wcslen 函数计算 newStrW 数组中的宽字符数,然后将它乘以 sizeof(wchar_t),计算出正确的 dataSize 值,如下所示:
size_t dataSize = wcslen(newStrW) * sizeof(wchar_t);
这将确保 dataSize 的值正确反映了 newStrW 数组中实际存储的数据量,从而保证所有数据都被写入到资源中。
解决了。。。
const std::string jsonContent = R"(abcdefg)";
const char* jsonBuffer = jsonContent.c_str();
const std::streamsize len = jsonContent.length();
```c++
```
朋友你好,以下是我把你的问题和相关观点都看了一遍分析出来的,望采纳谢谢啦
首先我理解的你代码的逻辑
使用宏 MAKEINTRESOURCE(135) 定义了一个指向整数资源 ID 的 LPCWSTR 类型指针。这个整数即为资源类型,本例中为 135。
同理,使用 LPCWSTR lpName = L"CPPFILEACCOUNTJSON" 定义指向资源名称的字符串指针。
调用 BeginUpdateResourceW 函数开始更新资源。此函数接受一个包含资源的可执行文件路径,以及一个布尔值,指示是否将资源写入当前进程的内存中。本例中使用 FALSE 表示不将资源写入当前进程的内存中。
将需要添加到资源中的数据从 char 类型转换为 wchar_t 类型,并将其保存在 newStrW 数组中。然后计算出需要添加的资源数据的大小。
使用 UpdateResourceW 函数将资源添加到可执行文件中。该函数接受句柄 hUpdate,表示要更新资源的可执行文件;lpName,表示新资源的名称;lpType,表示新资源的类型;0,表示资源的标记;newStrW,表示资源数据的指针;dataSize,表示资源数据的大小。
如果 UpdateResourceW 函数执行失败,则会调用 MessageBoxW 函数显示错误消息。
最后,使用 EndUpdateResourceW 函数结束资源更新。如果函数执行失败,则使用 GetLastError 函数获取错误代码,并使用 FormatMessageW 函数获取详细的错误描述。
在代码的最后,使用 system("pause") 以及 cout 和 return 语句输出一些信息和退出程序。
然后我发现修改了这段后,运行通过了欧
const std::string jsonContent = R"(abcdefg)";
const char* jsonBuffer = jsonContent.c_str();
const std::streamsize len = jsonContent.length();
不知道
不知道你这个问题是否已经解决, 如果还没有解决的话:回答引用ChatGPT:
在代码中,您使用了sizeof(newStr)来计算新字符串的大小,这是错误的。因为sizeof操作符返回的是数组的大小,而不是字符串的长度。数组的大小包括了最后一个元素的空间,即使它是一个空字符。这可能导致您的字符串被截断,并且只有第一个字符被写入到资源中。
为了获取字符串的长度,您应该使用strlen函数。它返回字符串的长度,不包括最后一个空字符。您还应该在新字符串中添加一个空字符,以确保它以正确的方式终止。
下面是修正后的代码:
int main()
{
const LPCWSTR lpType = MAKEINTRESOURCE(135);
const LPCWSTR lpName = L"CPPFILEACCOUNTJSON";
wchar_t exePath[] = L"I:\\CPP\\project\\test\\bin\\test.exe";
LPWSTR lpExePath = exePath;
HANDLE hUpdate = BeginUpdateResourceW(exePath, FALSE);
if (hUpdate == NULL) {
MessageBoxW(0, L"BeginUpdateResource 失败。", 0, MB_OK | MB_ICONERROR);
return 1;
}
char newStr[] = "123456789";
int newStrLen = strlen(newStr);
std::vector<wchar_t> newStrW(newStrLen + 1);
if (!MultiByteToWideChar(CP_UTF8, 0, newStr, newStrLen, &newStrW[0], newStrLen)) {
MessageBoxW(0, L"MultiByteToWideChar 失败。", 0, MB_OK | MB_ICONERROR);
return 1;
}
newStrW[newStrLen] = L'\0'; // add null terminator
size_t dataSize = (newStrLen + 1) * sizeof(wchar_t); // add one for null terminator
if (!UpdateResourceW(hUpdate, lpType, lpName, 0, &newStrW[0], dataSize)) {
MessageBoxW(0, L"UpdateResource 失败。", 0, MB_OK | MB_ICONERROR);
return 1;
}
if (!EndUpdateResourceW(hUpdate, FALSE)) {
DWORD errCode = GetLastError();
LPWSTR errBuffer = nullptr;
FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
nullptr, errCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&errBuffer, 0, nullptr);
MessageBoxW(nullptr, errBuffer, L"错误", MB_OK | MB_ICONERROR);
LocalFree(errBuffer);
return 1;
}
MessageBoxW(0, L"资源更新成功。", 0, MB_OK);
return 0;
}
这个代码中,我们使用strlen函数来获取新字符串的长度。我们还使用了一个std::vector对象来存储新字符串的宽字符表示,并在新字符串的末尾添加了一个空字符。最后,我们使用正确的顺序调用了UpdateResourceW函数,并在结束时关闭了资源更新句柄。
希望这个修改后的代码可以解决您的问题!