![]() |
#1 |
Участник
|
![]()
После вызова WinAPI-й ф-ции CopyFile независимо от успешности ее работы WinAPI::getLastError() всегда возвращает 0, а результат меня всё-таки интересует
![]() Вроде нашел инфо, что сия ошибка была исправлена в SP2-м, но у меня SP3 и тем не менее приходится обращаться за помощью ![]() Заранее благодарен за ответ ![]() |
|
![]() |
#2 |
Moderator
|
Незнаю насколько поможет, но вот немного информации (несколько сумбурно)
WinApi::getLastError() |
|
![]() |
#3 |
Участник
|
А вы getLastError() вызываете после вызова метода (извиняюсь за тавтологию)?
__________________
Axapta v.3.0 sp5 kr2 |
|
![]() |
#4 |
Участник
|
DreamCreator - я это читал, но там всё начинается как раз с куска аннотации к SP2 об исправлении ошибки GetLastError, а потом рассказ о том, что собственно сия ф-ция представляет, что гораздо полнее изложено в MSDN
![]() AndyD - да, сразу после, причём убедившись, что CopyFile вернуло 0, т.е. согласно MSDN произошла ошибка - я и сам знаю что пытаюсь переписать файл, открытый в другом приложении, но мне нужно, чтобы об этом мне сообщила Аксапта ![]() |
|
![]() |
#5 |
Участник
|
Сразу не спросил - вы вызываете метод CopyFile из класса WinApi или написали собственную оболочку для него?
Дело в том, что в реализации WinApi сделано так X++: if (_copyFile.call(fileName, newFileName, !overwrite ) == 0) return WinAPI::getLastError(); return 0; Т.е. получается перевернутая схема возвращения значения. Если у вас своя реализация - приведите ее.
__________________
Axapta v.3.0 sp5 kr2 |
|
![]() |
#6 |
Участник
|
Весь текст:
static void Job123(Args _args) { str sMsg; sMsg = WinAPI::copyFile_FRM('D:\\2776.dbf', 'D:\\Clients\\TempFile.dbf', true ); box::info(sMsg); } client server static str copyFile_FRM(str fileName, str newFileName, boolean bFailIfExists = TRUE) { DLL _winApiDLL = new DLL('KERNEL32'); DLLFunction _copyFile = new DLLFunction(_winApiDLL, 'CopyFileA'); Int iErr; str sErrMsg = ""; _copyFile.returns(ExtTypes: ![]() _copyFile.arg(ExtTypes::String, ExtTypes::String, ExtTypes: ![]() if (_copyFile.call(fileName, newFileName, bFailIfExists ) == 0) { iErr = WinAPI::getLastError(); sErrMsg = WinAPI::formatMessage(iErr) ; } return sErrMsg; } |
|
![]() |
#7 |
Участник
|
Проверил ваш код - у меня успешно отрабатывает (в смысле, если есть ошибка при копировании - то выдает соответствующее сообщение)
Кстати, чтобы эта функция не смогла переписать файл, необходимо, чтобы файл был открыт другим процессом не в режиме совместимости FILE_SHARE_READ или был заблокирован полностью или частично (с помощью фунции LockFile)
__________________
Axapta v.3.0 sp5 kr2 |
|
![]() |
#8 |
Участник
|
1.Переставил SP3, после чего проверил версии основных файлов:
ax32.exe, ax32serv.exe и AxCom.dll - 3.0.1951.3733 , что соответствует Axapta 3.0 CIS SP3 CU1 2.В фаре создал по Shift+F4 файл TempFile.dbf в каталоге D:\Clients\, сразу нажал F2 и вышел из фаровского редактора. Полученный таким образом файл нулевой длины открываю MS Word, набрав в ком строке winword.exe TempFile.dbf и таким образом этот файл блокирую. 3. Запускаю джобик: static void Job123(Args _args){; WinAPI::copyFile_FRM('D:\\2776.dbf', 'D:\\Clients\\TempFile.dbf', true ); } , где на второй строчке предварительно устанавливаю точ. Останова. 4.Пройдя пошагово до строк: if (_copyFile.call(fileName, newFileName, bFailIfExists ) == 0) { iErr = WinAPI::getLastError(); благополучно захожу в if и в iErr получаю всё тот же «0», на который formatMessage возвращает радостное сообщение о том, что операция успешно завершена. А у Вас, AndyD, такой номер получается или на 4-м шаге всё-таки вернётся не «0»? Заранее благодарен (самого достала эта заноза ![]() |
|
![]() |
#9 |
Участник
|
Отрабатывает с сообщением об ошибке.
Версия такая же как у вас, только билд другой 3.0.1951.3730 Проверял так же на SP5 c роллапом 2 - тоже отрабатывает с сообщением об ошибке
__________________
Axapta v.3.0 sp5 kr2 |
|
![]() |
#10 |
Участник
|
При абсолютно такой-же последовательности действий?
|
|
![]() |
#11 |
Участник
|
Угу
Файл только создавал в другой проге. Но это не важно
__________________
Axapta v.3.0 sp5 kr2 |
|
![]() |
#12 |
Участник
|
После сообщения AndyD сделал то, что нужно было сделать с самого начала – посмотрел код по слоям. И обнаружил свинью, подложенную разработчиком.
Итак: На SYS слое остался оригинальный код (до SP2) client server static int getLastError() { DLL _winApiDLL = new DLL('KERNEL32'); DLLFunction _getLastError = new DLLFunction(_winApiDLL, 'GetLastError'); _getLastError.returns(ExtTypes: ![]() return _getLastError.call(); } На SYP слое SP2 благополучно исправил ошибку – мол между вызовом файловых функций (например копирование) и getLastError Аксапта вызвает ещё кучу всего и таким образом это значение сбивает. Во 2-м SP значение getLastError кэшируется. client server static int getLastError() { // Syp Modifications - SP2 - BEGIN // DLL _winApiDLL = new DLL('KERNEL32'); // DLLFunction _getLastError = new DLLFunction(_winApiDLL, 'GetLastError'); // // _getLastError.returns(ExtTypes: ![]() // // return _getLastError.call(); return DLL::lastDLLError(); // Syp Modifications - SP2 – END } Но на VAR слое наш разработчик ничтоже сумятише вернул в зад эти исправления по какой-то ему одному ведомой причине: client server static int getLastError() { // вернул все назад. а токакой-то криворукий вызов метода класса DDL сделал, а сам метод создать звбыл. повбывав бы! // Syp Modifications - SP2 - BEGIN DLL _winApiDLL = new DLL('KERNEL32'); DLLFunction _getLastError = new DLLFunction(_winApiDLL, 'GetLastError'); _getLastError.returns(ExtTypes: ![]() return _getLastError.call(); // return DLL::lastDLLError(); // Syp Modifications - SP2 - END } Вот так-то – удивительные рядом! Впредь буду изучать слой наших разработчиков прежде чем морочить голову отзывчивым людям из AxForum ![]() |
|