Skip to main content

Managing Client Versions

How do you know if you have updated all of your client machines to the correct and current AX version?

For a lot of companies that have distributed clients, managing the client software can be somewhat of a headache for the IT staff. As the roll out of new kernel builds are released, it is important to make sure the client applications are updated as well. It is especially difficult if the client applications are located on mobile machine or computers that may not be inaccessible locations due to a variety of business requirements.

The following code suggestion can be put into the AOD to help prevent client side applications from logging into the production system when it has not been updated to the correct kernel version.

When our Premier Field Engineer team performs a Health Check, we will check the client executable to make sure they are on the same kernel version as the AOS. This helps improve the AX environments stability.

1) Within the AOT, create a new class

a. In the following code example the class name is DAX_ClientVersionCheck

b. Create a new method under the class called MAIN

c. Copy the following code into the method:

static void main(Args _args)

{

str currentVersion = '5.0.1500.1670'; // change this to desired kernel version

str msgText;

;

if (currentVersion != xInfo::releaseVersion()+ '.' + xInfo::buildNo())

{

msgText = "The client version needs to be updated to: " + currentVersion + ".\nCurrent version is " + xInfo::releaseVersion()+ '.' + xInfo::buildNo() + "\n\nPlease contact your System Administrator";

box::Warning(respText,"Client version issue");

// remove the following commenting on the next line to force client shutdown

//infolog.shutDown(true);

}

}

2) Change the variable currentVersion to the desired Kernel version number.

3) Save this class.

4) Open the "Info" Class.

5) Locate and open the method " workspaceWindowCreated" in the X++ editor

6) Modify the "workspaceWindowCreated" method to look like this:

void workspaceWindowCreated(int _hWnd)

{

// Put workspace window specific initialization here.

UserInfo userInfo;

Args args; // DAX modification

select firstonly AutoLogOff

from userInfo

where userInfo.Id == curuserid();

if (userInfo && userInfo.AutoLogOff)

this.setTimeOut(identifierstr(autologoff), userInfo.AutoLogOff*1000*60, true);



this.setTimeOut(identifierstr(watchDog), #watchdogInterval, false);

// DAX modification for startup test

DAX_ClientVersionCheck::main(args);

}

7) Save this code.

8) Exit AX and restart.

9) Run a Test. You should an info box message if the client version does not match:

10) Go back to the AOT

11) Change the MAIN method on DAX_ClientVersionCheck by uncommenting the following line:

//infolog.shutdown(true);

12) Save, Exit, and restart AX

13) Now when a user tries to log-in with an incorrect client application, they will be stopped until their client application matches the version number placed in the Class code.

The above code is a suggestion only. If you decide to use it in your environment, please note that it is at your own risk and it would be considered a customization, which is generally not supported by the Microsoft Support Engineers.

Popular posts from this blog

Dynamics Axapta: Sales Orders & Business Connector

Well, again folllowing my same idea of writting close to nothing and pasting code, I'll paste in some code to create a sales order from some basic data and the invoice it. I'll try to explain more in the future. AxaptaObject axSalesTable = ax.CreateAxaptaObject("AxSalesTable"); AxaptaRecord rcInventDim = ax.CreateAxaptaRecord("InventDim"); AxaptaRecord rcCustTable = ax.CreateAxaptaRecord("CustTable"); rcCustTable.ExecuteStmt("select * from %1 where %1.AccountNum == '" + MySalesOrderObject.CustAccount + "'"); if (MySalesOrderObject.CurrencyCode.Trim().Length == 0) MySalesOrderObject.CurrencyCode = rcCustTable.get_Field("Currency").ToString().Trim(); string sTaxGroup = rcCustTable.get_Field("taxgroup").ToString().Trim(); //set header level fields axSalesTable.Call("parmSalesName", MySalesOrderObject.SalesName.Trim()); axSalesTable.Call("parmCustAccount", M

Passing values between form and class

Class name is EmplDuplication and Form is EmplTable . void clicked() {    MenuFunction mf;    args args = new Args();    ;     args.record(EmplTable);     mf = new menufunction(identifierstr(EmplDuplication), MenuItemType::Action); mf.run(args); } Meanwhile, in the main() method of the EmplDuplication class, we need to put this Axapta x++ code to get the datasource: static void main(Args args) {     EmplDuplication EmplDuplication; EmplTable localEmplTable; ;     if(args.record().TableId == tablenum(EmplTable)) localEmplTable = args.record();     ... }