15.02.2007, 17:07 | #1 |
Участник
|
WinAPI::getLastError() всегда возвращает 0
После вызова WinAPI-й ф-ции CopyFile независимо от успешности ее работы WinAPI::getLastError() всегда возвращает 0, а результат меня всё-таки интересует
Вроде нашел инфо, что сия ошибка была исправлена в SP2-м, но у меня SP3 и тем не менее приходится обращаться за помощью , поелико не хотелось бы извращаться и проверять успешность копирования косвенными методами. Заранее благодарен за ответ |
|
15.02.2007, 17:19 | #2 |
Moderator
|
Незнаю насколько поможет, но вот немного информации (несколько сумбурно)
WinApi::getLastError() |
|
15.02.2007, 17:48 | #3 |
Участник
|
А вы getLastError() вызываете после вызова метода (извиняюсь за тавтологию)?
__________________
Axapta v.3.0 sp5 kr2 |
|
15.02.2007, 18:18 | #4 |
Участник
|
DreamCreator - я это читал, но там всё начинается как раз с куска аннотации к SP2 об исправлении ошибки GetLastError, а потом рассказ о том, что собственно сия ф-ция представляет, что гораздо полнее изложено в MSDN
AndyD - да, сразу после, причём убедившись, что CopyFile вернуло 0, т.е. согласно MSDN произошла ошибка - я и сам знаю что пытаюсь переписать файл, открытый в другом приложении, но мне нужно, чтобы об этом мне сообщила Аксапта |
|
15.02.2007, 20:20 | #5 |
Участник
|
Сразу не спросил - вы вызываете метод CopyFile из класса WinApi или написали собственную оболочку для него?
Дело в том, что в реализации WinApi сделано так X++: if (_copyFile.call(fileName, newFileName, !overwrite ) == 0) return WinAPI::getLastError(); return 0; Т.е. получается перевернутая схема возвращения значения. Если у вас своя реализация - приведите ее.
__________________
Axapta v.3.0 sp5 kr2 |
|
16.02.2007, 12:01 | #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:Word); _copyFile.arg(ExtTypes::String, ExtTypes::String, ExtTypes:Word); if (_copyFile.call(fileName, newFileName, bFailIfExists ) == 0) { iErr = WinAPI::getLastError(); sErrMsg = WinAPI::formatMessage(iErr) ; } return sErrMsg; } |
|
18.02.2007, 14:32 | #7 |
Участник
|
Проверил ваш код - у меня успешно отрабатывает (в смысле, если есть ошибка при копировании - то выдает соответствующее сообщение)
Кстати, чтобы эта функция не смогла переписать файл, необходимо, чтобы файл был открыт другим процессом не в режиме совместимости FILE_SHARE_READ или был заблокирован полностью или частично (с помощью фунции LockFile)
__________________
Axapta v.3.0 sp5 kr2 |
|
19.02.2007, 16:53 | #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»? Заранее благодарен (самого достала эта заноза ) |
|
19.02.2007, 17:25 | #9 |
Участник
|
Отрабатывает с сообщением об ошибке.
Версия такая же как у вас, только билд другой 3.0.1951.3730 Проверял так же на SP5 c роллапом 2 - тоже отрабатывает с сообщением об ошибке
__________________
Axapta v.3.0 sp5 kr2 |
|
20.02.2007, 10:47 | #10 |
Участник
|
При абсолютно такой-же последовательности действий?
|
|
20.02.2007, 11:15 | #11 |
Участник
|
Угу
Файл только создавал в другой проге. Но это не важно
__________________
Axapta v.3.0 sp5 kr2 |
|
23.02.2007, 13:06 | #12 |
Участник
|
После сообщения AndyD сделал то, что нужно было сделать с самого начала – посмотрел код по слоям. И обнаружил свинью, подложенную разработчиком.
Итак: На SYS слое остался оригинальный код (до SP2) client server static int getLastError() { DLL _winApiDLL = new DLL('KERNEL32'); DLLFunction _getLastError = new DLLFunction(_winApiDLL, 'GetLastError'); _getLastError.returns(ExtTypes:Word); 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:Word); // // 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:Word); return _getLastError.call(); // return DLL::lastDLLError(); // Syp Modifications - SP2 - END } Вот так-то – удивительные рядом! Впредь буду изучать слой наших разработчиков прежде чем морочить голову отзывчивым людям из AxForum ) . |
|