Thursday, May 25, 2006

Enabling the 'Edit in Microsoft Word' Functionality for Office 2000/XP Users

Ever since SharePoint v2 was released organizations have struggled with the Office 2003-dependent features of the product. The primary source of frustration are those functions that should work for all users but don’t – like the ‘Edit in [Application]’ link in document libraries. Users with Office 2000/XP get the dreaded “” error when trying to access files using this option, while Office 2003 users can continue working without interruption. While there are several workarounds for this missing functionality, all of them require Office 2000/XP users to perform different steps to access a document than those users who have Office 2003 installed on their system.

Fortunately, there is a way to overcome this problem. The ‘Edit in …’ option is exposed in the core JavaScript file OWS.JS located in the 60\TEMPLATE\LAYOUTS\1033 folder on each front-end web server. On or about line 1440 is the following function:

function editDocumentWithProgID2(strDocument, varProgID, varEditor)
{
var objEditor;
if (strDocument.charAt(0) == "/" strDocument.substr(0,3).toLowerCase() == "%2f")
strDocument = document.location.protocol + "//" + document.location.host + strDocument;
try
{
objEditor = new ActiveXObject(varEditor + ".2");
if (!objEditor.EditDocument2(window, strDocument, varProgID))
alert(L_EditDocumentRuntimeError_Text);
window.onfocus = RefreshOnNextFocus;
return;
}
catch (e)
{
}
try
{
objEditor = new ActiveXObject(varEditor + ".1");
window.onfocus = null;
if (SzExtension(strDocument) == "ppt" && varProgID == "")
varProgID = "PowerPoint.Slide";
if (!objEditor.EditDocument(strDocument, varProgID))
alert(L_EditDocumentRuntimeError_Text);
SetWindowRefreshOnFocus();
return;
}
catch (e)
{
alert(L_EditDocumentProgIDError_Text);
}
}

This function takes three parameters that define the document’s location, program ID, and the application which created it. The critical code in this function is found within the two Try…Catch blocks starting on line 1445. The first block applies to Office 2003 users (the “.2” designation appended to the variable varEditor indicates O2K3 clients), while the second is applicable to Office 2000/XP clients. This is the portion of the function that must be altered to enable the ‘Edit in …’ option for these users.

The original code identifies the application type and determines the correct application to launch based on settings in the DOCICON.XML file. For Office 2000/XP clients, the script must instead contain an explicit mapping between file extension and application (UPDATE: There is a way to parse the DOCICON.XML file dynamically to achieve these results but the code is lengthy and cumbersome – the performance trade-offs are probably not worth the effort). To achieve this, simply add a series of if…else if statements to the beginning of the second block for each file type:

if (SzExtension(strDocument) == "doc")
{
objEditor = new ActiveXObject("Word.Application");
objEditor.Visible = true;
objEditor.Documents.Open(strDocument);
}
else if (SzExtension(strDocument) == "xls")
{
objEditor = new ActiveXObject("Excel.Application");
objEditor.Visible = true;
objEditor.Workbooks.Open(strDocument);
}
else if (SzExtension(strDocument) == "ppt")
{
objEditor = new ActiveXObject("PowerPoint.Application");
objEditor.Visible = true;
objEditor.Presentations.Open(strDocument);
}
else if (SzExtension(strDocument) == "vsd")
{
objEditor = new ActiveXObject("Visio.Application");
objEditor.Visible = true;
objEditor.Presentations.Open(strDocument);
}
else
{
objEditor = new ActiveXObject(varEditor + ".1");
window.onfocus = null;
if (SzExtension(strDocument) == "ppt" && varProgID == "")
varProgID = "PowerPoint.Slide";
if (!objEditor.EditDocument(strDocument, varProgID))
alert(L_EditDocumentRuntimeError_Text);
}
SetWindowRefreshOnFocus();
return;

The script will now check the file extension when the ‘Edit in …’ option is clicked and, if it matches one of the ‘if’ or ‘else if’ statements, open the associated application and load the file. For compatibility, the original code is retained in the final ‘else’ statement. Also, the SetWindowRefreshOnFocus() and return lines have been moved to the end of the function so they remain applicable to the entire function (if not relocated, the window will remain in a wait state after the ActiveX object has been invoked).

There are a couple of caveats to this solution:

1. Each file type must be explicitly declared in the ‘if…else if’ statements. This can be overcome by instead parsing the DOCICON.XML file; however, as noted above this method is a bit cumbersome and the XML settings are not comprehensive (many of the mappings call SharePoint.OpenDocuments instead of the original application, so a clunky series of substitutions must still be made to be effective; overall, this solution is less efficient than simply making the declarations in the code itself).

2. If the SPS Area/WSS site is not in the user’s Intranet zone in IE and the ‘Initialize and script ActiveX controls not marked as safe’ option is not set to ‘Enable’, the user will get a warning dialog each time they select the ‘Edit in …’ option. For organizations that make use of policy files and/or login scripts, these settings can be enabled globally via a policy file on login.

While this is not a substitute for upgrading all Office 2000/XP clients to Office 2003 (users on the older platforms still won’t have the Explorer View functionality or be able to upload multiple files), it will serve as an effective interim measure until the upgrade process can be completed. Afterwards, the script can be reverted back to its original state and the workaround code removed.