Я пытаюсь загрузить изображение на рабочий стол пользователя с URL-адреса, используя Win32. Я позаботился обо всех HTTP-запросах и точно знаю, что все работает хорошо. Когда я иду звонить CreateFile()
, отладчик Visual Studio просто говорит: «Исключение: Application.exe вызвал точку останова» и что он возобновится в строке CreateFile(). Также появляется код ошибки "Обнаружена критическая ошибка c0000374"
Вот мой код:
VARIANT varResponse;
VariantInit(&varResponse);
...
hr = pIWinHttpRequest->get_ResponseBody(&varResponse);
...
if (SUCCEEDED(hr)) {
long upperBounds;
long lowerBounds;
unsigned char* buff;
//Make sure that varResponse is an array of unsigned bytes
if (varResponse.vt == (VT_ARRAY | VT_UI1)) {
long Dims = SafeArrayGetDim(varResponse.parray);
//It should only have one dimension
if (Dims == 1) {
//Get Array lower and upper bounds
SafeArrayGetLBound(varResponse.parray, 1, &lowerBounds);
SafeArrayGetUBound(varResponse.parray, 1, &upperBounds);
upperBounds++;
SafeArrayAccessData(varResponse.parray, (void**)&buff);
HANDLE hFile;
DWORD dwBytesWritten;
PWSTR filepath[MAX_PATH];
HRESULT hr = SHGetKnownFolderPath(FOLDERID_Desktop, 0, NULL, &*filepath);
if (SUCCEEDED(hr)) {
//PathCombine(filepathForImage, filepathToDesktop, L"\\todaysDailyImage.jpg");
PathAppend(*filepath, L"todaysDailyImage.jpg");
MessageBox(NULL, *filepath, L"Check if filepath works", MB_OK);
}
hFile = CreateFile(*filepath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
//File failed
}
else {
WriteFile(hFile, buff, upperBounds - lowerBounds, &dwBytesWritten, NULL);
//File was written
}
CloseHandle(hFile);
CoTaskMemFree(filepath);
SafeArrayUnaccessData(varResponse.parray);
MessageBox(NULL, L"Everything was cleaned up", L"Update:", MB_OK);
}
}
}
Я делаю что-то не так?
@MikeCAT, как бы это выглядело, потому что я пытался wstringstream
, но не мог этого понять
@DaMahdi03 примерно так: PWSTR folderpath; SHGetKnownFolderPath(..., &folderpath); wostringstream wos; wos << folderpath << L"\\todaysDailyImage.jpg"; wstring filepath = wos.str(); ... hFile = CreateFile(filepath.c_str(), ...); ...
То, как вы используете filepath
, совершенно неправильно.
Вы объявляете его как массив из MAX_PATH
(260) числа PWSTR
указателей.
Когда вы обращаетесь к массиву только по его имени, вы получаете указатель на 1-й элемент массива. Итак, &*filepath
— это то же самое, что &*(&filepath[0])
, то есть фактически &filepath[0]
. А *filepath
— это то же самое, что *(&filepath[0])
, то есть фактически filepath[0]
. Итак, что касается SHGetKnownFolderPath()
и MessageBox()
, они работают только с 1-м указателем PWSTR
в массиве, а остальные 259 элементов массива игнорируются. Эта часть в порядке, но расточительна.
Однако для PathAppend()
требуется буфер назначения, который представляет собой массив из MAX_PATH
числа WCHAR
элементов. Вы добавляете к массиву WCHAR[]
, который SHGetKnownFolderPath()
выделяет в качестве своего вывода, который недостаточно велик, чтобы содержать имя файла, которое вы пытаетесь добавить к нему. Итак, вы вызываете ошибки, потому что пытаетесь изменить память, которая не была выделена для хранения этой модификации.
Вам вообще не нужен массив PWSTR
. Вместо этого попробуйте что-то вроде этого:
PWSTR folderpath;
HRESULT hr = SHGetKnownFolderPath(FOLDERID_Desktop, 0, NULL, &folderpath);
if (FAILED(hr)) {
// ...
}
else {
PWSTR filepath;
hr = PathAllocCombine(folderpath, L"todaysDailyImage.jpg", 0, &filepath);
if (FAIlED(hr)) {
// ...
}
else {
MessageBoxW(NULL, filepath, L"Check if filepath works", MB_OK);
hFile = CreateFileW(filepath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
//File failed
}
else {
WriteFile(hFile, buff, upperBounds - lowerBounds, &dwBytesWritten, NULL);
//File was written
CloseHandle(hFile);
}
LocalFree(filepath);
}
CoTaskMemFree(folderpath);
}
Спасибо, это сработало! хотя не понимаю что я делал не так
Подозрительно ли добавление вещей к результату
SHGetKnownFolderPath
. Должно быть безопаснее скопировать строку в достаточно большой буфер, прежде чем объединять его.