Today marks my first day offical day as AX 7 (Dynamics 365 for Operations) developer. To celebrate I though I would post two commands that have come in useful so far:
Internet Information Services (IIS)
- iisreset /stop
- iisreset /start
- iisreset /restart
To run the commands, press Windows key + R, type them in and press enter.
These commands stop, starts or restarts your server. Think of it as the same commands you used to do in Services to stop and start the AOS.
This command can be run in the Visual Studio Command prompt:
This command deletes the user preferences for Visual Studio.
So far we’ve tried it for every issue we’ve run into: Table browser not working, EDT editor not opening and so on and so forth. It has not solved any of our issues till now, but I thought I would put it out there. If it solves some inexplicable issue you have with Visual Studio and AX 7, please let me know in the comments!
Whenever someone experiences a bizarre, inexplicable error, you will see a standard list of steps to try and solve the problem. These standard steps usually range from deleting the user setup on a form, to restarting the AOS.
If the unsolvable issue is limited to one user, a typical task to try is to delete the Application User Cache (AUC) files in the user’s AppData folder.
The AppData folder is hidden inside the user’s folder, and can be in different locations on different servers. I can get a little lost looking for the AppData folder… Luckily I have made a mind-blowing discovery this week: Windows have a thing called path variables or system variables. Some programmers use them to do amazing things, but the simplest way to use them is to type them in windows explorer.
For example, on any windows server, open explorer and type: %Appdata%
You will see the Application Data folder.
Back to AX, to the delete the AUC files:
- Close the user’s client.
- Open explorer, type %Appdata%.
- Delete the all files ending with .auc.
- Open the client.
- Celebrate your victory over the mysterious error! (or move on the the next desperate step on the list)
- If you frequently have to clear out the Appdata folder, get a batch script like this one.
- Try the same thing for other system folders like %temp% or %programdata%.
- Learn more about system variables here. Find out how you can set up your own and use them in scripts.
Hope this nifty trick saves you time and impresses your friends!
I rarely need to work with the AX database. In my company developers work on the AOS, and leave SQL related thing to the BI and installation people. Therefore, if I want to see the name of the database that an AX installation uses, it means I am either doing something I should not be doing, or are really desperate..
..and then I can never find the form where you can see the name of the database!
For future references (and to shorten those moments when you are not sure if you restored the correct database), to see the name of the database that contains the data, go to:
System Administration > Inquiries > Database > Database information
This opens a form with the server name and database:
If you are a hardcore developer who prefer to dazzle others with your AOT skills, you can find this form at AOT > Forms >
When you do a full compile with AxBuild, a AxCompileAll.html log file is created with all the compile errors and warnings that you would normally see in the Compiler output window. Normally it looks something like this in a browser:
If your log file looks like the one above, you can simply go to the 3 errors in the AOT, investigate and fix the problems. Unfortunately the compiler output sometimes looks like this:
You could investigate all 100+ errors listed, but the frustrating thing is that these errors are often not real errors. For some reason AxBuild sometimes logs a list of ‘fake’ compile errors. Luckily it is easy and quick to solve the fake errors by recompiling the list in the AX client.
To recompile AxCompileAll.html do the following:
- Import AxCompileAll.html into the compiler window by clicking on the double arrow next to the Setup button:
- Click on Recompile all, also found under the double arrow next to the Setup button:
Since it is only compiling the classes with errors, this is much faster that recompiling the entire AOT. If all goes well, all ‘fake’ errors should be solved and the compiler output window should have no or few errors.
The AxCompileAll.html is usually found at C:\Program Files\Microsoft Dynamics AX\60\Server\MicrosoftDynamicsAX\Log\ on the AOS.
UPDATE 26 December 2014:
I just learned an even more useful way to recompile your errors in AxCompileAll.html in a post by Kenny Saelen on Axilicious. The basics are:
- Import AxCompileAll.html
- In the compiler windows, select create project
- Compile the project
In Kenny Saelen’s post, he has a tool that does these steps automatically.
Today I quickly wanted to see which fields in the PurchLine table are mandatory. Purchline is a large table, so instead of checking the properties of each field, I quickly wrote a job that displays an info log of all the mandatory fields. I used the DictClass example script from Microsoft, and adapted it so that it generates a list with all the fields in the table.
This job can be easily changed to display the fields of other tables, simply change the tableName variable. It can also be changed to display other properties like ‘Allows edit on create’. For this you need to change the #DBF_Mandatory flag to another flag defined in the macro:
This script uses a number of interesting things like macros, dictField and dictTable. I’ll write separate posts for these topics soon. Until then, here is a simple jobs that lists all the fields in a table and their properties:
static void getMandatoryFields(Args _args)
TableName tableName = "PurchLine";
dictTable = new dictTable(tableName2Id(tableName));
fieldId = dictTable.fieldNext(0);
dictField = new DictField(tableName2Id(tableName), fieldId);
nFlags = dictField.flags();
if (bitTest(nFlags, #DBF_MANDATORY))
info(strFmt("The field %1 is mandatory.", dictField.name()));
//info(strFmt("The field %1 is not mandatory.", DictField.name()));
fieldId = dictTable.fieldNext(fieldId);
The resulting info log should look something like this: