Problems in the function SHFileOperation. I use it to copy the folder, but the function ends with error code 87 or 2. There is the following code:

#include <iostream> #include <string> #include <windows.h> #include <shellapi.h> int main(int argc, char* argv[]) { setlocale(LC_ALL, "Russian"); std::string directionNames = argv[1]; std::string sourceDir = directionNames + "\\*\0\0"; std::string targetDir = directionNames + "_delComments"; SHFILEOPSTRUCT SHF; SHF.hwnd = 0; SHF.wFunc = FO_COPY; SHF.pFrom = sourceDir.c_str(); SHF.pTo = targetDir.c_str(); SHF.fFlags = 512; SHF.hNameMappings = 0; SHF.lpszProgressTitle = 0; int result = SHFileOperation(&SHF); if (result != 0) if (SHF.fAnyOperationsAborted) std::cout << "Выполнение операции прервано пользователем\n"; else std::cout << "Ошибка выполнения операции\n"; else std::cout << "Операция успешно завершена\n"; std::cout << result << std::endl; std::cin.get(); return 0; } 

Also there is a situation when once for 15-20 starts copying is performed successfully. What could be the problem?

  • msdn did not help you? msdn.microsoft.com/en-us/library/windows/desktop/ ... error codes are described there. - nick_n_a
  • @nick_n_a Yes, I read the documentation error 87: DE_SRC_IS_DVD 0x87 The DVD is a source of a read-only, possibly unformatted, But I don’t understand the cause of the occurrence and how to fix it - Max Yu
  • 2
    @MaxU, maybe you are confusing error code 0x87 with code 87 (ERROR_INVALID_PARAMETER). Look here - Embedder
  • @Embedder Yes, you are right, I confused) But the solution to correcting error 87 is presented there by adding ZeroMemory(&SHF, sizeof(SHFILEOPSTRUCT)); brought no results - Max Yu
  • I would not suffer for such a program with string, but would make an array of chars, and put strcpy, strcpy, strcat, strcat and everything (that would all be ASCIIZ). - nick_n_a

1 answer 1

Error 2 - ERROR_FILE_NOT_FOUND (file not found), error 86 - ERROR_INVALID_PASSWORD (The specified network password is not correct - the specified network password is incorrect). Very suspicious errors. If you say that the code sometimes works with the same parameters, then, given these errors, there is a suspicion that somewhere something is not initialized and sometimes the "garbage" in the memory is formed in the way we need it. Since the error occurs when calling SHFileOperation , the problem should be looked for in the initialization of its argument.

Next, read the documentation . In the note we see:

You must ensure that the source paths are double-null terminated.

Transfer:

You must ensure that the source and destination paths are terminated by two null characters.

But the variable targetDir in your code is a regular std::string and converting it to a C string will yield only one terminating zero. Therefore, the missing zero should be added:

 target_dir += '\0'. 

UPDATE

My above reasoning was wrong, although the direction was correct. The fact is that when concatenating std::string strings for the second string, the constructor of the std::string class is called, which takes as an argument the regular C string, which it reads up to the first zero character, i.e. an extra null character will be ignored. To avoid this, an extra null character at the end of the line must be added separately:

 std::string sourceDir = directionNames + "\\"; sourceDir.push_back('\0'); std::string targetDir = directionNames + "_delComments\\"; targetDir.push_back('\0'); 

With the above code it works.

  • Adding zero did not help to correct the situation, and the error does not appear in 86 but in 87, which reads: DE_SRC_IS_DVD 0x87 The DVD is a source of a read-only DVD, that is probably unformatted
  • And how does an error occur? The user may not correctly indicate the volume? Or is there a Russian C: put in place of the English C :? Can you log arguments on error? - nick_n_a
  • All the same you do not check the validity of the input parameters. Try the FindFirstFile function - what will it tell you (to verify the existence of the folder)? Try to somehow check the validity of the input parameters. Somehow you can CreateFile check that this is a folder, but I find FindFirstFile easier. Put the loop in 2 steps - if without errors - break; if with an error, a debugger (for example, the DebugBreak function). - nick_n_a
  • @nick_n_a I transfer the folder via the command line by transferring the desired folder to the program exe-file. As a result, an empty copy of the folder is created, and all attachments are lost. Sometimes, as I said, everything passes successfully and a copy is created with all attachments, but very rarely - Max Yu
  • What are you doing 1. with spaces if there are spaces in the folder name? 2. Try to put the mask *.* Instead of * Wind for some reason, it does not perceive one *. - nick_n_a