Преместете файл, AX2012

Опитвам се да преместя файл, нищо умно.

Проблемът, който имам, е обяснен в блога на AX WONDERS.

Причината за това е, че когато се използва AX клас, който се изпълнява на сървъра, изключението никога не се връща към клиента и следователно не може да бъде обработено правилно.... операцията няма да попадне в изключението Exception::CRLError

Ако изходният файл се отвори от MSWord, например, се хвърля изключение в метода fileLocked, което е едновременно вбесяващо, но и забавно.

Всякакви предложения са добре дошли!

Малко код:

server static void moveFile(str fileName, str newFileName)
{
    #File
    Set                 permissionSet;
    ;

    permissionSet =  new Set(Types::Class);
    //permissionSet.add(new FileIOPermission(fileName,#io_write));
    permissionSet.add(new FileIOPermission('',#io_write));
    permissionSet.add(new InteropPermission(InteropKind::ClrInterop));

    CodeAccessPermission::assertMultiple(permissionSet);

    if (isRunningOnServer()) 
    { 
        if (WinAPIServer::fileExists(newFileName))
            WinAPIServer::deleteFile(newFileName);
        WinAPIServer::copyFile(fileName, newFileName);
        if (!WinAPIServer::fileLocked(fileName))
            WinAPIServer::deleteFile(fileName);
    }
    else
    {
        if (WinApi::fileExists(newFileName))
            WinApi::deleteFile(newFileName);
        WinAPI::copyFile(fileName, newFileName);
        if (!WinAPI::fileLocked(fileName))
            WinAPI::deleteFile(fileName);
    }
    //System.IO.File::Move(fileName, newFileName);

    CodeAccessPermission::revertAssert();
}

Регистър за грешки:

System.IO.IOException: The process cannot access the file 'M:\Interfaces\Prod\ImportacionClientes\Direcciones\XXXXXXAD_20130711_1136.TXT' because it is being used by another process.

   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)

   at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)

   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)

   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)

   at System.IO.File.OpenWrite(String path)

   at Dynamics.Ax.Application.WinAPIServer.fileLocked(String _fileName) in WinAPIServer.fileLocked.xpp:line 33

   at Dynamics.Ax.Application.EVE_UlaboxInterfaceClientes_IN.moveFile(String fileName, String newFileName) in EVE_UlaboxInterfaceClientes_IN.moveFile.xpp:line 19

person ian_scho    schedule 14.07.2013    source източник
comment
Защо това изтриване, копиране, изтриване?   -  person Jan B. Kjeldsen    schedule 15.07.2013
comment
Само едно просто „Преместване“ би било по-добре, съгласен съм. Но първото изтриване е да се гарантира, че дестинацията е свободна, преди да копирате файла.   -  person ian_scho    schedule 15.07.2013
comment
След това първо направете System.IO.File::Delete(newFileName);. Не забравяйте да хванете CLRError.   -  person Jan B. Kjeldsen    schedule 04.08.2013


Отговори (3)


Бих отишъл за

 System.IO.File::Move(fileName, newFileName);

вместо да е много умен. Помислете за предишното съществуване на newFileName грешка.

Не използвайте файловите методи WinAPI в сървърен или партиден контекст (проверихте това).
Използването на WinAPI и WinAPIServer е твърде болезнено, отидете направо към .Net методите.

Най-вероятно fileLocked е в грешка.

person Jan B. Kjeldsen    schedule 14.07.2013

Опитвате се да осъществите достъп до newFileName, без да изисквате разрешения за него. Освен това методът isRuningOnServer() не работи както се очаква във всички случаи по време на пакетна обработка, така че бих проучил дали работи добре във вашия случай.

person j.a.estevan    schedule 24.07.2013

TextIo и неговите базови класове не освобождават блокировката за четене на файл, когато се използват в пакет, дори ако присвоите на обекта null.

Пренапишете импортирането със StreamReader и използвайте .close() и .dispose() и ще работи.

Редактиране: Извикването на finalize() на TextIo ще затвори файла, също и когато се изпълнява в пакет.

person Pontus    schedule 14.10.2014