Skip to main content
Dynamics 365

MagicPath (DOWNLOADFROMSTREAM and UPLOADINTOSTREAM without a dialog box)

The C/AL commands DOWNLOADFROMSTREAM and UPLOADINTOSTREAM have the purpose of sending files between RTC and the NAV Server. A few times now, we had the question: How can we use these functions without it displaying the dialog box to select a file and folder name?

This is how you can automatically download and upload files without any user interactions:

The trick is to use MagicPath, like in codeunit 419 “3-Tier Automation Mgt.”. MagicPath is initiated by setting the folder name to ‘<TEMP>’ like this:
DOWNLOADFROMSTREAM(IStream,”,‘<TEMP>’, ”,MagicPath);

DOWNLOADFROMSTREAM

The code example below will copy a specific file from the NAV Server to the RTC machine with no questions asked about folder or file name or anything else:

IF NOT ISSERVICETIER THEN
EXIT;
FileToDownload := ‘c:\Temp\ServerFile.txt’;
FileVar.OPEN(FileToDownload);
FileVar.CREATEINSTREAM(IStream);
DOWNLOADFROMSTREAM(IStream,,‘<TEMP>’, ,MagicPath);
MESSAGE(‘Path = ‘ + MagicPath);

FileVar.CLOSE;

Variables:

Name Data Type Length
FileToDownload Text 180
FileVar File
IStream InStream
MagicPath Text 180

Now we have the file on the RTC machine, and MagicPath tells us its location. The location will be something like this:
C:\Users\[UserName]\AppData\Local\Temp\Microsoft Dynamics NAV\4612\__TEMP__ff7c5a286cfd463f9f7d92ae5b4757e2

The number 4612 in the MagicPath comes from the Process ID of RTC.

Handling files client side

So, what if we wanted to rename it to a specific name? We have the FILE object in C/AL, but of course since C/AL runs on the NAV Server and not on RTC, this won’t work since the purpose of the above is exactly to copy the file to the client machine. Instead, use this automation:

‘Microsoft Scripting Runtime’.FileSystemObject

Then create an instance ClientSide:
CREATE(FileSystemObject,TRUE,TRUE);

So, if you wanted to continue the code above and place and name the file to something specific on the client’s machine, add these lines:

CREATE(FileSystemObject,TRUE,TRUE);
DestinationFileName := ‘c:\Temp\newfile.txt’;
IF FileSystemObject.FileExists(DestinationFileName) THEN
FileSystemObject.DeleteFile(DestinationFileName,TRUE);
FileSystemObject.CopyFile(MagicPath,DestinationFileName);
FileSystemObject.DeleteFile(magicpath,TRUE);

UPLOADINTOSTREAM

MagicPath works both ways. But with DOWNLOADFROMSTREAM it creates MagicPath for you and tells you where it is. With UPLOADINTOSTREAM you need to know it in advance. Remember the MagicPath location above includes the Process ID of RTC. One way could be to work that out somehow. But what I would suggest instead, is to download a temp test file first, then see where MagicPath downloads it to. The path for upload will be the same:

// download a temp file to get MagicPath
FileVar.CREATETEMPFILE;
FileVar.CREATEINSTREAM(IStream);
DOWNLOADFROMSTREAM(IStream,,‘<TEMP>’, ,MagicPath);
FileVar.CLOSE;
MESSAGE(MagicPath);

Then extract the folder name from MagicPath:

FOR i := STRLEN(MagicPath) DOWNTO 1 DO BEGIN
IF MagicPath[i] = ‘\’ THEN BEGIN
MagicPath := COPYSTR(MagicPath,1,i);
i := 1;
END;
END;

Once you know the location of MagicPath, the next step is to copy the file you want to upload into that folder:

FileToUpload := ‘newfile.txt’;
FolderName := ‘c:\Temp\’;

IF ISCLEAR(FileSystemObject) THEN
CREATE(FileSystemObject,TRUE,TRUE);
FileSystemObject.CopyFile(FolderName + ‘\’ + FileToUpload,MagicPath + ‘\’ + FileToUpload);

Then use UPLOADINTOSTREAM to upload the file from MagicPath to the NAV Server:
UPLOADINTOSTREAM(,‘<TEMP>’,,FileToUpload,IStream);

And finally, save the InStream to a file on the server:

FileVar.WRITEMODE(TRUE);
FileVar.CREATE(‘c:\Temp\OnServer.txt’);
FileVar.CREATEOUTSTREAM(OStream);
COPYSTREAM(ostream,istream);
FileVar.CLOSE;

So, put all this together and the end result is:

The file c:\Temp\ServerFile.txt gets downloaded to C:\Temp\NewFile.txt, and then uploaded back to the server as C:\Temp\OnServer.txt.