web.sta – web-app, tar­get brow­ser is Inter­net Explo­rer 9 & 11

Text­Sys­tem – stan­da­lo­ne desk­top app­li­ca­ti­on, writ­ten in Java/Swing

Inter­me­dia­teLay­er – Cli­ent-Ser­ver app, lin­king web.sta and Text­Sys­tem together. 

web.sta can call Text­Sys­tem via the Inter­me­dia­teLay­er. Inter­me­dia­teLay­er crea­tes an HTTP ser­ver for this pur­po­se and web.sta sim­ply sends GET or POST requests to the local­host. Inter­me­dia­teLay­er pro­ces­ses the request para­me­ters and starts the Text­Sys­tem. The­re is no need for feed­back calls, so the inter­ac­tion sche­me is simp­le and robust enough.


In Citrix envi­ron­ment we can not crea­te several lis­tening sockets on the same IP address and port. It is necessa­ry eit­her to chan­ge the port, or to chan­ge the IP address. But Citrix pro­vi­des a spe­cial mecha­nism for cir­cum­ven­ting this restric­tion, without chan­ging the algo­rithm of the pro­gram. This mecha­nism is cal­led Vir­tu­al IP Loo­p­back. The admi­nis­tra­tor sim­ply con­fi­gu­re necessa­ry app­li­ca­ti­ons in the Citrix con­fi­gu­ra­ti­on panel and the app­li­ca­ti­on that uses local­host for socket con­nec­tions will recei­ve not, but an IP address in the form 127.0.0. <SID + 1>, whe­re SID is the ses­si­on ID of the Win­dows user.

The Pro­blem

All this worked fine under IE9 (and with other brow­sers too) on Win­dows Ser­ver 2008 R2. And then the cli­ents wan­ted some­thing new and Win­dows Ser­ver 2012 R2 appeared with IE11. And the who­le sys­tem stop­ped working. Regard­less of Citrix IE11 set­tings, when spe­ci­fy­ing “local­host” it always tri­es to estab­lish a con­nec­tion to, but nobo­dy lis­tens the­re. After a litt­le rese­arch, we came to the con­clu­si­on that this is a bug in IE11.


If the vir­tua­liz­a­ti­on for local­host does not work out of the Citrix box for IE11, then let’s wri­te it ourselves!

For the­se pur­po­ses, we deci­ded to wri­te a win­dows ser­vice, which will be the simp­lest web ser­ver, lis­ten to and redi­rect requests to the desi­red Inter­me­dia­teLay­er, based on the ses­si­on num­ber of the user. We did not find a simp­le solu­ti­on to get the SID, but we immedia­te­ly found SES­SI­ONNA­ME in the envi­ron­ment varia­bles. In IE via ActiveX we get the envi­ron­ment varia­ble, pass it as a para­me­ter to the HTTP request. In Rou­tingSer­vice by the ses­si­onna­me through wtsapi32.lib we get the ses­si­on num­ber. Then we redi­rect the HTTP request and return the respon­se to IE.

Some­thing went wrong

We began the tes­ting and inte­gra­ti­on of our ser­vice. But not ever­ything went as smooth as we would like.

As it tur­ned out, the name of the ses­si­on can be chan­ged, alt­hough we did not under­stand in what con­di­ti­ons it hap­pens. But often it hap­pen­ed that the ses­si­on name chan­ged, and IE11 only knows the initi­al value of the envi­ron­ment varia­ble. And per­sist­ent­ly pas­ses this value to the RoutingService.

What is in the registry?

It is necessa­ry to find ano­t­her way to get the ses­si­onna­me. We have loo­ked for infor­ma­ti­on about ses­si­ons in the regis­try and tha­t’s what they found: in HKEY_CURRENT_USER \ Vola­ti­le Envi­ron­ment we can get a list of ses­si­ons of the cur­rent user.

If the user ses­si­on is one, then ever­ything is fine, we can read and use it. And if the­re are a lot of ses­si­ons for one user, then we need to somehow deter­mi­ne which ses­si­on we are in. We could not come up with anything bet­ter than matching the path to the tem­pora­ry files folder.

Here is an example:

In IE, we get the cur­rent path to TEMP using ActiveX Scripting.FileSystemObject.

This way we mana­ged to get the name of our ses­si­on. But tha­t’s not all. The value of the keys under the Vola­ti­le Envi­ron­ment is, in fact, the SID is. That is, we can immedia­te­ly get the necessa­ry IP address in Java­Script and send a request to it.

Shall we sim­pli­fy it? 

Final­ly we can get the SID and estab­lish a con­nec­tion direct­ly, without using Rou­tingSer­vice. But the solu­ti­on still does not look beau­ti­ful. Stu­dy­ing the Inter­net show­ed that the pro­blem exists, but the solu­ti­on to this pro­blem is not descri­bed any­whe­re. And the Micro­soft keeps silence as well. 

We hope someo­ne with this spe­ci­fic pro­blem can bene­fit from our experience.