2014. december 18., csütörtök

LedgertransStatementDP.ProcessOffSetAccountInStaging has a copy-paste error

I found a bug in AX today in the data provider class of the Ledger trans statement report, and I will share it here, in case it helps anyone.


The task: lets fill the fields (OffsetAcct1, OffsetAcct2, and OffsetAcct3) with some data.
What happens: the code fills OffsetAcct1, OffsetAcct2 and for good measure fills OffsetAcct2 again, never using OffsetAcct3 despite the intention obvious from the comments.

The whole function is a nasty mess of a way of solving the task, but at least it doesn't even work.
Here is the original code snippet;

And here is my no- so-complicated fix for the offending paragraph



2014. szeptember 12., péntek

Show all fields: Property name has max length 40

I spent some time today with the following error:
The user right-clicked an Advance Invoice record, then chose "Record Info", then "Show all fields" and got the tasty error message below:

Property Name has max length 40. An attempt to set it to a string having length 41 has been made.

You would get similar error messages, if you called the same function on the Advance invoice lines, though then it would say length 45.

The solutions: the SysRecordInfo Form on the SYP layer contains a bug.

The problem is with the line marked with red (duh).



The Form's name can be only 40 characters long. The DictTable.name() is "CzCustAdvanceInvoiceTable" (25 chars) + _ShowAllRecords_(15 chars) is too long. Tough luck.

I don't know which KB article dropped the ball on this one, but it's okay in SYS layer, and wrong in SYP layer.

I took the easy way out and simply removed the '_ShowAllRecords_' from the function call, and presto!, it worked.


2014. szeptember 10., szerda

AX: Original (installed configuration) in registry for new users

The back story

We have a terminal server used by nearly a hundred users simultaneously to launch AX clients. The AX client had been installed a while back, and since then the original AX farm has been extended, some of the servers have been marked as dedicated batch servers, etc. Long story short, the "original configuration" in the registry is pretty much useless at this moment.

Of course they are all using .axc files to connect to the AOS, but unfortunately when AX crashes (and oh boy, does that happen), it nicely offers to restart. However, at restarting it does NOT use the same configuration it was started with, it defaults to the one stored in the registry, and the user arrives to an AOS where he is not supposed to be.

The task

Update both all of the current AX configurations and the default configuration for new users to a correct set of AOSes.

The solution

all users
The users part is pretty straightforward: under HKEY_USERS\<SID>\Software\Microsoft\Dynamics\6.0\Configuration\Original (installeded configuration), the information is stored in the AOS2 and WSDL string values. If you want to add more than one AOS, in then you can list them separated with a semicolon

default user
However the default user profile is not stored under HKEY_USERS\.Default, but is copied from HKLM, when the client launches his first AX using registry. If he always launches AX using an connection file, the registry keys are apparently not created. 

Also, this is where the configuration for Business Connector is stored

The following script will fix all of the above, for all the configs of all the users

2014. augusztus 15., péntek

Remote Desktop Connection Manager (rdcman.exe) 3334 problem

On Windows 8, Remote desktop connection manager has the annoying habit of throwing unexplainable error messages after opening more than a couple of connections, with error code 3334

If you are managing dozens of development (or live) environments, this is bloody annoying.

I have seen several proposed solutions on the net for this problem, this is the one that worked for everyone in our office, but as always, your mileage may vary.

  1. Open a Visual Studio Command Prompt with Administrative priviliges
  2. cd "c:\Program Files (x86)\Remote Desktop Connection Manager"
  3. editbin /LARGEADDRESSAWARE rdcman.exe
After this (at least for us), rdcman just works like it's supposed to.

2014. június 16., hétfő

AX installation needs file sharing to be enabled on the SQL server

Today during an AX installation I got the following error in the DynamicsSetupLog.tct


The root cause was that the SQL server (a Windows Server 2012) didn't have File sharing enabled amongst its roles, so AX couldn't verify if an SQL component was installed. Solution: After I enabled file sharing on the target server, the setup continued without any further problems.

2014. május 28., szerda

AX 2012 R2 crashes while synchronizing with TFS - KB 2902776 to the rescue!

I had a very frustrating error on the development servers I oversee (each developer has their own virtual machine): when a new environment was created it simply wouldn't sync to the Team Foundation Server code repository.

If you clicked on Synchronize and selected the model, it would think for a bit, then 90% of the time, it would crash. Opening the sync log and trying to Process the failed elements would lead to the same AppCrash error.

Deleting the AX local caches didn't help, restarting the AOS, doing full compile, full CIL compile, nothing would help. Recreating the database would sometimes have an effect, but that's it.

Thankfully there is a solution:

KB2902776 solves the issue. Unfortunately it is only available from PartnerSource (which is not indexed by Google), so it took a bit to find it.

It is a model update of the Foundation model, so I assume there is a code error in the SysXXXX class that does the synchronization.

After installing the hotfix I did a full compile/sync/CIL compile cycle before trying it, no clue if that's actually necessary, but as there was a model update, you are supposed to waste two-three hours with it.

Hope it saves others some frustration!

2014. május 9., péntek

Adding a computer to a domain with Powershell

If you have to add lots of computers to a domain, (after launching sysprepped images for example, that already have their new computername), then the following script might come in handy, and save you some password typing.

This is a shortcut, of course, and a slight security trade off.
If you are not comfortable copy-pasting your password into powershell windows as cleartext, don't use the script!

2014. május 8., csütörtök

Turning off UAC in Windows 2012 R2 with Powershell

In Windows 2012 R2, the slider that we used to use for turning off UAC (User Account Control) does not really work. It is there, but when you adjust it to minimum, nothing happens, it doesn't even ask for a reboot.


Apparently, you have to manipulate the registry to turn the damn thing off.

The following powershell command, if executed from an Admin powershell window will do just that (and immediately notify you, that you need a reboot)

set-itemproperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system -name "EnableLua" -value 0

2014. március 17., hétfő

AX 2012 import/compile log locations

There are several long running operations in Microsoft Dynamics AX 2012 that we execute during our daily build, such as
  • Importing XPOs
  • Compiling the code
  • Compiling the IL
  • Synchronizing the database
  • Importing label files
When you are doing these tasks interactively, you can immediately see if something is wrong. However, if you execute these tasks automated (with AXBuild.exe and through the -autorun switch), you will want to verify whether any of these steps failed miserably. 

Surprisingly enough, most of the time AX does log the results, but it's incredibly inconsistent in doing so. Let's see where the separate logs can be found!

XPO import log

I import XPO files with the  following command

Ax32.exe -aotimportfile=<PATH> -nocompileonImport -Model=<MODEL> -lazyclassloading -lazytableloading -Minimize

The is no way whatsoever to import an .xpo file that has a space in the path, so take care where you place your input files. 
The result ends up under the user profile directory (typically c:\Users\<Username>) in the Microsoft\Dynamics Ax\Log subdirectory, in <ImportedXpoFileName>Import.log.

XPO compile log

With the shiny new compilation tool, it became much easier to execute a full compile that would finish before the expected heatdeath of the universe.

Axbuild.exe xppcompileall /s=01 /altbin="<AXClientExePath>" /c="<AXServerExePath>" /l="<LogFolder>"

The AxBuild.exe can be found in the server bin directory. If you change the working directory to that location, then the /altbin and /c parameters become unnecessary. If you run AxBuild.exe from elsewhere, it will need a couple of hints on where to find the Ax32.exe and the Ax32serv.exe

You can see this is a newer tool, because it recognizes quotation marks, so you can have spaces in your paths.

The log it emits is a html file, and will be placed in whatever directory you specify in the /l switch. By default it logs in the C:\Program Files\Microsoft Dynamics AX\60\Server\<AOSNAME>\Log\ folder.

Parsing this html file with powershell will be the topic of another article.


CIL Compile log

Even if the XPO compiles, different errors can come to light during the CIL compilation. The following command executes a full CIL compilation. If you want to execute an incremental CIL compilation you would have to either modify the SysStartupCmd class in the AX, or use an Autorun.xml to import a class that calls SysCompileIL::generateIncrementalIL(true, true, true); method. Here, I demonstrate the full CIL method.

Ax32.exe -startupcmd=CompileIl  -nocompileonImport -lazyclassloading -lazytableloading -Minimize

Prepare to meet the third different logging method, this time into a Dynamics.Ax.Application.dll.log text file placed under the bin/XppIL directory of the server, so the full path will be something like this C:\Program Files\Microsoft Dynamics AX\60\Server\<AOSNAME>\bin\XppIL\Dynamics.Ax.Application.dll.log

If this file ends with the following, then all is fine and dandy (otherwise the exact error messages can be found earlier in this file)
Errors: 0
Warnings: 0

Synchronize log

If the xpp code compiles without errors, then the synchronize should succeed pretty much by default, right? Wrong.

In some arcane cases, synchronizing tables can and will fail, even if no one messed around with the SQL server in the background, so it's necessary to check whether AX will be able to synch your model on the target environment or not.

Once again, this is done by using AX32.exe with another StartupCmd parameter.

Ax32.exe -startupcmd=synchronize -nocompileonImport -lazyclassloading -lazytableloading -Minimize

And once again, the errors are logged into someplace new. This time the result can be found in SQL, and the following query returns all errors that ever occurred during synchronization:

SELECT DESCRIPTION FROM dbo.SYSEXCEPTIONTABLE WHERE  module='SysStartupCmdSynchronize' AND exception>1

You could filter the table more for recent messages, or if it's a build environment where the database is reset anyway, just issue a DELETE FROM dbo.SYSEXCEPTIONTABLE WHERE  module='SysStartupCmdSynchronize' command before running the synchronize.

Label file import - no log found

The only reliable way I found for importing label files, and forcing the AOS to actually write the labels into the .ald files in the bin directory, is to delete the current ald, ali, alc files, import the new ald, then restart the AOS after the import. The Label::flush command should do the trick, except it only works for languages that are not the language of the client executing the command. So if you use a technical user that has a language other than your normal languages, it could work, but I just stuck with restarting the AOS afterwards. This is the command used:

Ax32.exe -startupcmd=AldImport_<PATH>  -nocompileonImport -lazyclassloading -lazytableloading -Minimize

Once again, there can be no spaces in the path.

As far as I have been able to tell, there is no indication whatsoever if anything went wrong with the process, but if anyone has any info, I would be really interested.