Internet Explorer

Citrix StoreFront – Experiences with Storefront Customization SDK and Web API

2017-04-24
/ /
in Blog
/

Our organization has been exploring upgrading our Citrix environment from 6.5 to 7.X.  The biggest road blocks we’ve been experiencing?  Various nuanced features in Citrix XenApp 6.5 don’t work or are not supported in 7.X.

This brings me to this post and an example of the difficulties we are facing, my exploration of solutions to this problem, and our potential solution.

In Citrix Web Interface 5.1+ you can create a URI with a set of application launch parameters and those parameters would be passed to the application.  This is detailed in this Citrix article here (CTX123998).  For us, these launches occur with a Site (WI5.4 terminology) or Store (Storefront terminology) that allows anonymous (or unauthenticated) users.

By following that guide and modifying your Web Interface you can change one of your sites so that it accepts launch parameters.  You simply enter a specific URI in your browser, and the application would launch with said parameters.  An example:

http://bottheory.local/Citrix/XenApp/site/launcher.aspx?CTX_Application=Citrix.MPS.App.XenApp.Notepad&LaunchId=1263894298505&NFuse_AppCommandLine=C:\Windows\WindowsUpdate.log

This allows you to send links around to other people and they can click to automatically launch an application with the parameters specified.  If you are really unlucky, your org might document this as an official way to launch a hosted application and this actually gets coded into certain applications.  So now you may have tens of local apps utilizing this as an acceptable method to launch a hosted application.  For an organization, this may be an acceptable way to launch certain hosted applications since around ~2008 so this “feature”, unfortunately, has built up quite a bit of inertia.

We can’t let this feature break when we move to StoreFront.  We track the number of launches from these hosted applications and it’s in the hundreds/thousands per day.  This is a critical and well used feature.

So how does this work in Web Interface and what actually happens?

URI substitution and launch process

The modifications that you apply add a new ‘query’ to the URI that is picked up.  This ‘query’ is “NFuse_AppCommandLine” and the value it is equal to (“C:\Windows\WindowsUpdate.log” in my example) is passed into the ICA file.

The ICA file, when launched, will pass the parameter to a special string “%**” the is set on the command line of the published application.  This token “%**” gets replaced by the parameter specified in the ICA which then generates the launch string.  This string is executed and the result is the program launches.

Can we do this with Storefront?  Well, first things first, is this even possible with XenApp/XenDesktop 7.X?  In order to test this I created an application and specified the special token.

I then generated an ICA file and manually modified the LongCommandLine to add my parameter.  I then launched it:

 

Did it work?

Yes, it worked.

Success!  So XenApp/XenDesktop 7.X will substitute the tokens with the LongCommandLine in the ICA file.  Excellent.  So now we just need Storefront to take the URI and add it to the LongCommandLine.  Storefront does not do this out of the box.

However, Citrix offers a couple of possible solutions to this problem (that I explored).

StoreFront WebAPI
StoreFront Store Customization SDK

What are these and how do they work?

StoreFront Web API

This API is billed as:

“Write a new Web UI or integrate StoreFront into your own Web portal”

We are going to need to either modify Storefront or write our own in order to take and parameters in the URI.  I decided to write our own.  Using the ApiExample.html in the WebAPI I added the following:

This looks into the URI and allows you to get the value of either query string.  In my example I am grabbing the values for “CTX_Application” and “NFuse_AppCommandLine”.

I then removed a bunch of the authentication portions from the ApiExample.html (I’ll be using an unauthenticated store).  In order to automatically select the specified application I added some javascript to check the resource list and get the launch URL:

There is a function within the ApiExample.html file that pulls the ICA file.  Could we take this and modify it before returning it with the LongCommandLine addition?  We have the NFuse_AppCommandLine now.

It turns out, you can. You can capture the ICA file as a variable and then using javascripts ‘.replace’ method you can modify the line so that it contains your string.  But how do you pass the ICA file to the system to launch?

This is how Citrix launches the ICA file in the ApiExample.html:

It generates a URL then sets it as the src in the iframe.  The actual result looks like this:

The ICA file is returned in this line:

When we capture the ICA file as a variable the only way that I’ve found you can reference it is via a blob.  What does the src path look like when do that?

Ok, this looks great!  I can create an ICA file than modify it all through WebAPI and return the ICA file to the browser for execution.  Does it work?

Yes and no. 🙁

It works in Chrome and Firefox, but IE doesn’t auto-launch.  It prompts to ‘save’ a file.  Why?  IE doesn’t support opening ‘non-standard’ blobs.  MS offers a method called “msSaveOrOpenBlob” which you can use instead, and this method then prompts for opening the blob.  This will work for opening the ICA file but now the end user requires an extra step.  So this won’t work.  It needs to be automatic like its supposed to be for a good experience.

So WebAPI appears to offer part of the solution.  We can capture the nFuse_AppCommandLine but we need to get it to LongCommandLine.

At this point I decided to look at the StoreFront Store Customization SDK.  It states it has this ability:

Post-Launch ICA file—use this to modify the generated ICA file. For example, use this to change ICA virtual channel parameters and prevent users from accessing their clipboard.

That sounds perfect!

StoreFront Store Customization SDK

The StoreFront store customization SDK bills one of its features as:

The Store Customization SDK allows you to apply custom logic to the process of displaying resources to users and to adjust launch parameters. For example, you can use the SDK to control which apps and desktops are displayed to users, to change ICA virtual channel parameters, or to modify access conditions through XenApp and XenDesktop policy selection.

I underlined the part that is important to me.  That’s what I want, exactly!  I want to adjust launch parameters.

To start, one of the tasks that I need is to take my nFuse_AppCommandLine and get it passed to the SDK.  The only way I’ve found to make this happen is to enable ‘forwardedHeaders‘ in your web.config file.

With this, you need to set your POST/GET Header on your request to Storefront to get this parameter passed to the SDK.  Here is how I setup my SDK:

Install the “Microsoft Visual Studio Community Edition” on a test StoreFront server.

 

Download the StoreCustomizationSDK and open the ‘Customization_Launch’ project file:

 

Right-click ‘Customization_Launch’ and select ‘Properties’.

 

Modify the Outpath in Build to the “%site%\bin” location.  This is NOT the %site%Web, but just the %site%.

Open the LaunchResultModifer.cs

 

Set a breakpoint somewhere in the file.

Build > Build ‘Customization_Launch’

Ensure the build was successful:

If you get an error message:

Just ignore it.  We’re compiling a library and not an executable and that’s why you get this message.

Now we connect to the debugger to the ‘Citrix Delivery Services Resources’.  Select ‘Attach to Process…’

Select the w3wp.exe process whose user name is ‘Citrix Delivery Services Resources’.  You may need to select ‘Show processes from all users’ and click ‘ Attach.

Click ‘Attach’.

Browse to your website and click to launch an icon:

Your debugger should pause at the breakpoint:

And you can inspect the values.

At this point I wasn’t interested in trying to re-write the ApiExample.html to get this testing underway, I instead used PowerShell to submit my POST’s and GET’s.  Remember, I’m using an unauthenticated store so I could cut down on the requests sent to StoreFront to get my apps.  I found a script from Ryan Butler and made some modifications to it.  I modified it to remove the parameters since I’m doing testing via hardcoding 🙂

Executing the powershell script and examining a custom variable with breakpoint shows us that our header was successfully passed into the file:

Awesome!  So can we do something with this?  Citrix has provided a function that does a find/replace of the value you want to modify.  To enable it, we need to add it the ICAFile.cs:

Browse to ICAFile.cs

 

At this point we can use the helper methods within the IcaFile.cs.  To do so, just add “using Examples.Helpers;” to the top of the file:

I cleaned out the HDXRouting out of the file, grabbed the nFuseAppCMDLine header, and then returned the result:

The result?

Success!  We’ve used the WebAPI and the StoreFront Customization SDK to supply a header, modify the ICA file, and return it with the value needed!  The ICA file returned works perfectly!  Ok, so I’m thinking this looks pretty good right?!  We just need to get the iframe to supply a custom header when the src gets updated.

Except I don’t think it’s possible to tag a custom header when you update a src in an iframe.   So then I started thinking maybe I can use a cookie!  If I can pass a cookie into the Storefront Customization SDK I could use that instead of the header.  Unfortunately, I do not see anyway to query a custom cookie or pass a custom cookie into the SDK.  Citrix appears to have (rightfully!) locked down Storefront that this doesn’t seem possible.  No custom cookies are passed into the httpcontext (that I can see).

So all this work appears to be for naught (outside of an exercise on how one could setup and customize Storefront).

 

But what about the Storefront feature “add shortcuts to websites“?

Although doing that will allow to launch an app via a URL, it doesn’t offer any method to pass values into the URL.  So it’s a non-starter as well.

Next will be a workaround/solution that appears to work…

Read More

EventID 6003 – The winlogon notification subscriber was unavailable to handle a critical notification event.

2016-05-31
/ / /

We updated one of our Citrix XenApp servers and this message started flooding our Application event log:
“The winlogon notification subscriber <TrustedInstaller> was unavailable to handle a critical notification event.”

So what’s going on here?

Examining the registry on a ‘good’ working system and the ‘bad’ system revealed the following:

2

Good TrustedInstaller – No Error 6003

 

1

Bad TrustedInstaller – Error 6003

How did that value get there?

It turns out we installed Internet Explorer 11 with our patch cycle — but that in and of itself did not cause our issue.  Additional components for IE 11 were installed as well:
3

“Microsoft Windows English Spelling Package” and “Microsoft Windows English Hyphenation Package”

Neither of these packages are present on any of the ‘working’ systems.  I tested to determine which of them placed the registry key there…

It turns out both of them do.  If you uninstall *either* package it will remove the ‘CreateSession’ value.  Since these packages are not in our standard build we are removing both.

Read More

Citrix Director 7.7 is giving me artifacts!

2016-01-19
/ / /

We are still in a pilot-preupgrade phase of Citrix Director 7.7 and found an issue where we were getting artifacts with IE11.  The artifacts manifested themselves like so:

This is wrong.
When the search box should look like this:
This is right.
This issue appears to be caused by a policy our organization uses to enable compatibility view for sites on the Local Intranet:
The Culprit
Citrix says the following about Director and ‘Compatibility View’:

Director does not support Internet Explorer compatibility mode. Please use the recommended browser settings. When you install Internet Explorer, accept the default to use the recommended security and compatibility settings. If you already installed the browser and chose not to use the recommended settings, go to Tools > Internet Options > Advanced > Reset and follow the instructions

Because we use a group policy to push this setting out, disabling it and re-enabling it on a site-per-site configuration isn’t acceptable.  There is an option to set the ‘zone assignment’ of our Citrix Director server to be on ‘Trusted Sites’ instead of ‘Local Intranet’ but this would be another policy that would have to be pushed out to the ~80,000 workstations we have.  Instead, there is another option.  We can edit the default.html file in the Citrix Director folder and add a line in thesection to tell IE to exclude this site from compatibility mode.  To execute this:
Edit the Default.html file (“C:inetpubwwwrootDirectordefault.html”) and add this line:

To the ‘head’ section.  Example:

Add the line around here
Delete your cache and now your website will work without issue.
Read More

Force Internet Explorer 10 or 11 to always use 64bit version

2015-10-25
/ / /

I was working on an issue where a user was always prompted to ‘Install’ the Citrix ICA client.  No matter how many times they downloaded and installed the client it continuously prompted them to install it again from the Web Interface:

I checked the add-on’s and saw the following:

No Citrix plugins in site.  I then checked Task Manager to confirm the IE type (32bit vs 64bit) and this is what I saw:

Without the *32, Internet Explorer is running in 64bit mode.  Currently, Citrix does not provide a 64bit plugin to IE so it won’t run and it won’t be detected.  I then exited IE and browsed to the Internet Explorer folder (C:program files (x86)Internet Exploreriexplore.exe) and attempted to launch iexplore.exe from there.  Still came up as 64bit.  So now this got interesting…  Microsoft does not allow or provide a way to force a 64bit default for IE on Windows 7.

So how is this happening?

It turns out there is a registry key you can set that will force IE to ALWAYS be 64bit:

HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth (or HKLM)

If the REG_DWORD is 0x0 it will always force IE to be 64bit.  Deleting or changing this value will default IE to 32bit.  So this key *could* be used to force IE to be 64bit.  There is a potential issue to be aware of, this will force IE to use the same process as the launcher for tabs, as opposed to spanning new processes.  Whether that increases/decreases stability would be something you’d have to test.

Read More

Internet Explorer Maintenance Odd Behaviour

2013-01-22
/ / /

Recently, I was experiencing some odd behaviour on some of our Windows boxes.  We were getting redirected to a proxy server but RSOP.MSC and group policy showed that we should have been good in the GUI.

The issue is IE Maintenance will store it’s settings in a INS file as opposed to the registry and for some reason IE Maintenance in GPEDIT.MSC doesn’t display the values.  This document details it more:

http://blogs.technet.com/b/perfguru/archive/2008/04/26/how-to-troubleshoot-internet-explorer-s-maintenance-group-policy.aspx

The INS files created via GPO are placed in the following locations:
2003-“C:\Documents and Settings\trententtye\Local Settings\Application Data\Microsoft\Internet Explorer”
2008-“C:\Users\trententtye\AppData\Local\Microsoft\Internet Explorer”

Read More

Internet Explorer popping up outside the App-V Bubble

2013-01-15
/ / /

We have an application that launches Internet Explorer for printing certain PDF documents that it creates.  Adobe Reader is in the AppV package and NOT locally on the server.  The application resides in an AppV bubble but Internet Explorer starts outside the bubble.  I was able to verify that by starting the application with the debug switch “/exe cmd.exe” and running SET which shows some variables that only exist within an AppV bubble.  Once at the command prompt I launched the application and got to the point where it launched IE, from there I was able to use the IE open dialog to launch cmd.exe from the Windowssystem32 folder.  Once that was open I ran SET again and the AppV variables were not there; this confirmed that it was not in the AppV bubble.

It appears this issue is caused by XenApp because it modifies the Internet Explorer handler registry keys to point to a unique Citrix version of IE.  This version appears to open outside the bubble.  to correct this you need to change these registry keys:

With the keys set like that Internet Explorer will now launch within the AppV bubble.

Read More