CopyFileEx COPY_FILE_RESTARTABLE

Тема в разделе "MS Visual C++", создана пользователем Sasha, 14 ноя 2004.

Статус темы:
Закрыта.
  1. Sasha

    Sasha Гость

    Не удается продолжить "докачку" файла после ее

    прерывания.
    В MSDN было сказано что при возврате из функции

    CopyProgressRoutine значения PROGRESS_STOP

    копирование может быть перезапущено позже ("Stop

    the copy operation. It can be restarted at a later time."). Но

    этого не происходит.
    При этом в функции CopyFileEx стоит флаг

    COPY_FILE_RESTARTABLE (Progress of the copy is

    tracked in the target file in case the copy fails. The failed

    copy can be restarted at a later time by specifying the same

    values for lpExistingFileName and lpNewFileName as

    those used in the call that failed.
    ).
    ВНИМАНИЕ: НЕ работает в Win9x.
    Предлагаю простой пример в консоле (Сохраните этот код под именем [Name].cpp и откомпилируйте):
    Код (Text):
    #define _WIN32_WINNT 0x0400
    #include <windows.h>
    #include <conio.h>
    #include <iostream>

    //////////////////////////////////////////
    //Поменяйте пути для файлов здесь/////////
    // 1 - исходный большой файл /////////////
    // 2 - файл, в который копировать 1-й ////
    //////////////////////////////////////////
    #define STRING_FROM "e:\\Соседка.avi"
    #define STRING_TO "e:\\Соседка2.avi"

    // Global Variables:
    int nCPRRet;
    DWORD dwThreadId;
    HANDLE hThread;
    char szFileFrom[260];
    char szFileTo[260];
    HWND hWnd;

    // Forward declarations of functions included in this code module:
    DWORD ErrorHandler(char *szTitle);
    DWORD WINAPI ThreadFunc( LPVOID lpParam );
    DWORD CALLBACK CopyProgressRoutine(LARGE_INTEGER, LARGE_INTEGER, LARGE_INTEGER StreamSize, LARGE_INTEGER, DWORD, DWORD, HANDLE, HANDLE, LPVOID);

    void CreateThread(void);
    void TerminateThread(void);
    void SetProgressReturn(int nRet);
    #define ExitProgram {std::cout << "Exit program" << std::endl;break;}
    void ShowHelp();

    int main(int argc, char* argv[])
    {
    lstrcpy(szFileFrom, STRING_FROM);
    lstrcpy(szFileTo, STRING_TO);
    ShowHelp();
    hWnd = GetForegroundWindow();
    while (TRUE)
    {
    int chChar = getch();
    if (chChar == '1')
    SetProgressReturn(PROGRESS_CONTINUE);
    if (chChar == '2')
    SetProgressReturn(PROGRESS_CANCEL);
    if (chChar == '3')
    SetProgressReturn(PROGRESS_STOP);
    if (chChar == '4')
    SetProgressReturn(PROGRESS_QUIET);
    if (chChar == '7')
    CreateThread();
    if (chChar == '9')
    TerminateThread();
    if (chChar == '0')
    ExitProgram;
    }
    CloseHandle(hThread);
    return 0;
    }

    DWORD CALLBACK CopyProgressRoutine(
    LARGE_INTEGER TotalFileSize,     // file size
    LARGE_INTEGER TotalBytesTransferred, // bytes transferred
    LARGE_INTEGER StreamSize,       // bytes in stream
    LARGE_INTEGER StreamBytesTransferred, // bytes transferred for stream
    DWORD dwStreamNumber,         // current stream
    DWORD dwCallbackReason,        // callback reason
    HANDLE hSourceFile,          // handle to source file
    HANDLE hDestinationFile,       // handle to destination file
    LPVOID lpData             // from CopyFileEx
    )
    {
    //if (dwCallbackReason == CALLBACK_CHUNK_FINISHED)
    //{
    //  std::cout << "CALLBACK_CHUNK_FINISHED" << std::endl;
    //}
    if (dwCallbackReason == CALLBACK_STREAM_SWITCH)
    {
    std::cout << "CALLBACK_STREAM_SWITCH" << std::endl;
    }
    char str[256+1];
    sprintf(str, "%02d %% : %3d Mb / %3d Mb", (int)((TotalBytesTransferred.QuadPart*100) / TotalFileSize.QuadPart), (int)TotalBytesTransferred.QuadPart/1024/1024, (int)TotalFileSize.QuadPart/1024/1024);
    SetWindowText(hWnd, str);
    return nCPRRet;
    }

    DWORD WINAPI ThreadFunc( LPVOID lpParam )
    {
    int nRet = CopyFileEx(szFileFrom, szFileTo, CopyProgressRoutine, (LPVOID)NULL, NULL/*&bCancel*/, COPY_FILE_RESTARTABLE);
    if (!nRet)
    ErrorHandler("01");
     return nRet;
    }

    DWORD ErrorHandler(char *szTitle)
    {
    LPVOID lpMsgBuf;
    DWORD dwError;
    FormatMessage(
    FORMAT_MESSAGE_ALLOCATE_BUFFER |
    FORMAT_MESSAGE_FROM_SYSTEM |
    FORMAT_MESSAGE_IGNORE_INSERTS,
    NULL,
    dwError=GetLastError(),
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
    (LPTSTR) &lpMsgBuf,
    0,
    NULL
    );
    // Process any inserts in lpMsgBuf.
    // ...
    // Display the string.
    MessageBox( NULL, (LPCTSTR)lpMsgBuf, szTitle, MB_OK | MB_ICONINFORMATION );
    // Free the buffer.
    LocalFree( lpMsgBuf );
    return dwError;
    }

    void CreateThread(void)
    {
    hThread = CreateThread(
    NULL,            // no security attributes
    0,              // use default stack size
    ThreadFunc,         // thread function
    0,              // argument to thread function
    0,              // use default creation flags
    &dwThreadId);        // returns the thread identifier
    if (!hThread)
       ErrorHandler("02");
    else
    std::cout << "Created thread successefully" << std::endl;
    }

    void SetProgressReturn(int nRet)
    {
    switch (nRet)
    {
    case PROGRESS_CONTINUE:
    nCPRRet = PROGRESS_CONTINUE;
    std::cout << "PROGRESS_CONTINUE" << std::endl;
    break;
    case PROGRESS_CANCEL:
    nCPRRet = PROGRESS_CANCEL;
    std::cout << "PROGRESS_CANCEL" << std::endl;
    break;
    case PROGRESS_STOP:
    nCPRRet = PROGRESS_STOP;
    std::cout << "PROGRESS_STOP" << std::endl;
    break;
    case PROGRESS_QUIET:
    nCPRRet = PROGRESS_QUIET;
    std::cout << "PROGRESS_QUIET" << std::endl;
    break;
    default:
    std::cout << "*цензура*!" << std::endl;
    exit(1);
    }
    }

    void ShowHelp()
    {
    std::cout << "Set return value for the CopyProgressRoutine(...):" << std::endl;
    std::cout << "1 - PROGRESS_CONTINUE" << std::endl;
    std::cout << "2 - PROGRESS_CANCEL" << std::endl;
    std::cout << "3 - PROGRESS_STOP" << std::endl;
    std::cout << "4 - PROGRESS_QUIET" << std::endl;
    std::cout << std::endl;
    std::cout << "7 - Start CopyFileEx function in another thread" << std::endl;
    std::cout << "9 - Terminate thread" << std::endl;
    std::cout << "0 - Exit programm" << std::endl;
    std::cout << "V    MSDN: 1,7,2 - \"PROGRESS_STOP - Stop the copy operation. It can be restarted at a later time.\" Eto v HELPe po funkcii CopyProgressRoutine(...)" << std::endl;
    std::cout << "Moi deistviya: 1,7  - no nachinaetsya s 00%, skolko bi ya ne skopiroval v pervij raz." << std::endl;
    }

    void TerminateThread(void)
    {
    if (!TerminateThread(hThread, 0))
    ErrorHandler("03");
    }
     
Статус темы:
Закрыта.

Поделиться этой страницей