As most of you are aware by now, AX 2012 makes extensive use of .NET CIL to perform various functions within the system e.g. the AIF framework, AX Batch Server, AX SSRS Reports, etc – all of these components now run as .NET CIL instead of X++ code.
This has made it increasingly important to regularly compile your X++ code into CIL using either of the following methods:
This can end up being an extremely painful process, as it normally requires this task to be performed outside of working hours, and for somebody to stay up late to wait for the Full System Compile to finish so that the CIL compile can be started.
To get around this, we can make use of a batch script that will perform both of these tasks outside of working hours, which can then be scheduled to run nightly.
This blog will provide a basic example of the AX32.exe commands that can be used to perform the required system compilations (FYI – There are several blogs on the internet that talks about creating automated build scripts. These blogs go into a lot more detail about deploying models, loading XPO files, etc. So if you need to perform these tasks, please don’t hesitate to go and check them out).
For my “Lights out” compilation script, I’m going to perform the following very basic tasks:
The following screenshot shows a batch script that performs all of the tasks as summarized above (Each section within the script will be described in more detail later in this blog):
![]()
Script Variables
SET serviceName=AOS60$01
SET aosHost=AX2012-A
SET aosPort=2712
SET appPath=”C:\Program Files (X86)\Microsoft Dynamics AX\60\Client\Bin\AX32.EXE”
The first section of the script should be pretty self-explanatory i.e. 4 variables that are used to identify the name of the AOS Service (as shown in the Services Management snap-in), the server hosting the AOS Server, the Port number assigned to the AOS Server, and then finally the Path to the AX Client executable.
(I’ve included the Host Name and Port number parameters to allow for environments where multiple AOS servers are installed on a single host e.g. a DEV and TEST environments).
Restart AOS Server
net stop %serviceName%
net start %serviceName%
The next section in the script restarts the AOS server. I include this restart step to ensure that the latest label file changes are loaded into the AX Model Store.
Perform Full System Compile
%appPath% -aos2=%aosHost%:%aosPort% -startupcmd=CompileAll_- -lazytableloading -lazyclassloading
Once the AOS service has been restarted, I initiate the Full X++ compile command.
The AX32 executable supports multiple command line parameters (A full listing can be found here). The two significant parameters are: -aos2 AND –startupcmd.
When the AX client starts up, it performs various initialization tasks to improve the overall performance of the client e.g. the system pre-compiles and loads various system tables and classes into memory for quick reference.
This process slows down the initial start-up time of the AX client.
For the purpose of doing a full system compile, these performance optimization tasks performed during start-up doesn’t provide any benefit to us, so by using the –lazytableloading and –lazyclassloading parameters we tell the application to not perform these tasks during start-up.
Perform Full CIL Compile
%appPath% -aos2=%aosHost%:%aosPort% -startupcmd=CompileIl -lazytableloading -lazyclassloading
After the full compile is completed we use the same AX32 command, but this time we use the CompileIL start-up command.
Restart AOS Server
net stop %serviceName%
net start %serviceName%
And finally we restart the AOS service to release all of the system resources that used during the compilation process.
Conclusion
Now there are several enhancements that can be made to this script e.g. checking to see if any errors occurred during the Full X++ compile, and then only initiating the CIL compile if no errors occurred. But this is something for another day.
I hope this proves useful, and let me know if you have any questions.
This has made it increasingly important to regularly compile your X++ code into CIL using either of the following methods:
- Full CIL Generation
- Incremental CIL generation.
This can end up being an extremely painful process, as it normally requires this task to be performed outside of working hours, and for somebody to stay up late to wait for the Full System Compile to finish so that the CIL compile can be started.
To get around this, we can make use of a batch script that will perform both of these tasks outside of working hours, which can then be scheduled to run nightly.
This blog will provide a basic example of the AX32.exe commands that can be used to perform the required system compilations (FYI – There are several blogs on the internet that talks about creating automated build scripts. These blogs go into a lot more detail about deploying models, loading XPO files, etc. So if you need to perform these tasks, please don’t hesitate to go and check them out).
For my “Lights out” compilation script, I’m going to perform the following very basic tasks:


SET serviceName=AOS60$01
SET aosHost=AX2012-A
SET aosPort=2712
SET appPath=”C:\Program Files (X86)\Microsoft Dynamics AX\60\Client\Bin\AX32.EXE”
The first section of the script should be pretty self-explanatory i.e. 4 variables that are used to identify the name of the AOS Service (as shown in the Services Management snap-in), the server hosting the AOS Server, the Port number assigned to the AOS Server, and then finally the Path to the AX Client executable.
(I’ve included the Host Name and Port number parameters to allow for environments where multiple AOS servers are installed on a single host e.g. a DEV and TEST environments).
Restart AOS Server
net stop %serviceName%
net start %serviceName%
The next section in the script restarts the AOS server. I include this restart step to ensure that the latest label file changes are loaded into the AX Model Store.
Perform Full System Compile
%appPath% -aos2=%aosHost%:%aosPort% -startupcmd=CompileAll_- -lazytableloading -lazyclassloading
Once the AOS service has been restarted, I initiate the Full X++ compile command.
The AX32 executable supports multiple command line parameters (A full listing can be found here). The two significant parameters are: -aos2 AND –startupcmd.
- The –aos2 command line parameter is used to tell the AX32 executable which AOS Server to connect to.
- The –startupCmd command line parameter tells the AX32 executable which command to execute during start-up.You will notice that I’ve included a _- at the end of the CompileAll command. This tells AX to perform a full system compile, but NOT update the Cross Reference information. If you want to perform a Cross Reference update, change the value to _+.
When the AX client starts up, it performs various initialization tasks to improve the overall performance of the client e.g. the system pre-compiles and loads various system tables and classes into memory for quick reference.
This process slows down the initial start-up time of the AX client.
For the purpose of doing a full system compile, these performance optimization tasks performed during start-up doesn’t provide any benefit to us, so by using the –lazytableloading and –lazyclassloading parameters we tell the application to not perform these tasks during start-up.
Perform Full CIL Compile
%appPath% -aos2=%aosHost%:%aosPort% -startupcmd=CompileIl -lazytableloading -lazyclassloading
After the full compile is completed we use the same AX32 command, but this time we use the CompileIL start-up command.
Restart AOS Server
net stop %serviceName%
net start %serviceName%
And finally we restart the AOS service to release all of the system resources that used during the compilation process.
Conclusion
Now there are several enhancements that can be made to this script e.g. checking to see if any errors occurred during the Full X++ compile, and then only initiating the CIL compile if no errors occurred. But this is something for another day.
I hope this proves useful, and let me know if you have any questions.
I have created some outbound services to export data from Ax to a interface.
I tested them by passing a specific record in a job.
But i want to run this outbound service as a RunBase batch class.( I want to create a batch job class and run the outbound serivce)
So here i want to run the service for all the data in the service (query).
How can i achieve this ?
Thanks in advance
In order to automate the export process you could create as you said a new class that inherit from RunBaseBatch and then running this class within a batch job.
This will send the records to the queue.
In order to automatically process the queue you filled with the class, take a look at this link : http://technet.microsoft.com/en-us/library/hh352328.aspx
It explains how to configure the batch jobs for AIF.
Query queryCustTable;
AifActionId actionId;
AifEndpointList endPointList;
AifConstraintList aifConstraintList = new AifConstraintList();
AifConstraint aifConstraint = new AifConstraint();
AifOutboundProcessingService AifOutboundProcessingService;
queryCustTable = new Query();
queryCustTable.addDataSource(tableNum(custTable),"CustTable");
queryCustTable.dataSourceTable(tableNum(custTable)).addRange(fieldNum(custTable,AccountNum)).value("13*");
aifConstraint.parmType(AifConstraintType::NoConstraint);
aifConstraintList.addConstraint(aifConstraint);
actionId = AifSendService::getDefaultSendAction(classnum(CustCustomerService), AifSendActionType::SendByQuery);
if (actionId)
{
endPointList = AifSendService::getEligibleEndpoints(actionId, aifConstraintList);
if(endpointList.getEndpointCount()>0)
AifSendService::submitFromQuery(actionId,endPointList,queryCustTable,AifSendMode::Async);
}
AifOutboundProcessingService = new AifOutboundProcessingService();
AifOutboundProcessingService.run();
Don't forget to change the operation on the outbound service from CustCustomerService.read to CustCustomerService.find
Like through x++ i want to run a specific Inbound message
Take a look a the AifInboundProcessingService class. It should do the job.
AifOutboundProcessingService = new AifOutboundProcessingService();
AifOutboundProcessingService.run();
and
AifGatewaySendService = new AifGatewaySendService();
AifGatewaySendService.run();
I would say it depends.
The AifOutboundProcessingService will process all the requests that were placed in the AifOutboundProcessingQueue by the submitDefault method. It will send them in the AifGatewayQueue table.
The AifGatewaySendService on the other hand will retrieve records that are
in the AifGatewayQueue and will process the messages. In this case, as the outbound port is configured to export a file, it will export the message (XML file) in the specified directory.
So you can use this code in different ways depending on your intentions :)
I am trying to export Items data using standard service "InventItemService"
But when the file is exported i cannot see all the items in the file. Also i cannot see the newly created items in the file.
If i try to export the specific item (which is not coming in the xml) through job the xml got generated for that item.
But when the service is running for all the items some items and new items are not coming in the xml. Also the query returns the item data (which is not coming
Am i missing anything ? what can be the reason for this .
Honestly, I don't know what could be the cause. Do you use the same code to export only one item and all items ? I mean do you send "byKey" or "byQuery" ?
I have a question about preparation of entity key lists. The normal way is, to define this like you said: keyData = SysDictTable::getKeyData(custTable);
In my case, I get the RecId but I need the naturalKey for my outbound update message instead. Do you know some samples to prepare this in the axd class? I've seen, there is a method called useNaturalKey and a possibility to manipulate the KeyMap in getEntityKeyReplaycmentElementMap. Do you have some experiences to do this? I can't find anything in the web.
Best regards,
Frank
I've created a query with vendtable and dirpartyview, and created a document service through AIFDocumentservicewizard and configured that in outbound port. Can anyone tell me how to access the service and send the details to an XML file