2016-02-24 6 views
-1

CopyFileEx со следующим вызовом GetLastError возвращает ERROR_INVALID_PARAMETER, даже если копия удалась на Win2012R2, начиная примерно с 2 месяцев назад (возможно, с декабря 2015 года). В Windows XP до Windows 7 и Win 2k3 до Win2k8R2 этого не происходит, и GetLastError всегда возвращает 0 (ERROR_SUCCESS).CopyFileEx возвращает ERROR_INVALID_PARAMETER, даже если копия прошла успешно на Win2012R2

Является ли это ожидаемым поведением такого типа API Win32? Вам нужно добавить код результата и GetLastError, чтобы убедиться в его результатах?

Этот КБ кажется связанным с проблемой, но применение этого патча не изменяет поведение API. Был, вероятно, еще один KB, что вызвало проблемы появляются, но я не смог найти его https://support.microsoft.com/en-us/kb/2963918

Документация для GetLastError:

Return value

The return value is the calling thread's last-error code.

The Return Value section of the documentation for each function that sets the last-error code notes the conditions under which the function sets the last-error code. Most functions that set the thread's last-error code set it when they fail. However, some functions also set the last-error code when they succeed. If the function is not documented to set the last-error code, the value returned by this function is simply the most recent last-error code to have been set; some functions set the last-error code to 0 on success and others do not.

+0

Возможно, что ProgressCallBackRoutine установит ошибку. Но я полагаю, что это называется другой нитью? (и, следовательно, не видно из вызывающего потока?) Или является обратным вызовом текущего потока и операции копирования на другом? Или оба одинаковы? (тогда длительная операция пользовательского интерфейса в обратном вызове может замедлить работу) –

+0

В [документации] (https://msdn.microsoft.com/en-us/library/windows/desktop/aa363852.aspx) указано, что вы вызываете ' GetLastError' только с ошибкой. Вызов его после успешного завершения «CopyFileEx» не дает четко определенного значения. Ваш код зависит от неуказанного поведения и просто не повезло в одной системе. Это глючит, и вам нужно это исправить. В API нет ничего плохого. – IInspectable

+0

@Inpectable CopyFileEx не владеет результатом потоков LastErrorCode. Любой вызов в одном потоке может установить его на ошибки. Документация для CopyFileEx подразумевает, что LastErrorCode не затрагивается в случае успеха, устанавливается только в случае сбоя. Это означает, что либо что-то внутренне в CopyFileEx терпит неудачу, либо мой собственный Callback не удается (если он находится в одном потоке). –

ответ

3

От documentation:

Return value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information call GetLastError.

Другими словами , если функция завершается успешно, вы не должны звонить GetLastError, и не обещаете, что будет возвращено, если вы это сделаете.

Итак, вы приписываете значение значению, возвращаемому GetLastError, где не должно быть приписано никакого значения.

Это общий шаблон в Win32. Очень много функций аналогичны. Значение, возвращаемое GetLastError, имеет смысл только в том случае, если возвращаемое значение функции указывает на сбой. Однако это не универсальное правило, поэтому вам нужно проверить документацию по функции по функциям.

Типичная форма вызова такой функции Win32 выглядит следующим образом:

if (CopyFileEx(...)) 
{ 
    // function call succeeded, continue 
} 
else 
{ 
    DWORD err = GetLastError(); 
    // do something with err 
} 

Обратите внимание, что GetLastError вызывается только тогда, когда функция указывает на неисправность через возвращаемое значение.

+0

Когда я прочитал документацию для GetLastError, он заявляет, что некоторые функции используют его для установки 0 для успеха. И, как вы говорите, в документации для CopyFileEx не указано, что она установит ERROR_SUCCESS для успешной копии. Но ни в одной документации не говорится, что CopyFileEx установит последнюю ошибку в фактический код ошибки, если он НЕ сбой. Если Microsft не закодировал ошибку во внутреннем коде, который внутренне получает ошибку (по ней). Эта MS будет называть что-то с недопустимым параметром internall еще хуже в моей книге, если это то, что подразумевается? –

+0

Когда CopeFileEx успешно, последнее значение кода ошибки не определено. –

+0

Не об этом я знаю? Если CopyFileEx преуспевает, он не устанавливает последнюю ошибку вообще. Для последней ошибки нет значения нежелательной почты, и она не может быть неопределенной, так как она принадлежит вызывающему потоку. Если вызывающий (меня) не установил его, и он был изменен до и после вызова CopyFileEx, то другой вызов API внутри CopyFileEx установил его в код ошибки. –

 Смежные вопросы

  • Нет связанных вопросов^_^