About Terminal Server, Citrix, Delphi and other stuff
Yesterday I was troubleshooting an application that was migrated to Citrix XenApp.
The application is able to use a high precision scale which is attached to the client pc’s com port. This com port is redirected to XenApp.
While testing users reported several issues, let’s have a look at them.
Error configuring COM Port
Within the application the comport to which the scale is connected must be configured:
After pressing "Registreer" to register the new com port the following error message was shown
This application reads data from an external device called SECUTEST.
The device is connected to a COM port which is redirected to the XenApp session. In contrast to Microsoft Remote Desktop Services COM ports are not automatically redirected in XenApp but need to be mapped via eg a logonscript (NET USE COM1: \\Client\COM1:) or using UEM.
In my case the COM port was mapped with RES Workspace Manager:
An application called Cardiology PACS was recently packaged for a Citrix XenApp environment. The functional tester reported a strange problem at the logon screen: after entering the username it was not possible to go to the password field with the TAB key.
This was a strange observation since I cannot imagine XenApp interfering with tab stops. So what was going on?
In the old situation the user was starting the application on his local pc. The application remembered the last username and pre-filled this, therefore the cursor was already in the Password field. The user simply entered his password and hit the Enter key:
On XenApp the Username field is not pre-filled because the last username is kept globally per machine. Therefore the user has to enter both the username and the password:
I tested the Tab key behavior in both situations and as I expected it didn’t work in both situations. This happens because the Tab Order has been messed up by the programmer (if you press Tab 9 times you do end up in the Username field).
Because this is something that would annoy me if I were the user I decided to fix it.
For this mechanism to work correctly the file twain_32.dll must be present in the Windows directory.
On Windows 2008 this dll should be copied from winsxs (side by side) to the windows directory as described in CTX123981.
On Windows 2003 the dll is already in the correct directory, however applications that are not Terminal Server Aware cannot find this dll because the Windows directory is redirected to the user profile. Citrix recommends copying twain_32.dll to each user’s profile directory but this will take up unnecessary space.
So what alternatives do we have?
Another post on something that happened last week, this time it’s about a Java based Application again.
This particular application wanted to download three DLL’s from the Webserver to the Java bin directory.
This presents us with several issues on a multi user server such as a Citrix of Terminal Server:
I assumed that if I preinstalled the DLL’s the application wouldn’t try to overwrite them but that didn’t work.
Then I monitored with Process Monitor if the Application wrote some kind of check file but at first I didn’t find anything.
So I decided to use the CorrectFilePaths shim to redirect the DLL’s to the user’s homedirectory (see Using the CorrectFilePaths shim to redirect an ini file to a writable location for an explanation).
A few days ago I was packaging an application that was writing an INI file in the application directory.
If you have read my earlier article, Using the CorrectFilePaths shim to redirect an ini file to a writable location, then you will probably think: create a nice shim and redirect that ini file!
But this application had a few challenges, the first being that it writes %COMPUTERNAME%.INI. The application’s developer probably assumed that a user is bound to one pc and that no other user’s use that pc.
To solve it we we need to catch all possible computer names (it would be nice if the CorrectFilePaths shims was able to accept wildcards and environment variables).
But it doesn’t so it means we have to add a parameter for each possible computer name. In my case that was doable because I have only 8 Citrix servers.
So I created a Fix using the Application Compatibility Manager as described in my previous post.
However it didn’t work, so I started to trace what happens.
Lately I wrote a few articles about fixing bad applications using Compatibility Shims. If you didn’t read them yet, here are the links:
I also described that you can install an Application Compatibility Database using the sdbinst command.
At first I just took a script task in my Altiris Server to deploy the database using sdbinst -q <dbname> but later on I got a better idea.
My collegue that is working with me on the current project was packaging another application that uses Oracle.
The interesting thing about it is that he ran into the same error I did: the Oracle client tries to create (and access) an Object in the Global namespace.
But he got an entirely different error message:
To confirm it was the same issue I gave a test user the Create Global Objects privilege and after logging on again the problem went away.
So I applied the same fix that I wrote about yesterday in Redirect Global Object to Local Objects (aka fix that bad app!) to this application and it worked nicely!
Today I was working on Unattended Installation of an Application called SmartDocuments.
The application seemed to behave nicely on a Multi User (Citrix/Terminal Server) environment: it writes user configuration to the user part of the registry and writes configuration files in a user accessible path.
When testing with a normal user account I ran into a problem though, I got an Oracle ORA-01019 error message:
The English message is ORA01019: unable to allocate memory in the user side.
Earlier today I wrote about Using the CorrectFilePaths shim to redirect an ini file to a writable location and believe it or not the next application I was working with today needed a nice shim as well.
This one was a little more complicated and that’s why I am writing a second post about it.
I am not sure if this is actuall documented somewhere but a Shim is not applied to Applications or DLL’s that reside in the system directory.
The application in question here is a Visual Basic 6 application which uses the VB6 runtime, msvbvm60.dll which resides usually in %systemroot%\system32.
We need to do two things if we want to apply the shim to msvbvm60.dll:
.NET .NET FrameWork Active Directory Altiris Automation Manager bug Citrix Dell Delphi Excel Exchange Exchange2003 Exchange2010 Hack HP iOS Java LinkedIn Linux Lync MSI Office Office 2010 Outlook Passat Password PowerPoint PowerShell RES RNS510 SasLibEx Security Terminal Server ThinApp TSAdminEx Unattended VBS VCDS Vista Visual Basic VMWare Volkswagen Windows PE Wordpress XenApp