ClientName in Citrix environment

Hi,

4D v18R2, Windows, Citrix
We run a 4D application in a Citrix environment where we need the “client name” of the running client session.
Until now, the only way to get the correct clientname is by launching cmd.exe

$command:="cmd.exe /C echo %ClientName%"
$in:=""
$out:=""
$error:=""

SET ENVIRONMENT VARIABLE("_4D_OPTION_HIDE_CONSOLE";"true")
LAUNCH EXTERNAL PROCESS($command;$in;$out;$error)

I also tried it with the 4D command

$vT_Current_machine:=Current machine

but this does not seem to work (not the correct or empty value)

I tried it by getting the environment variable with Win32API

$vL_Error:=sys_GetEnv ("CLIENTNAME";$vT_Current_machine)

but also this does not seem to be the solution

My question: Does anybody know of a best way to get the correct ClientName in a citrix environment using an out of the box 4D command?

Hi,

Did you try Get system info with the “accountName” property ?

sys_GetEnv seems to call _dupenv_s…but is that how the information is generally looked up in C, or on platforms other than 4D?

How about ExpandEnvironmentStrings…?

I will try to get accountName

$systemInfo:=Get system info

Do you know if the commands Current machine and Current system user always return the same values as resp. $systemInfo.machineName and $systemInfo.accountName ? On my Windows laptop it does, but I know that in Citrix environments other rules apply (mostly controlled by the hosting party)

Do you know if the commands Current machine and Current system user always return the same values as resp. $systemInfo.machineName and $systemInfo.accountName ?

“always” I don’t know.
On my TSE environment, it does : 2020-06-25 10_48_16-Window

1 Like

I also notice another thing with

$systemInfo:=Get system info

It takes about 1 second to complete on my system. I find this quite long

Given the amount of information, I suppose it takes time to ask all this to system. Anyway, except volumes, it’s not supposed to change a lot, so once you’ve called it you could avoid to call it again. Something like

if (Storage.mySysInfo=null)
 use (Storage)
  Storage.mySysInfo:=get system info
 end use
end if

Hi Arnaud,

Unfortunately, this is not true with Citrix environments
Although not advised, sometimes a user “takes over” a citrix session on another machine
The 4D client is then still running, but the systems client name has changed
We use this clientname for communication, and need it to have the actual value, so getting the value every time before doing communication

Hi Miyako,
How do I do that?

Hi,

image

Client Name is the machine starting the citrix session, we need this value
Machine Name is the citrix server, we don’t need this value
Account Name is the user logging in, we don’t need this value

The value we need (Client Name) is an environment variable that can be retrieved either with LEP

cmd.exe /C echo %ClientName%

or with WIN32API

sys_GetEnv ("CLIENTNAME";$vT_Current_machine)

Both commands return the same value
The strange thing with this is, that they don’t refresh. So while the variable changes, its value is not refreshed in 4D. I need to restart 4D to get the new value

Anybody?

That’s the way an OS is working or at least shells are working.

Example: If you opened a shell (in Windows cmd e.g.) and then you change the PATH variable using other controls of the OS the changed PATH variable isn’t reflected in the shell. You have to start a new one.

I’m not sure, but there could be way to force the reloading of the environment. But I don’t remember …

Yes, I think I’ve seen that, B takes the seat of A and A is disconnected… That said, the citrix session is the same but the 4D client is not, B has the “On startup” method executed, no? Then you could execute Get system info on startup.

I think the app that changed the environment is encouraged to post a WM_SETTINGCHANGE message on Windows, but other processes are free to ignore it.

Meanwhile, posted a really simple proof-of-concept here.

Can it be different that we use 4D Volume Desktop?
When taking over the citrix session, we are still in the app, in the same window etc. so no startup here.

Hi Miyako,

Unfortunately I dno’t have time to test it right now, but I sure am interested
I get back to it next week.

Thanks,
Piotr

Perhaps the value can be obtains directly from the registry?

c.f. https://rcmtech.wordpress.com/2011/06/09/how-to-get-clientname-within-logon-script-on-server-2008-r2-xenapp-6/

see also https://github.com/chocolatey/choco/blob/master/src/chocolatey.resources/redirects/RefreshEnv.cmd

Hi Miyako,

You posted a posted a really simple proof-of-concept. What does this poc do?
Is the batch file from chocolatey a replacement of this poc?

Is executing

cmd.exe /C echo %ClientName%

other than using the batch file from chocolatey?

Is using WIN32API command

sys_GetEnv ("CLIENTNAME";$vT_Current_machine)

other than using the batch file from chocolatey?

Did you click the link? It gives the API (in C) used internally. You can also browse the source. But no, I don’t used any batch files.

The chocolatey example is about reading the values from the registry in response to a window message. The plugin does not do that.

Hi Miyako,

Your “simple proof of concept” plugin seems to work for me i.e. it gets the environment variable “CLIENTNAME” from the environment
So no poc for me anymore… I am going to use it, replacing the WIN32API command :grinning:
I am not a C expert, and I have not browsed the source

The one thing that still does not work is that the environment variable I am interested in, i.e. “CLIENTNAME”, does not refresh until I restart 4D
I have looked at the Microsoft documentation of _wgetenv and noticed the following remark :

…use the copy of the environment pointed to by the global variable _environ to access the environment

So apparently there exists such thing as a copy of the environment, and maybe this is the reason?
I don’t know, maybe you do?

Thanks for your help,
Piotr

If I understand the explanation correctly, 4D gets a copy of the environment variables at startup, as do all other processes. In other words, it is not like an inter-process variable, it is like a process variable.

Citrix may update the environment variable, but that change does not propagate automatically, as mentioned in the chocolatey comment. Instead of using regular APIs to get the environment variable, it seems one must mimic a process startup by loading all environment variables from the registry.