Bojensen Blogs

Art Of Creation – Dynamics AX Blog » How to print any file in Dynamics AX


So you need to print some files from Dynamics AX? And it also has to work in batch?
Below are 2 methods that will help you do just that.

Printing text files using the copy method

This was the first method I used, and it works flawlessly when using text files, such as .txt or .csv files. It also works great on .prn files.
To print such a file, you can simple copy the file to the printer. See example code below.

static void KlFor_PrintUsingCopy(Args _args) { // use only for text files #File Set permissionSet; System.Exception interopException; FileName destinationFileName; // parameters Filename fileName = @"C:\text.txt"; PrinterName printername = @"\\PrintServer\YourPrinter"; ; try { // combine the destination path using the printer and the filename new InteropPermission(InteropKind::ClrInterop).assert(); destinationFileName = System.IO.Path::Combine(printerName, System.IO.Path::GetFileName(fileName)); CodeAccessPermission::revertAssert(); // then copy the file permissionSet = new Set(Types::Class); permissionSet.add(new FileIOPermission(fileName,#io_write)); permissionSet.add(new FileIOPermission(destinationFileName,#io_write)); permissionSet.add(new InteropPermission(InteropKind::ClrInterop)); CodeAccessPermission::assertMultiple(permissionSet); System.IO.File::Copy(fileName, destinationFileName); CodeAccessPermission::revertAssert(); } catch(Exception::CLRError) { // catch CLR errors and show inner exception interopException = CLRInterop::getLastException(); while (!CLRInterop::isNull(interopException.get_InnerException())) { interopException = interopException.get_InnerException(); } error(strFmt("%1", CLRInterop::getAnyTypeForObject(interopException.get_Message()))); } }

An easy method, but do not use it on binary file types. Doing this would result in and endless stream of pages with unreadable characters on it. Yes… I’ve tried.

Print any file use System.Diagnostics.Process

A better way to print files is using the System.Diagnostics namespace. This example uses the “printto” verb to print the files to the server. This verb is visible in the context menu when you right click on a file, it will be listed as the option “Print”. Basically we are using Windows this functionality together with file extension associations to automatically print any file type.
A prerequisite is that an application is available that can open and print the files you want to print. If for example you want to print PDF files in batch using this method, you should install PDF reader software on the AOS server.

static void KlFor_PrintUsingSystemDiagnostics(Args _args) { #File System.Diagnostics.ProcessStartInfo processInfo; System.Diagnostics.Process process; System.Exception interopException; // Parameters Filename fileName = @"C:\text.txt"; PrinterName printername = @"\\PrintServer\YourPrinter"; ; printerName = '"' + printerName + '"'; try { // assert permissions new InteropPermission(InteropKind::ClrInterop).assert(); process = new System.Diagnostics.Process(); processInfo = process.get_StartInfo(); processInfo.set_UseShellExecute(true); processInfo.set_CreateNoWindow(true); processInfo.set_FileName(fileName); // the argument is the printer name processInfo.set_Arguments(printerName); // set the verb to printto processInfo.set_Verb('printto'); processInfo.set_WindowStyle(System.Diagnostics.ProcessWindowStyle::Hidden); process.Start(); // revert asserted permissions CodeAccessPermission::revertAssert(); } catch(Exception::CLRError) { interopException = CLRInterop::getLastException(); while (!CLRInterop::isNull(interopException.get_InnerException())) { interopException = interopException.get_InnerException(); } error(strFmt("@RDS10563", fileName, CLRInterop::getAnyTypeForObject(interopException.get_Message()))); } }

You can use the code above to do many other things .The functionality is similar to shellexecute, only neater. If you are interested in modifying the code for other purposes using other verbs, you can figure out what verbs you can use using the job below. You will notice that the verbs that are available depend on the extension the file is using.

static void KlFor_GetAllVerbsForFile2(Args _args) { System.Diagnostics.ProcessStartInfo processInfo; System.Array verbs; int i; List fileNames; container verbsContainer; ListEnumerator listEnumerator; fileNames = new List(Types::String); fileNames.addEnd(".xlsx"); fileNames.addEnd(".docx"); fileNames.addEnd(".png"); fileNames.addEnd(".txt"); fileNames.addEnd(".pdf"); listEnumerator = fileNames.getEnumerator(); new InteropPermission(InteropKind::ClrInterop).assert(); while(listEnumerator.moveNext()) { processInfo = new System.Diagnostics.ProcessStartInfo(listEnumerator.current()); verbs = processInfo.get_Verbs(); verbsContainer = conNull(); for( i=0; i<ClrInterop::getAnyTypeForObject(verbs.get_Length()); i++ ) { verbsContainer += ClrInterop::getAnyTypeForObject(verbs.GetValue(i)); } info(strFmt("%1 has verbs: %2", listEnumerator.current(), con2Str(verbsContainer))); } CodeAccessPermission::revertAssert(); }

It takes a while to figure out how to do these things so hopefully this will save someone the trouble of going through that.

Art Of Creation – Dynamics AX Blog » How to print any file in Dynamics AX

Comments are closed.