Technical conference 2014 : Day one

I’m putting a blog post online today because yesterday the Wifi was really letting us down. But anyway, it turned out to be a very interesting day!


It all started out with what Microsoft is good at, giving presentations! The keynote was packed with content and demo’s so we were immediately excited to see some of the demo’s.

  • Professional services
    This demo showed a few new neat features when it comes to project management inside Dynamics AX
  • Retail
    This was a really nice demo! It was packed with new features and showed the new mobile experiences and nice demo’s on online shops.
    I was really impressed with all of the features available for retail.
  • Warehousing
    Another interesting demo was about the Blue Horseshoe warehousing solution. This really made me realize that all of the features I have been implementing the last 5 years were actually in there.
    There was a nice demo of the mobile app that lets you do stuff like picking, …
    Another nice addition here is the possibility to diable warehouse processes for certain inventory locations. Someone from the Blue Horseshoe guys even noted that they have eliminated the need for quarantine warehouses. There is an extra status now on the on hand inventory screen where you can specify that tis inventory cannot be used for other processes.

 A day in the life of a developer

The first actual session I attended was called “A day in the life of a developer / IT Manager”.

When I look at my scribbles, there’s a lot in there. But let me just mention a few key things that I noticed:

  • Trace parser
    Developers use the trace parser not enough when they are finished coding a feature. Being proactive means tracing your code to get out the obvious flaws.
  • LCS model upload
    We are using the feature in lifecycle services to upload the model for customization analysis. People should use that more often too.
    There is actually a HTML report available in the same format as the compiler output so developers can import that in AX to directly access the corresponding code.
  • Machines for building
    When devs check in there code, there should obviously be a build process that builds the code. For this, developers request hardware but this should be kept in mind when looking at the build performace:

    • Put all of the components on one box
    • Put in at least 16GB of RAM
    • Do not constraint the SQL memory
    • Install KB2844240 to optimize index performance optimizations
    • Request faster CPU’s first instead of more CPU’s
    • Install an SSD on the build machine
    • Use AxBuild.Exe 🙂

Data export and Import Framework (DIXF)

The session about DIXF was also nice as a recap of what I already knew by working with DIXF at a customer site.

There were some interesting new features available in the R3 version:

  • Compare and copy data between companies (Only on entity level)
  • Copy entity data accross difference Microsoft Dynamics AX environments (Only on entity level)
  • MDM on top of DIXF
    Reuses DIXF for master data management (More in posts to come on this)
  • Out of the box support for 150+ entities
    • Master entities
    • Documents
    • Journals
    • Parameters
    • Reference data
    • Configuration data (EP Settings, Server Settings, Batch Settings, …)
  • Performance of staging to target
    There is support for parallel task bundling. Large files can be split up over several tasks.
  • There is a compare entity wizard that can compare entities between companies

Create AX Builds using the new server side compiler

For me, this was interesting because I have been playing around a lot with builds and the sessions turned out to be more like a Q&A session.

Firstly there was an explanation about how the compiler works. Roughly seen, there are 3 main parts:

  • Phase 1: Header compilation for tables and classes.
  • Phase 2: Complete X++ sources compiled into P-Code. Error log get created
  • Phase 3: Compile the error list. Here they did not actually managed that the number of passes depends on the errors. An number of error is incremented and as long are there are errors a new pass is tried. (Up to pass 5)

The important part here is that this is done on all of the tiers. The client performs the compilation and the communication goes all the way through the AOS to the SQL Database. But this has been solved and now the compilation is actually done on the server now. It is a 64bit compilation and X++ execution is kept to a minimum.

After the session, later on the evening, we met up with Robert Badawy which gave the sessions.  It was nice to have a chat with him and get his view on all of this and how Microsoft does the build process internally.

Cleaning up after AxBuild.exe

So the AxBuild.exe tool has been around for a couple of weeks now and imho this is the best addition that a CU brought until now.

There have been some nice post about how it works and what you should keep in mind:

Though the tool is fantastic, we noticed that after performing a compile we always needed some manual actions to get the error count to 0.
Due to the limitations of AxBuild we always had approximately 100 errors left after compiling. A lot of them were custom .Net assemblies that could not be referenced at compile time.

So here is what you normally do when performing a full compile now:

  • AxBuild your environment
  • Import the HTML compiler output
  • In the compiler windows, select create project to create a project with all of the objects that were still invalid
  • Compile the project inside the Ax client

Well, just to make it easier, I have created a little tool which does the last 3 actions at once so that we do not need to perform these things manually. (And enabling us to incorporate it in automated builds).

The idea is to have a startup command which I can use like this :

ax32.exe -startupCmd=importandcompileaxbuildlog_<Full path to the exported compiler log file>

Due to the nature of the (imho not so good) design of the startup commands, it is not possible to enter a file path with spaces in your command prompt. Also putting quotes around it wouldn’t help too.
Therefor I have used the ‘*’ sign and the startup command will replace the ‘*’ charaters with spaces. For example:

ax32.exe -startupCmd=importandcompileaxbuildlog_C:\Program Files\Microsoft*Dynamics*AX\60\Server\AX60R2\Log\AxCompileAll.html

If you want to try it yourself, you can find an XPO containing the code here.

AX2012 R2 Enterprise portal installation issues – Part 1

The last few days I have been playing around with the Enterprise Portal. I needed to setup a High Available portal and there were soms discoveries along the road.

Though I’m planning on writing some other posts on the general architecture used when installing the Enterprise Portal in a HA environment and the possible installation issues you might have, I wanted to discuss one of the smaller issues encountered.

When opening the Enterprise Portal site, you can run into the following error:

c:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ep\EPSecurityControl.ascx.cs(13): error CS0234: The type or namespace name ‘AX’ does not exist in the namespace ‘Microsoft.Dynamics’ (are you missing an assembly reference?)

You can solve this by running the Ax installer for EP installation on all of the machines in the farm. When installing, uncheck all of the checkboxes to only install the binaries.

AX2012 DLL Deployment and how AX binds DLL’s at runtime

In an earlier post I have showed how to use custom WPF controls with Dynamics AX 2012.

Well when using this type of fuctionality, you will often come into troubles when using it on other environments because of the corresponding DLL files not being deployed on their machine.

For that, you can use the automatic deployment feature of Ax when adding projects to the AOT. But it seems that there is an issue there. You can find lots of information on this post made by Joris De Gruyter:

And there is also information to be found here:

In short you have the following options to deploy your DLL files:

  • Automatic deployment feature of Visual Studio projects in the AOT
  • Using the SysFileDeployer framework (Joris mentioned an upcoming blog post on that, so that will be cool and interesting)
  • Copy them into the client\bin or server\bin directories
  • Use the Global Assembly Cache to store assemblies

While opinions might be devided, I tend to like the latter option. Simply because the GAC is intended to manage just that. Some of the benefits of the GAC:

  • No polution of the file system with DLL files being copied all around
  • Assemblies must be signed and the PublicKeyToken can be used to differentiate versions of your DLL file (Think of disallowing an assembly in production if it is coming from development environments and the wrong version was accidentally added)
  • Due to the previous fact, you can also have multiple versions of the same DLL file in your GAC.
  • GAC Redirection can be used to point to the right assembly if older versions are searched for

So let’s look back at the initial problem that I was facing. Dynamics AX threw up an error mentioning that it could not find the DLL file it needed. Strange because it was present in the GAC so it should always find it there.


Well to find out why it did not find the DLL I needed to check where AX was actually looking for it. And to do that you can use a .net framework tool called fuslogvw. This little helpfull tool is actually an assembly binding logging tool. So if DLL files are searched for, this little guy will give you the details about it.

So open up a Visual Studio Command Prompt and type fuslogvw and hit enter. First we need to do some minor setup to get it to log stuff. So go to Settings and select the log all binds to disk option. Then select a path to store the log in and you’re set to go.

Fuslogvw Settings

At that point I fired up the AX client and openened up the form that uses the assembly that appeared to be missing. Fuslogvw caught the information that is displayed below.


*** Assembly Binder Log Entry  (17/05/2013 @ 9:03:38) ***

The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Running under executable  C:\Program Files (x86)\Microsoft Dynamics AX\60\Client\Bin\Ax32.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: User = EPS\lab rd wdpan59
LOG: DisplayName = EPS.AX.WPFControls, Version=, Culture=neutral, PublicKeyToken=null
LOG: Appbase = file:///C:/Program Files (x86)/Microsoft Dynamics AX/60/Client/Bin/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = Ax32.exe
Calling assembly : Microsoft.Dynamics.AX.ManagedInterop, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Program Files (x86)\Microsoft Dynamics AX\60\Client\Bin\Ax32.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: The same bind was seen before, and was failed with hr = 0x80070002.
ERR: Unrecoverable error occurred during pre-download check (hr = 0x80070002).

The following line shows what was wrong at the time:

LOG: DisplayName = EPS.AX.WPFControls, Version=, Culture=neutral, PublicKeyToken=null

The assembly manager was actually looking for an unsigned version of my assembly in the GAC. But that version is not present since I had signed my assembly… So why was it looking for an unsigned version?? Well the answer to this was the order in which I had done things.

For development purposes I did the following in the exact same order:

  • Created a Visual Studio solution and added it to the AOT.
  • Added a ManagedHost control on a form and pointed out to the assembly that I needed. (Filedbased) (Until now an unsigned one)
  • When all was working well, I tried to do stuff the BP way and I signed my assembly and put it into the GAC.

As that seems to be enough, environments other than my machine were still facing the issue even though the DLL was in the GAC there too. And when looking at the ManagedHost control in AX, I saw that it was keeping a reference to the unsigned assembly and not the signed one!! So to solve it, you need to do things in a different order:

  • Create the Visual studio project.
  • Sign and build your assembly.
  • Add the solution to the AOT.
  • Add the ManagedHost control now and point to the assembly (that is now in your GAC already)

When this is done, you will have a reference in AX that also takes the right PublicKeyToken in to account and it works on the other machines also. To be sure I checked with fuslogvw again and this is the output.


*** Assembly Binder Log Entry  (17/05/2013 @ 9:03:42) ***

The operation was successful.
Bind result: hr = 0x0. The operation completed successfully.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework\v4.0.30319\clr.dll
Running under executable  C:\Program Files (x86)\Microsoft Dynamics AX\60\Client\Bin\Ax32.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: User = EPS\lab rd wdpan59
LOG: DisplayName = EPS.AX.WPFControls, Version=, Culture=neutral, PublicKeyToken=14cd416a5dbff93c, processorArchitecture=x86
LOG: Appbase = file:///C:/Program Files (x86)/Microsoft Dynamics AX/60/Client/Bin/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = Ax32.exe
Calling assembly : Microsoft.Dynamics.AX.ManagedInterop, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35.
LOG: This bind starts in default load context.
LOG: Using application configuration file: C:\Program Files (x86)\Microsoft Dynamics AX\60\Client\Bin\Ax32.exe.Config
LOG: Using host configuration file: 
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v4.0.30319\config\machine.config.
LOG: Post-policy reference: EPS.AX.WPFControls, Version=, Culture=neutral, PublicKeyToken=14cd416a5dbff93c, processorArchitecture=x86
LOG: Found assembly by looking in the GAC.
LOG: Binding succeeds. Returns assembly from C:\Windows\Microsoft.Net\assembly\GAC_32\EPS.AX.WPFControls\v4.0_1.0.0.0__14cd416a5dbff93c\EPS.AX.WPFControls.dll.
LOG: Assembly is loaded in default load context.

And as we can see, Dynamics AX now takes the key into account and mentioned that it indeed found the assembly in the GAC.

LOG: DisplayName = EPS.AX.WPFControls, Version=, Culture=neutral, PublicKeyToken=14cd416a5dbff93c, processorArchitecture=x86

So for now, we have stored all the assemblies that we use in a folder on the network and every time there is a new version available, simple scripts are run to update the GAC and that is the only thing that needs to be done.



Hosting custom WPF calendar control in AX 2012

The requirement

A couple of days ago, I needed to create a calendar like lookup but it had to be possible to block out dates for selection. In Dynamics AX, there is calendar lookup form available, but there are some minors to it:

  • It is not really (easy) customizable
  • It has limited functionality

What I needed the calendar form to do:

  • Visually block dates for selection
  • Easy navigation over longer periods
  • Support for different selection types (Single date, weeks, multiple selected dates, …)
  • Provide a custom range to display dates

So it is clear that Ax does not have a calendar like that, so I had the idea of creating a custom control for this. But due to time restriction ( isn’t there always a time restriction ! 🙂 ) I went looking for a WPF control that I could wrap around and integrate it with Ax. And then I found the following control that has all I need : But having a working control in a WPF application is one thing, getting it to work with Dynamics AX is another. I noticed when I was using the control directly, the client crashed and some of the properties were not marshallable because Dynamics AX does not support generics. So wrapping the control in a control of my own was an option here. And there are two reasons why I did wrap the control:

  • When using the control directly, it crashed 🙂
  • When wrapping into your own control, you can decide which of the features you want to be available and which are omitted
  • It is possible to write some helper methods for generic properties since Ax does not support generics

Now let me show you how to do it.

Creating a custom WPF user control

First start of by creating a custom WPF user control. Open up visual studio and create a new project of the type WPF User Control Library. NewProject Since we are going to implement the vhCalendat control, add a reference to the vhCalendar dll file. (Found in the CodeProject post link above). Once the reference is in place and before going into XAML mode, let us take a look at the code behind file and put some things in place.

Control definition

First we have a partial class that defines the CalendarViewControl. Extending this later with your own stuff should be easy since it is a partial. public partial class CalendarViewControl : UserControl, INotifyPropertyChanged

Control properties

Now lets add properties for all of the calendar’s properties that we want to expose. (Here I will not show them all, just some examples)

/// <summary>
/// Gets/Sets the date that is being displayed in the calendar
/// </summary>
public DateTime DisplayDate 
        return (DateTime)theCalendar.DisplayDate; 
        theCalendar.DisplayDate = value; 

/// <summary>
/// Gets/Sets animations are used
/// </summary>
public bool IsAnimated 
        return (bool)theCalendar.IsAnimated; 
        theCalendar.IsAnimated = value; 

/// <summary>
/// Gets/Sets the selection mode 
/// </summary>
public CalendarSelectionType SelectionMode 
        int i = (int)theCalendar.SelectionMode; 
        return (CalendarSelectionType)i; 
        int i = (int)theCalendar.SelectionMode; 
        theCalendar.SelectionMode = (SelectionType)i; 

The last property above shows a bit of ‘nasty’ code because I needed to translate the System.Windows.Visibility enum into a custom enum. This was because the CIL generator had a problem with the System.Windows.Visibility enum. CIL kept giving me the error : ‘Invalid cast’ until I used a custom enum.

Control events

Next to some properties, there are also a couple of events. The first one is to let Dynamics AX know that the selected date has changed.

public delegate void SelectedDateChangedEventHandler(object sender, EventArgs e); 

public event SelectedDateChangedEventHandler SelectedDateChanged; 

/// <summary>
/// Raised when the selected date changes in the calendar.
/// </summary>
public void RaiseSelectedDateChanged(object sender, vhCalendar.SelectedDateChangedEventArgs e) 
    if (SelectedDateChanged != null) 
        SelectedDateChanged(this, new EPSSelectedDateChangedEventArgs() { NewDate = e.NewDate, OldDate = e.OldDate }); 

Please note that the delegate is outside of the class but in the same namespace. Af of now, I’ve implemented single selection but there are also events in the calendar for when multiple selection changes.

Another important one is the RaisePropertyChanged event. This event will be useful to us when we are using binding in XAML. It will notify the control’s user interface that a property has changed and all of the UI elements that are bound to the corresponding property will be updated. (Note that the delegate PropertyChangedEventHandler is already known because our control implement INotifyPropertyChanged.

/// <summary>
/// Raised when one of the properties was changed in the WPF control
/// </summary>
public void RaisePropertyChanged(string propertyName) 
    if (PropertyChanged != null) 
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 

Implement the control in Dynamics AX

Now for the AX part, start with creating a form with a ManagedHost control so that we can host the control. When you add the ManagedHost control, a windows will popup to select the control type that you want to use. In that window, select the reference to the dll (or browse for your dll) and select the type of control to use.


 Next we need a way to handle the events of the calencar control. When we choose a date in the control, we need to be notified in X++ so that we can do what we want with it.

To do that, you can right click the ManagedHost control and select events. In the events window, you can now select our selectedDateChanged event and add an X++ handler method to it.


  The following code was added to our form ( Note that you can also use the ManagedEventHandler class when you are consuming external services asynchronously! ):

_ManagedHost_Control = ManagedHost.control();
_ManagedHost_Control.add_SelectedDateChanged(new ManagedEventHandler(this, 'ManagedHost_SelectedDateChanged'));

So when we open our form and we select a date in the calendar, the ManagedHost_SelectedDateChanged method will be called. So let’s open up the form and see what it looks like.


Nice! But are we satisfied yet? Not quite…

Imho when implementing things like this, you should always keep in mind that others want to use your control in other contexts. Today I want to use it when selecting delivery dates but if we make some modifications, everyone can use this in any context they want.

What I did to achieve this is to create two things:

  • A property bag class that contains all of the properties that can be passed to the control.
  • An interface that forms need to implement when they want to host the control.

So first let’s take a look at the property bag. This is in fact merely a class with some parm methods on it. No PhD required here 🙂

/// <summary>
/// Data container class containing the parameters that can be set on the WPF control from inside Ax.
/// </summary>
public class EPSWPFCalendarParameters
    // Selection type of dates (single, multiple, ...)
    EPS.AX.WPFControls.CalendarSelectionType selectionType;

    // Start view of the calendar (month, year, decade, ...)
    EPS.AX.WPFControls.CalendarDisplayType displayType;

    // Date being displayed in the calendar
    System.DateTime displayDate;

    // Date from where the calendar displays dates
    System.DateTime displayDateStart;

    // Date to where the calendar displays dates
    System.DateTime displayDateEnd;

    // Use animation and transitions in the calendar
    boolean isAnimated;

    // Show the footer
    EPS.AX.WPFControls.CalendarVisibilityType footerVisibility;

    // Color the today's date in the calendar
    boolean isTodayHighlighted;

    // Show week columns
    EPS.AX.WPFControls.CalendarVisibilityType weekColumnVisibility;

    // Dates that will be marked as blocked and will not be selectable in the calendar
    Map blockedDatesList;

Apart from the parm methods, there is also an initialization method present so that some defaults are set in case they are not specified by the caller.

public void initDefaults()
    this.parmDisplayDate            (systemDateGet());
    this.parmDisplayType            (EPS.AX.WPFControls.CalendarDisplayType::Month);
    this.parmFooterVisibility       (EPS.AX.WPFControls.CalendarVisibilityType::Visible);
    this.parmIsAnimated             (true);
    this.parmIsTodayHighlighted     (true);
    this.parmSelectionType          (EPS.AX.WPFControls.CalendarSelectionType::Single);
    this.parmWeekColumnVisibility   (EPS.AX.WPFControls.CalendarVisibilityType::Visible);
    this.parmBlockedDatesList       (new Map(Types::Date, Types::Date));

Now for the next part, let’s create an interface that simply asures that forms hosting the control have a method to construct parameters for the calendar control.

/// <summary>
/// Interface for defining what is needed to be able to host the EPS WPF Calendar control on that form.
/// </summary>
public interface EPSWPFCalendarFormHostable { } 

/// <summary>
/// Calendar parameter data bag.
/// </summary>
/// <returns>
/// An instance of EPSWPFCalendarParameters 
/// </returns>
public EPSWPFCalendarParameters calendarParameters() 
{ }

This interface needs to be implemented on the caller form. Below we have an example of just that. (Note that for this example the code is on the form, but this should be done in a form handler class)

class FormRun extends ObjectRun implements EPSWPFCalendarFormHostable

/// <summary>
/// Contains parameters for the WPF calendar
/// <summary>
/// <returns>
/// An instance of EPSWPFCalendarParameters. 
/// </returns> 
public EPSWPFCalendarParameters calendarParameters() 
    // Create default instance of the parameters 
    calendarParameters = EPSWPFCalendarParameters::construct(); 

    // Set the calendar selection mode to a single date 

    // Set the default view to a month 

    // Passes a map of dates to be blocked for selection in the calendar

    return calendarParameters; 

For the last part, we need to glue these together. This is done in the form where we host the calendar control. When the form is called, it requests the calendar parameters from the caller and applies all of them to the control.

public void init()
    SysSetupFormRun formRun = element.args().caller();

    // Check if the managed host is even the right type
    if(ManagedHost.control() is EPS.AX.WPFControls.CalendarViewControl)
        calendarViewControl = ManagedHost.control() as EPS.AX.WPFControls.CalendarViewControl;
        throw error("@EPS6008");

    // Initialize from the caller interface (The caller should have implemented the interface that contains the calendarParameters)
    if(formHasMethod(formRun, 'calendarParameters'))
        hostable = element.args().caller();

        // The hostable should have the parameters defined
        calendarParameters = hostable.calendarParameters();

        // Initialize the calendar control based on the found parameters
        throw error("@EPS6009");

    // Register an event handler that attached to the selected date changed event of the calendar control)
    calendarViewControl.add_SelectedDateChanged(new ManagedEventHandler(this, 'ManagedHost_SelectedDateChanged'));

Note the formHasMethod call. This is an extra safety check. When using classes, the compiler makes sure that you have implemented the interface’s methods. But with forms, you never have a constructor called so that the compiler can do the check for you.

/// <summary>
/// Initializes the control based on the parameters found in the caller.
/// <summary>
private void initControlParameters() 
    Map blockedDates = calendarParameters.parmBlockedDatesList(); 
    MapEnumerator mapEnum; 
    TransDate fromDate; 
    TransDate toDate; 

    calendarViewControl.set_SelectionMode (calendarParameters.parmSelectionType()); 
    calendarViewControl.set_DisplayMode (calendarParameters.parmDisplayType()); 
    calendarViewControl.set_FooterVisibility (calendarParameters.parmFooterVisibility()); 
    calendarViewControl.set_IsAnimated (calendarParameters.parmIsAnimated()); 
    calendarViewControl.set_IsTodayHighlighted (calendarParameters.parmIsTodayHighlighted()); 
    calendarViewControl.set_WeekColumnVisibility (calendarParameters.parmWeekColumnVisibility()); 

        calendarViewControl.set_DisplayDate (calendarParameters.parmDisplayDate()); 

        calendarViewControl.set_DisplayDateStart (calendarParameters.parmDisplayDateStart()); 

        calendarViewControl.set_DisplayDateEnd (calendarParameters.parmDisplayDateEnd()); 

    // Pass the blocked out dates collection to the control. 
        mapEnum = blockedDates.getEnumerator(); 
        while (mapEnum.moveNext()) 
            fromDate = mapEnum.currentKey(); 
            toDate = mapEnum.currentValue(); 
            calendarViewControl.addBlockedDate(fromDate, toDate); 

So when all of this is in place, the calendar form calls the calling form and requests the parameters, passes them to the control and renders the control. Everyone that want to have the same control hosted on their for only need to implement the calendar parameters method on the form and that’s it.

When all is in place, this is what it looks like when the calendar has blocked days:



When clicking on the month title, you can easily navigate between months and years:





So that is the end of it. I hope you already have some ideas as to what controls you can now host within Dynamics AX 2012. It is possible to create your own, but you can host any other WPF control if you want. (Think of Infragistics controls, Telerik, …)

Running AX2012 R2 locally on Windows 2012 Server booted directly from VHD

I have been working on a large project since a couple of months now and we use a virtualized environment where every developer has his own proprietary development machine. I am not going to make any statements about virtualization and the hardware that is beneath all of those machines is definitely ok.But here’s the thing:

  • There is a Citrix involved and the network at the customer site does not cope with the traffic now and then.
  • Secondly, the developer machines have enough resources ( or at least they think VMware gives them enough 😉 ) but Dynamics Ax 2012 (R2) is quite the resource consumer (CPU when compiling and memory when generating CIL and performing DB syncs…)

So in the end these machines end up being perceived as too slow and I wanted to see if my personal (physical) machine would perform better when I worked on it locally and just using the network to get to the TFS. The following things I am already sure of:

  • I am not on the company domain which relieves me of all the policies being executed at startup ( Yes, they take forever there! And no I am going to tell you how to run AX 2012 without a domain as that used to be possible in AX2009 but with AX 2012 it is a whole other story, which I am happy to give you some details about if you would ask me apart from this post 🙂 )
  • I am absolutely sure how much resources I own on my machine

The machine on which I am running my test here has the following key specifications: (It is a pretty decent thing (the SSD helps a lot), but you can always argue for more RAM off course 😉

  • HP Elitebook 8570p
  • Intel(R) Core(TM) i5-3320M CPU @ 2.60GHz, 2601 Mhz, 2 Core(s), 4 Logical Processor(s)
  • 8GB DDR3
  • 250 GB SSD drive

There are two goals of this test:

  • Running AX2012 locally and solving my problem of my virtual developer machine being too slow over citrix
  • Booting directly from a VHDX (Hyper-V Virtual Hard Disk) so that I can switch between operating systems and enable full hardware access for my virtual machine. (Except for the disk which is still virtualized because we boot from a VHDX file)

First step : Create a virtual machine and install Windows Server 2012

Now off we go! Off course I am not going into many details of creating a VHD file as this is prerequisite knowledge for this post. It is just creating a virtual machine and installing the Windows Server 2012.

Second step : Creating a boot option for the Windows Server 2012 VHD

The first step was simple, but now comes the interesting part. We know how to create the virtual machine, but how can we boot right of the VHDX instead of having to boot an OS first to be able to run your virtualization software of choice?

Well, BCDEDIT to the rescue! BCDEdit is found in your windows\system32 folder and is used to modify your boot configuration. What we need to do here is to add a boot option that mounts our VHDX file when booting.

Follow the steps in the following link and you will be able to do just that!

Third step : Installing a domain controller

AX 2012 cannot run without a domain controller ( captain obvious to the rescue 🙂 ) so we are not going to modify registry keys to trick it into running without one. (As was possible in AX 2009)

Again, there is nice step-by-step guide from Microsoft to install Active Directory Domain Services on your 2012 Server ( Yes, dcpromo has been deprecated 🙂 ) :

If you follow the steps you should have a domain controller on there and your server manager should look similar to the one I have here.

Server manager

Fourth step: Installing SQL Server, Visual Studio and AX2012 R2

I think this step is familiar. You have your own Server and domain controller up an running so you can go ahead and create the needed service accounts and Dynamics AX 2012 R2 has everything it needs to run in there. From here on, it is just like installing your own developer environment.


First thing that I have noticed: Windows Server 2012 really seems to be performing well and handling resources nice. I have the OS running, domain controller active and it only used 1.5 GB of ram (I expected it to use more). The startup time is also acceptable : 2.5 minutes from cold boot to logged in. (Compare that to booting windows 7 in the same time with running all of the company’s policies until I could log in…)

Another advantage here is that I have created a copy of the virtual machine so whenever I run into trouble, I can just boot into the other main OS again and replace the VHD file with a backup and I am good to go again. And when I want to get rid of the dual boot option, I just have to remove the VHDX file and adjust the boot configuration with BCDEdit and it’s gone. All of this minimizes the overhead of having to remaster your machine once in a while because it starts to get slow.

So I hope I showed you how you could do things differently when you want to run Ax locally.

Dynamics 2012 R2 In-place Upgrade : Configuration Issues

Today I was performing an in-place upgrade to R2 and that was an adventure on it’s own 🙂
First let’s start of by saying that the in-place upgrade documentation on MSDN was really helpful and well written!

But anyway, I wanted to tell you about two specific issues that I’ve encountered :

  • Database and AOS on different machines
  • AOS and locating the Model Store

Database and AOS on different machines

When I ran the installer to configure the existing database, the new R2 models from Microsoft were installed in the Model Store database, but the ‘old’ models were not copied from the other database to the new model store. The white paper mentions possible trouble, but I just performed the data upgrade on a single machine and that was that.

AOS and locating the Model Store

The other issue was a bit more interesting. When the data upgrade was done, I restore the database over the existing one on the target environment. But when I started the AOS server, I received a huge amount of DB sync issues. At first I was surprised since I am used to restoring databases and connecting the AOS to them. Once done, you should have the same situation but here it was not the case.

Further investigation pointed out that the installer forgot some things when upgrading the AOS. Namely, updating the existing configuration of the AOS. Since R2, there are two new parameters in the configuration files : ModelDBServer and ModelDatabase. But they have been left blank.


So at this point,  the AOS starts and since the isntaller did not remove the old models from the data database, it is still a valid model store and Ax starts!
Filling in these values with the correct model store database solved the issue.

PS: The same is happening for the Max Buffer Size parameter (Left at 24kb and R2 need 40kb)


AX2012 R2 – Hidden compiler errors – Update

Recently I was reading a post concerning hidden compiler error messages in Dynamics AX2012 on the blog of Joris Degruyter. Nice post since it also made me realize we were facing the same problem! (You can read all about the details in the blog post)

To solve the issue, there was a hotfix known by the KB number 2797772.
Well since we are already using AX2012 R2 this hotfix was not a solution for us since the hotfix is related to AX2012 FP.

After logging the issue with Microsoft and the outstanding work of the support engineers, this issue got escalated and a fix was released very quickly. It goes by the KB number 2822515 and it can be downloaded here: KB2822515/6.2.1000.582/free/460217_intl_i386_zip.exe

After installing the fix, your build number should be 6.2.1500.582 which is past the CU1 build number.


AX2012 R2 : DB Sync – Failed to create a session


Thanks to a Kevin Roos, for spending the time to look into this one!

We have been seeing the following error lately in AX2012 R2:

Failed to create a session; confirm that the user has the proper privileges to log on to Microsoft Dynamics

A closer look into this learned that this is linked to the new partitions feature.

It seems the UserInfo table is not correctly updated and the partition administrator is not updated correctly when you restore an existing DB or the Demo database.
To fix this, you can do the following.

  • Stop the AOS
  • Restore the database again
  • Start the AOS
  • Start a client and complete the partition initialiasation checklist
  • Close the client and execute the script below on the SQL database
  • Restart the client and reimport your license (if you were restoring the Microsoft demo data, the demo license is back in there)
  • Then compile / generate CIL / DB sync and you should be on track again!

The script for updating the UserInfo inforation is as follows:

DECLARE @NetworkDomain nvarchar(255); 
DECLARE @NetworkAlias nvarchar(80); 
DECLARE @SID nvarchar(124); DECLARE @InitialPartition bigint; 

select @InitialPartition=Recid from PARTITIONS where PARTITIONKEY=N'Initial' 

select @NetworkAlias=NETWORKALIAS,@NetworkDomain=NETWORKDOMAIN,@SID=SID from USERINFO where PARTITION=@InitialPartition AND ID = N'Admin' 



Dynamics AX 2012 R2 : XppPrePostArgs changes

Amongst many other changes made in Microsoft Dynamics AX 2012 R2, there has been soms changed to the XppPrePostArgs class too. But before you even read further, please also have a good read through a series of posts made by Joris Degruyter. The series give a nice overview of using models and events to make you code more upgradable. If there was a bible written for AX, this would be one of the first commandments!

In the series of post, Joris explains the use of the XppPrePostArgs class to fetch arguments you want to use in your event handler class. To get the FieldId from the args when the validateField method was triggered, the following code was used:

if(_args.getArg(_args.args().fieldName(1)) == FieldNum(CustTable, DMProjId)

Well, since R2, the XppPrePostArgs class has been modified to extend object instead of XppEventArgs. (MSDN:
One of the concequences is the absence of the args() method. So when you want to do the same thing as above, you now have to use the following code (it’s a bit simplified and less ugly) :

if(_args.getArgNum(1) == FieldNum(CustTable, DMProjId)