问题
I'm trying to move a file, nothing clever.
The problem I am having is explained in the AX WONDERS blog.
The reason for this is that when using an AX class that runs on the server, the exception never comes back to the client and therefore cannot be handled correctly.... the operation will not fall into the Exception::CRLError exception
If the source file is opened by MSWord, for example, an exception is thrown in the fileLocked method, which is both infuriating yet amusing.
Any suggestions most welcome!
Some code:
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();
}
Error registry:
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
回答1:
I would go for the
System.IO.File::Move(fileName, newFileName);
instead of being to clever.
Consider the prior existence of the newFileName
an error.
Don't use the WinAPI
file methods in a server or batch context (you checked that).
Using both WinAPI
and WinAPIServer
is just too painful, go straight for the .Net methods.
Most likely the fileLocked
is in error.
回答2:
You're trying to access the newFileName
without asserting permissions on it. Moreover, the isRuningOnServer()
method doesn't work as expected in all cases during batch processing, so I would investigate if it's working fine in your case.
回答3:
TextIo and the it's base classes don't release the file read lock when used in batch even if you assign the object null.
Rewrite the import with StreamReader and use .close() and .dispose() and it will work.
Edit: Calling finalize() on TextIo will close the file, also when running in batch.
回答4:
System.IO.File::Move(fileName, newFileName);
来源:https://stackoverflow.com/questions/17637619/move-a-file-ax2012