SharePoint 2010 - Edit Document via Citrix XenApp

Whilst recently performing a new SharePoint 2010 deployment for a client, I was presented with the following problem.  The client was using Citrix XenApp to deploy and manage Office 2010 on their users' desktops and as such was receiving the following error message

 

"The document could not be opened for editing. A Microsoft SharePoint Foundation compatible application could not be found to edit the document."

...when attempting to use the "Edit in {office app}"  from the document menu.


 

Now as you may (or may not) already be aware, by default SharePoint is configured to use the ‘owssupp.dll' ActiveX control to open Office documents in "edit mode", which is installed as part of the "SharePoint Support features" of the client's Office installation. (Further info on the subject see: http://bradleychetty.blogspot.com/2011/08/microsoft-sharepoint-foundation.html )

Now as the client was running Office via Citrix, there was no local installation of Office on the desktop machines and therefore no ‘owssupp.dll'.

The obvious solution to the problem was to simply run the "IE browser session" via Citrix as well, which does work as long as the "webclient service" is running on the Citrix server (see http://support.citrix.com/article/CTX125214).

However, the client didn't want to use Citrix for all web and internet traffic and didn't really want to give their users two browser links on the desktops (ie. one to browse SharePoint via Citrix and another local one for all other web/internet access).

 

So, what to do?

Well, SharePoint uses the DOCICON.XML file to control which documents are associated with a particular application (More information on how this works can be found at "Understanding DocIcon.xml files"), but basically the "OpenControl" attribute is used to specify the name of the ActiveX control used to open the particular document type (see http://msdn.microsoft.com/en-us/library/aa979488.aspx).

So one quick Google search later, and I found a useful article from "Manpreet's SharePoint Developer Blog", which covered the basics of "writing a custom SharePoint.OpenDocuments" control (and even includes source code for his ‘Malag.OpenDocuments control' as a starter for ten!).

It was at this point that the client pointed out they also had some "remote users" (connected over vpn) who didn't have access to Citrix, but DID have a local copy of Office installed on their Laptops and would need the same ability to "Edit Office Documents" directly from SharePoint...

 

Now as far as I'm aware, the DOCICON.XML file only permits a "one-to-one" association per file type, so using a "custom OpenDocuments" control (to open files via Citrix) wasn't going to be an option as the Citrix PNAgent wouldn't be available on the laptops of the remote users.

 

It seemed there was a requirement for two "Edit in {office app}" menu items to be available via the SharePoint user interface. One to open/edit the file via Citrix and another to use local installation of Office (ie. the default SharePoint "Edit" action)

So I came up with the following "sandbox solution" to achieve this:

1.       Create a "custom menu item"

See the following for further info:

http://www.thespgeek.com/2011/01/how-to-add-custom-menu-item-in.html

http://msdn.microsoft.com/en-us/library/ms473643.aspx

http://msdn.microsoft.com/en-us/library/ms460194.aspx

 

I set the "Scope" of my feature to "Site", so that it could be activated on a "per site-collection" basis, but obviously if you'd prefer it be controlled on a "per site" basis you could set your scope to be "Web".

 

2.       In the Elements.xml file,

 

..include a reference to a "CustomAction ScriptBlock", which includes the following code:

<CustomAction

    Location="ScriptLink"

    ScriptBlock='function doOpenWithCitrix(paramval, OfficeApp){

    openCitrixOfficApp(getUNCPath(paramval), OfficeApp);}

    function openCitrixOfficApp(strFileapth, strOfficeAppName){

    var oShell = new ActiveXObject("Shell.Application");

    var citrixCmd = "C:\\Program Files\\Citrix\\ICA Client\\pnagent.exe";

   /*Note - The Path to your pnagent.exe may need to be adjusted */

    var commandParms = " /QLaunch \""+ strOfficeAppName +"\" /param:\"" + strFileapth +"\" ";

    oShell.ShellExecute(citrixCmd, commandParms, "", "open", "1");}

    function getUNCPath(url){           

    var returnVal;

    returnVal = decodeURI(url);

    returnVal = returnVal.replace(new RegExp("/", "g"), "\\");

    returnVal = returnVal.replace(new RegExp("http:", "g"), "");

    returnVal = "\\\\" + location.hostname + returnVal;

    return returnVal;}'

    Sequence="101">

</CustomAction>

 

This JavaScript attempts to run the Citrix PNAgent.exe, along with the path to the Office document stored in SharePoint as a parameter.

For some reason Citrix didn't seem to like "http://" paths, so I have included a ‘getUNCPath' function which attempts to convert the URL of the document item to a UNC path.

(Again, please note that Citrix requires the "webclient service" to be running on the Citrix server so that it is able access the files via UNC paths - or rather via webDAV)

It is possible include the script in a ".js file" if you prefer (see http://blog.voyta.net/2010/09/12/referencing-javascript-files-using-customaction-in-sharepoint-2010-sandboxed-solutions/), but it's not necessary for the purposes of this example.

 

3.       Include the following "Custom Action"(s)

 

<CustomAction

    Id="CitrixOffice_Word2010"

    RegistrationType="FileType"

    RegistrationId="doc"

    Rights="EditListItems"

    ImageUrl="/_layouts/images/icdoc.png"

    Location="EditControlBlock"

    Sequence="252"

    Title="Edit in Microsoft Word 2010 (via Citrix)" >

    <UrlAction Url="javascript : doOpenWithCitrix('{ItemUrl}', 'Word 2010');"/>

  </CustomAction>

  <CustomAction

    Id="CitrixOffice_Word2010"

    RegistrationType="FileType"

    RegistrationId="docx"

    Rights="EditListItems"

    ImageUrl="/_layouts/images/icdoc.png"

    Location="EditControlBlock"

    Sequence="252"

    Title="Edit in Microsoft Word 2010 (via Citrix)" >

    <UrlAction Url="javascript : doOpenWithCitrix('{ItemUrl}', 'Word 2010');"/>

  </CustomAction>

 

  <CustomAction

    Id="CitrixOffice_Excel2010"

    RegistrationType="FileType"

    RegistrationId="xls"

    Rights="EditListItems"

    ImageUrl="/_layouts/images/icxls.png"

    Location="EditControlBlock"

    Sequence="252"

    Title="Edit in Microsoft Excel 2010 (via Citrix)" >

    <UrlAction Url="javascript : doOpenWithCitrix('{ItemUrl}', 'Excel 2010');"/>

  </CustomAction>

  <CustomAction

    Id="CitrixOffice_Excel2010"

    RegistrationType="FileType"

    RegistrationId="xlsx"

    Rights="EditListItems"

    ImageUrl="/_layouts/images/icxls.png"

    Location="EditControlBlock"

    Sequence="252"

    Title="Edit in Microsoft Excel (via Citrix)" >

    <UrlAction Url="javascript : doOpenWithCitrix('{ItemUrl}', 'Excel 2010');"/>

  </CustomAction>

 

  <CustomAction

    Id="CitrixOffice_Ppoint2010"

    RegistrationType="FileType"

    RegistrationId="ppt"

    Rights="EditListItems"

    ImageUrl="/_layouts/images/icppt.png"

    Location="EditControlBlock"

    Sequence="252"

    Title="Edit in Microsoft PowerPoint 2010 (via Citrix)" >

    <UrlAction Url="javascript : doOpenWithCitrix('{ItemUrl}', 'PowerPoint 2010');"/>

  </CustomAction>

  <CustomAction

    Id="CitrixOffice_Ppoint2010"

    RegistrationType="FileType"

    RegistrationId="pptx"

    Rights="EditListItems"

    ImageUrl="/_layouts/images/icppt.pngg"

    Location="EditControlBlock"

    Sequence="252"

    Title="Edit in Microsoft PowerPoint 2010 (via Citrix)" >

    <UrlAction Url="javascript : doOpenWithCitrix('{ItemUrl}', 'PowerPoint 2010');"/>

  </CustomAction>

 

Each of these, creates a new Menu Item (with the call to the custom JavaScript ) based on the associated FileType/FileExtension.

Note: the second parameter passed to the "doOpenWithCitrix" function needs to be the Application Name that is published in Citrix.

In this particular example, I have simply specified "'Word 2010', ‘Excel 2010' or ‘PowerPoint 2010'", but obviously these may vary depending on your Citrix setup.

 

You should then be able to publish your feature as a Sandbox Solution and see the following additional menu item

 

 

 

The final step that is required to get this working is to "Enable" the "Initialize and script ActiveX controls not marked as safe"in the Internet Explorer Security Options.

(unfortunately the "new ActiveXObject("Shell.Application");" javascript call requires this setting to be enabled to function correctly).

 

 

NOTE: To prevent creating a security risk I would ONLY RECOMMEND changing this security option for "Trusted Sites" (which obviously then needs to be controlled and/or restricted).

 

 

The source code and Visual Studio 2010 project is attached along with a complied ".wsp" file: 

download  EditViaCitrixOffice_MenuItem.zip

Comments

No Comments

Leave a Comment

(required)  
(optional)
(required)  
Add