There’re several different reasons when local printer is not available at Terminal Services Session, below are my check list, hope it helps.
#1. Printer redirection is disabled at Terminal Server
First thing to check is whether the server has disabled the printer redirection.
Also ensure it enable the use of user settings.
Path: Control Panel > Administrative tools > Terminal Services Configuration
Check group policy
Path: Start > Run > gpedit.msc > Local Computer Policy > Computer Configuration > Administrative Templates > Windows Components > Terminal Services > Client/Server data redirection
Ensure the printer redirection is not disabled.
Reference:
http://social.technet.microsoft.com/Forums/en/winserverTS/thread/619d78a1-dc47-45cf-a078-e9fba492dd1f
http://social.technet.microsoft.com/Forums/en/winserverTS/thread/4ebf9a34-85f3-4b91-9750-48124b9885ba
#2. Local resources (Printer) is not checked in the RDP connection settings
Ensure the “Printers” checkbox is checked under the “Local devices and resources” group.
#3. Printer driver is not available at Terminal Server
In certain cases, the issue was caused by printer driver is not available at the server, you might want to install it there.
Reference: http://technet.microsoft.com/en-us/library/cc758836(WS.10).aspx
#4. Printer is not using COM, LPT, or USB port
Refer to more details at http://support.microsoft.com/kb/302361.
Wednesday, 6 July 2011
Monday, 13 June 2011
Candidate for EntireTable CacheLookup on Dynamics AX
When deciding which table is suitable for EntireTable caching in Dynamics AX, the rule is the 128k size limit (http://msdn.microsoft.com/en-us/library/bb314630(v=AX.50).aspx). With the note in MSDN - "Avoid using EntireTable caches for large tables because once the cache size reaches 128 KB the cache is moved from memory to disk. A disk search is much slower than an in-memory search.", so, how do we decide which table should be cached? The easiest way is to look at the page count of the table itself. In SQL Server, 1 page == 8kb, which means 128k == 16 pages. With the help of 'sys.dm_db_index_physical_stats' we can list out all the tables that is less than or equal 16 pages, these will be the candidate for further analysis. Do not change them all to EntireTable CacheLookup, there're further analysis required.
USE <databasename>
GO
SELECT OBJECT_NAME(object_id),
[object_id],
index_id,
index_level,
page_count,
avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats(DB_ID('<databasename>'),NULL,NULL,NULL,DEFAULT)
WHERE page_count > 0
AND page_count <= 16
GO
USE <databasename>
GO
SELECT OBJECT_NAME(object_id),
[object_id],
index_id,
index_level,
page_count,
avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats(DB_ID('<databasename>'),NULL,NULL,NULL,DEFAULT)
WHERE page_count > 0
AND page_count <= 16
GO
If the system is still in implementation phase, most likely the data is quite crappy, insufficient, or with just a small set of test records, they're not helping in decision making. With the list of tables returned from the above query, do further analysis and ask yourself:
- Is the table potentially growing larger over time?
- Are the data quite static? (avoid doing EntireTable cache on small table, but has high change rate)
- Is the table (unique) index correctly set? (Eg. to the ::find() method or other query's unique criteria)
There's one thing that I'm not quite sure yet, that is whether the 128k limit is per index or per table.
You can test it out by capturing the trace and look at it with Trace Parser.
*NOTE: The query took around 30 minutes to run on my system (~500GB database), you might want to choose a better timing to run it.
To run the query against one single table, replace the second parameter to the object Id of the table.
From: sys.dm_db_index_physical_stats(DB_ID('<databasename>'),NULL,NULL,NULL,DEFAULT)
To: sys.dm_db_index_physical_stats(DB_ID('<databasename>'),OBJECT_ID('<tablename>'),NULL,NULL,DEFAULT)
*NOTE: The query took around 30 minutes to run on my system (~500GB database), you might want to choose a better timing to run it.
To run the query against one single table, replace the second parameter to the object Id of the table.
From: sys.dm_db_index_physical_stats(DB_ID('<databasename>'),NULL,NULL,NULL,DEFAULT)
To: sys.dm_db_index_physical_stats(DB_ID('<databasename>'),OBJECT_ID('<tablename>'),NULL,NULL,DEFAULT)
Monday, 16 May 2011
ExtendedTypeId of Enum and EDT
Just a quick post about the error encountered.
I was asked to debug an error and it has been found that it was due to developer is trying to use the "SysDictType()" class to look for the ExtendedTypeId of an enum. The code is quite dynamic, it accept the input from another setup table, which by default, it won't know what's the field that is coming in.
On the generic code, it seems like there's an assumption all field coming in will have EDT, therefore using only the SysDictType(), hence, error. The EDT name is needed for some other purpose, so I retain it. What I added is a branch to use either SysDictType() or SysDictEnum() based on the existence of the EDT.
Eg.
dictField = new DictField(tableId, fieldId);
if(dictField.typeId())extendedTypeId = new sysDictType(dictField.typeId()).extendedTypeId();
else if(dictField.enumId())
extendedTypeId = new sysDictEnum(dictField.enumId()).extendedTypeId();
Thursday, 12 May 2011
Send/add batch job through code on Dynamics AX
To add job into 'Batch job' using X++ code, just skip the .prompt() method.
All you need is:
- A class that extends RunBaseBatch
- A method that add the job into batch job
Eg.
classdeclaration SendBatchJob extends RunBaseBatch
{
....
....
}
//The method that calls to add the job
static void addBatchJob()
{
SendBatchJob sendBatch;
;
sendBatch = new SendBatchJob();
sendBatch.sendToBatch();
}
;
sendBatch = new SendBatchJob();
sendBatch.sendToBatch();
}
//The method that actually add the job into 'Batch job'
void sendToBatch()
{
this.batchInfo(); //InitializebatchInfo.parmBatchExecute(NoYes::Yes);
batchInfo.doBatch();
}
Friday, 6 May 2011
Running batch report in AX2009 (batch printing)
Since the change of AX2009 batch framework, printing of report through batch can be done through two methods:
- Printing from server (to printer or file)
- Printing from client (the legacy batch processing)
Prerequisites: For both of the method, there're some mandatory setup:
- Printing from server (to printer or file)
- Printing from client (the legacy batch processing)
Prerequisites: For both of the method, there're some mandatory setup:
- Enable any of the AOS that you want to make it as batch AOS
(Administration -> Setup -> Server configuration)
- Create batch group for printing.
Eg. One for client printing and one for server printing.
(Administration -> Setup -> Batch groups)
- Add the batch group created in #2 into the AOS enabled for batch processing (in #1)
Printing from server (print to printer)
- Enable the 'Allow clients to connect to printers on this server' settings at Dynamics AX Server Configuration Utility under the 'Application Object Server' tab.
- Enable the 'Connect to printers on the server' settings at Dynamics AX (client) Configuration Utility under the 'Connection' tab
- When printing report
> At the 'Batch' tab, check the 'Batch processing' and select the batch group created for server printing
> Click on the "Option" and select the server printer. Server printers are prefix with 'AOS:'
Printing from server (print to file)
- Enable the 'Allow clients to connect to printers on this server' settings at Dynamics AX Server Configuration Utility under the 'Application Object Server' tab.
*Although you're printing to file, but you still need to enable this.
- When printing report
> At the 'Batch' tab, check the 'Batch processing' and select the batch group created for server printing
> Click on the "Option" and select 'File', then ensure the file name is a UNC path (Eg.\\serverName\directory) else you'll get an error.
*After this job is added to the batch, you can check it at 'Basic > Inquiries > Batch job'. Click on the 'View tasks', notice that the 'Run location' is "Server". If your 'Run location' is "Client", then you might have selected a client printer or your report class method 'runsImpersonated()' has been overwritten to return "false".
Printing from client (through legacy batch processing)
- When printing report
> At the 'Batch' tab, check the 'Batch processing' and select the batch group created for client printing
> Click on the "Option" and select the client printer
- Run the legacy batch processing (Basic > Periodic > Batch > Processing)
*After this job is added to the batch, you can check it at Basic > Inquiries > Batch job. Click on the 'View tasks', look at the printing job/task, it will change from "Waiting" to "Ready", then to "Executing". Also notice that the 'Run location' is "Client". The legacy batch processing require the task to be in "Ready" status, this field cannot be changed manually, it is automatically changed if you've done step #3 in the prerequisites (it might not change immediately, give it some time then refresh it and look at the status again).
Some common errors:
- Use of printers on the server is not allowed
Resolution: Ensure the 'Allow clients to connect to printers on this server' settings at Dynamics AX Server Configuration Utility under the 'Application Object Server' tab is checked.
- Target file must be in UNC format

Resolution: Ensure when you select 'File' as the output, the 'File name' is UNC path. Eg. \\serverName\directory
- Selected printer is not an AOS printer

Resolution: Install the printer driver on the server.
Sometimes there're confusion regarding AOS printer and shared printer.
For printing to works in batch mode (running from server), the printer has to be AOS printer, which the printer is "Installed" as printer on the AOS host server, not "Connect" as shared printer.
Eg.
There's a print server with 5 printers shared out, the AOS "Connect" to these printers, all these printers will appear as "\\printServerName\printerName01", this will not appear as AOS printer, instead, they're client printer.
AOS printer is prefix with "AOS: " in front of the printer name in the printer selection list at print dialog.
The old/legacy client batch report printing in AX2009 concept also applies to the class. Let's say you have some process which utilize client code (Eg. needs to read Excel file), they won't run in the new AX2009 batch framework, you can then use the legacy batch processing, ensure the 'runsImpersonated()' method is overwritten to return "false", so that it will be run from client instead of server.
*Updated on 19/06/2012: Added details for "Selected printer is not an AOS printer"
Thursday, 28 April 2011
YouTube Internal Server Error 500
Got this message while trying to access a video, hey, they employ monkeys, that's hell smart of monkeys they are.
Haha, but of course you won't think that's real monkeys, Google just likes to jokes around.
Just do a refresh/reload, the error will go away (mostly).
============================
500 Internal Server Error
Sorry, something went wrong.
A team of highly trained monkeys has been dispatched to deal with this situation.
If you see them, show them this information:
....
....
....
....
Haha, but of course you won't think that's real monkeys, Google just likes to jokes around.
Just do a refresh/reload, the error will go away (mostly).
============================
500 Internal Server Error
Sorry, something went wrong.
A team of highly trained monkeys has been dispatched to deal with this situation.
If you see them, show them this information:
....
....
....
....
Wednesday, 13 April 2011
Creating serial number in Dynamics AX
If you happen to need serial number for testing your code/functionality, one of the quickest way is to create it manually at the ‘Serial numbers’ form.
Path: Stock management > Inquiries > Dimensions > Serial numbers
Tuesday, 29 March 2011
Create Dynamics AX Trace Parser database
If you're wondering how can you create Dynamics AX Trace Parser database, it's created through the "Register Database" menu.
Here're the step:
1. Open Dynamics AX Trace Parser2. Click on: File > Register Database
Older version of Trace Parser3. Enter the details for 'DatabaseServer' and 'DatabaseName'
Newer version of Trace Parser (come with AX2012)
4. If the database never exist, it will prompt for confirmation to create the database, else it will just register and use it.
*NOTE: Do not use old/previous version of TraceParser database on a newer TraceParser. Someone might thought, backup the existing DB, restore it and use it on new version of TraceParser, it might looks OK when you start up, but might throw unexpected error when you import trace file or view the existing trace. Another common issue, which is similar to the above, is connecting newer version TraceParser to old TraceParser database.
Tuesday, 7 December 2010
Switching Trace Parser between AX4, AX2009, & AX2012
When Trace Parser is started up, it will login to AX through business connector. If you have different version of AX, it won't prompt to ask about which version of AX it should use. If you need to switch between the version the Trace Parser logon to, you'll need to edit the Trace Parser config file.
Open the file 'Microsoft.Dynamics.AX.Tracing.TraceParser.exe.config' (under the Trace Parser installation path) and edit the line: <bindingRedirect oldVersion="5.0.0.0" newVersion="5.0.0.0"/>
Open the file 'Microsoft.Dynamics.AX.Tracing.TraceParser.exe.config' (under the Trace Parser installation path) and edit the line: <bindingRedirect oldVersion="5.0.0.0" newVersion="5.0.0.0"/>
Set the 'newVersion="5.0.0.0"' to the version you want.
Eg.
To logon to AX4: <bindingRedirect oldVersion="5.0.0.0" newVersion="4.0.0.0"/>
To logon to AX2009: <bindingRedirect oldVersion="5.0.0.0" newVersion="5.0.0.0"/>
If that doesn't works, it might be due to the 32/64bit issue.
Below is the excerpt from the an email I received.
=============================
Verify that both 4 and 5 BC.Net are in the GAC by opening up c:\windows\assembly from the start menu. If so, then the following should work:
<bindingRedirect oldVersion="5.0.0.0" newVersion="4.0.0.0" />
If that still doesn’t work, it may be an issue with 32/64 bit. BC.Net has both x86 and x64 for AX2009 but only x86 for AX4. If you have Visual Studio, you could open a visual studio command prompt and run
corflags /32BIT+ Microsoft.Dynamics.AX.Tracing.TraceParser.exe
Combined with the bindingRedirect, this should solve the problem.
=============================
*UPDATE: To connect to AX2012, just do the similar changes to the config file to version 6.0.0.0.
Monday, 6 December 2010
Event ID 117: Changed language setting to us_english.. The SQL statement was: "UPDATE SYSLASTVALUE SET VALUE ...
Below are two of the common errors seen in AX and the explanation of them from Microsoft support.
=========================
Event ID: 117
Description:
Object Server 01: The database reported (session 1 (-AOS-)): [Microsoft][ODBC SQL Server Driver][SQL Server]Changed language setting to us_english.. The SQL statement was: "UPDATE SYSLASTVALUE SET VALUE=?,RECVERSION=? WHERE (((((((USERID=?) AND (RECORDTYPE=?)) AND (ELEMENTNAME=?)) AND (DESIGNNAME=?)) AND (ISKERNEL=?)) AND (COMPANY=?)) AND (RECVERSION=?))"
Event ID: 110
Description:
Object Server 01: Dialog issued for client-less session 1: Cannot edit a record in LastValue (SysLastValue). User ID: , AdminUserSetup.
The SQL database has issued an error.
Description:
Object Server 01: The database reported (session 1 (-AOS-)): [Microsoft][ODBC SQL Server Driver][SQL Server]Changed language setting to us_english.. The SQL statement was: "UPDATE SYSLASTVALUE SET VALUE=?,RECVERSION=? WHERE (((((((USERID=?) AND (RECORDTYPE=?)) AND (ELEMENTNAME=?)) AND (DESIGNNAME=?)) AND (ISKERNEL=?)) AND (COMPANY=?)) AND (RECVERSION=?))"
Event ID: 110
Description:
Object Server 01: Dialog issued for client-less session 1: Cannot edit a record in LastValue (SysLastValue). User ID: , AdminUserSetup.
The SQL database has issued an error.
=========================
From my research the cause of this is that an update conflict occurs when updating a table with a blob type field, like SysLastValue table. The kernel uses ODBC function SQLParamData to put data into a blob field, in case of an update conflict SQLParamData returns SQL_NO_DATA. The AX kernel misinte rprets this return value, thinking that SQL server has raised an error, and so raises the two messages in the event log - message 110 indicates the update failed, message 117 is the last message raised from SQL server, which is actually just a standard information message that is normally not shown , as there is no actual error from SQL, it is only misinterpretation from AX kernel.
Tuesday, 23 November 2010
Basic TableGroup and CacheLookup rules
Below are some of the basic rules for setting Dynamics AX TableGroup and CacheLookup property.
| Table Type | Usage | Table Group to Use |
| Transactional | If updating Financials | Transaction |
| Transactional | If not updating Financials and is used as a Header | WorksheetHdr |
| Transactional | If not updating Financials and is used as a line related to a header | WorksheetLine |
| Master Data | Parameter Table | Parameter |
| Master Data | Core Master Data Like Customers | Main |
| Master Data | Grouping of Master data into Categories | Group |
Based on this table group, caching needs to be set based on:
| Table Group | Cache Type |
| Transaction, WorkSheetHdr, WorkSheetLine | NotinTTS |
| Parameter | EntireTable |
| Main, Group | Found |
| Group (if very small and below 128K) | EntireTable |
Once the Cache Lookup is set, analysis needs to be done to set the right primary key for most efficient use of caching.
Although these are the basic rules, but occasionally there're situation where they needs to be set differently.
Tuesday, 21 September 2010
Basic algorithm for the "Auto update statistics"
This is an excerpt from one of the support call I read recently, thought it would be beneficial to share it.
========================
Basically the SQL database engine will not update statistics every time a record is change, added or deleted. There is a change threshold for each table, and this is what effect the statistics update. So if you have a customer with large tansaction volumes, you could find that this update process is not triggered frequently enough.
The following describes the basic algorithm for the "auto update statistics" process:
The following describes the basic algorithm for the "auto update statistics" process:
- If the cardinality (in most cases this means row count) for a table is less than six and the table is in the tempdb database, auto update with every six modifications to the table.
- If the cardinality for a table is greater than 6, but less than or equal to 500, update status every 500 modifications.
- If the cardinality for a table is greater than 500, update statistics when (500 + 20 percent of the table) changes have occurred.
- For table variables, cardinality changes does not trigger auto update statistics.
Therefore you may find that large tables are only statistically updates when the row count increases by 20%. But this does not really take into account updates, and this does not change the row count. Therefore you may find that if you make lots of updates, the data statistics on the are not in tune with this updated data. So in this case, updating the statistics manually from a scripts would help the query optimiser when the process is run.
========================
Thursday, 16 September 2010
(Dynamics AX) Failed to establish connection at Terminal Server
The "Failed to establish connection" in Dynamics AX is a common error seen and these are the common reasons:
- AOS is down
- AX configuration is incorrect
- Firewall blocked the port used
- Connection issue between client and AOS
- User account is locked
But occasionally, my colleagues encountered this error at the Terminal Server (where all of us logon to), while there's no changes to anything (AX configuration, security, network, and etc), his/her AX suddenly doesn't works, can't connect to the AOS. Restart AOS or logon logoff from Terminal Server doesn't helps. Checked the 5 possible causes listed above, none of them is the cause.
I investigate further, AOS is running, port is not blocked, I logged on to the Terminal Server and start up AX client (all works fine, able to start up and forms opened OK). I asked a few other colleague to logon to the same Terminal Server and start up AX, all of them doesn't have the problem. So, what happens that only 2 of my colleagues unable to logon (Failed to establish connection)? The weird thing is the next day it's working fine for them, but on and off, it happens again (and to other users). Until today, I still doesn't know what could have cause this, but based on a random suspect, I do found the way to solve this - refresh group policy.
I was thinking, since it only happens to particular users, could it be profile or security changes? I then tried refresh the group policy, hooray, it works.
Here's what I do:
- Open command prompt (Start > Run > cmd)
- Type in "gpupdate /Force" and press "Enter"
(it will refresh the group policy and prompt whether OK to logoff) - Press "Y" and logged-off
- Login again and it is now working fine
If you know what could have cause this and why, do leave a message here, others could benefit from it.
Thursday, 9 September 2010
Change password from Terminal Server session
If you're looking around the way to change password from within Terminal Server session due to pressing Ctrl + Alt + Del is applied to your host machine rather than Terminal Server, you just need to change the last "Del" to "End".
Instead of pressing "Ctrl + Alt + Del", you press "Ctrl + Alt + End", you'll get the window where you see the button for Lock, Logoff, Shutdown, Change password, Task Manager and Cancel at your Terminal Server session. Now you can click on the "Change password" button to change your password.
Wednesday, 21 July 2010
Renew Malaysian passport in UK (London)
[Update, 12/04/2017]
This article is 7 years old and there has been some change since then.
Eg. The new address is 52 Bedford Row, London WC1R 4LR. Hardcopy photo is not required, will capture it on the spot, etc. Please read visitors comments below the article to get some insight of the recent change and their experience.
------------------------------------------------------
Below is the original article dated 21/07/2010
------------------------------------------------------
This article is 7 years old and there has been some change since then.
Eg. The new address is 52 Bedford Row, London WC1R 4LR. Hardcopy photo is not required, will capture it on the spot, etc. Please read visitors comments below the article to get some insight of the recent change and their experience.
------------------------------------------------------
Below is the original article dated 21/07/2010
------------------------------------------------------
Just to share some info regarding how to renew Malaysian passport at UK.
I'll make it short and simple based on my own experience.
- Take any transportation method to 45 Belgrave Square, London, SW1X 8QT
- Walk down to basement
- Photoshop is on the left, go straight
(if you doesn't have blue background passport photo, you may take it here, it cost £5)
- Reception & waiting room is on the right - Walk in and go straight to the reception and sign the guest book. You'll then be called and given a ticket number (you'll need to show him your passport, IC, & photos as well).
[I guess the purpose of showing them is to verify you have the required documents] - Wait till your number is displayed on the notification board, walk out the waiting room, turn right (has to open the door)
- Walk straight to the end, the counter is over there to process your passport renewal application
- You’ll need pass these to the staff:
- Passport
- Original IC
- Photostat IC (1x)
- Passport photo (2x) - Sit and wait
- You'll be called again to scan the thumb print for both hand (digital scanning)
(You're required to put on the ink and thumb print on the application form as well) - Pay the fees (cost £50 for 32 pages)
- You'll be given the receipt with time to come back to collect the passport
...
...
(processing)
...
... - Return to the Malaysian High Commission office at the time slot indicated in the receipt and go straight to the counter (not the waiting room) [usually 3.00pm - 4.00pm]
- Pass the blue receipt to the staff and wait to be called
- Called and collect passport
Done.
Common questions & answers:
- Can I carry bag(s) or mobile phone into Malaysian High Commission office?
Yes, you're allowed to carry bag(s) into the waiting room.
(I've called Malaysian High Commission to check prior to the visit)
- If passport expire earlier than visa, do I need to transfer the visa to the new passport?
No, you doesn't need to transfer the visa, you may travel together with the old passport.
(I've called UK Border to check).
- How long is the processing time for Malaysian passport renewal at London, UK?
Process and collect on the same day.
- What time is the Malaysian High Commission office open for application and collection?
For application: 9.00am - 11.00am
For collection: 3.00pm - 4.00pm
- What's the website of Malaysian High Commission office at London, UK?
http://www.jimlondon.net (Jabatan Imigresen Malaysia London)
- Is there any passport photo or photocopy service at Malaysian High Commission office at London, UK?
Yes.
Passport photo: To the left at the main entrance (at basement)
Photocopy: Eg. I/C. To the right in the waiting room
The above details is my experience as of 20/07/2010.
I would suggest you visit the website for latest info.
Subscribe to:
Posts (Atom)










