Thursday, September 28, 2006

MOSS2007 Beta2TR Trials and Tribulations

Today was my lucky day to install a new MOSS2007 Beta2TR virtual machine from scratch. Oh, joy. Has anyone anywhere at any time so far managed to do this without uttering a single curse of frustration? I seriously doubt it. So here are the lessons I learned on today's adventure to MOSS-land:

  • If you plan on using a unique admin account (other than 'Administrator') for database access and application pools (such as 'SPSAdministrator') be sure that you are logged in as that account throughout the entire installation, upgrade and configuration process. Otherwise, you'll get all kinds of strange errors during installation and configuration. Oh, and don't forget to add that account to SQL before starting the process with full admin rights (or at least 'dbcreator' and 'securityadmin').
  • The slipstream process ain't all it's cracked up to be. I tried three times to slipstream the install, which worked through the installation process (assuming you sorted out the somewhat misleading upgrade instructions), but it failed to create the central admin application upon configuration all three times. What is not quite so obvious is that you need both MOSS and WSS TR's to do the update - just MOSS won't work. This is confusing as you don't need have to install WSS before MOSS the first time around. Just remember to a) copy all the files from the Beta 2 cd image into a local directory, then b) extract the update files for MOSS B2TR and WSS B2TR into that directory's \Update folder.
  • Central Administration will not work from a clean slipstream install (at least not for me it wouldn't and I was working from a fresh Win2k3 install). The configuration wizard runs and the central admin app is created but you can't access it - just an annoying 404 error every time. You must first install Beta 2, then run the configuration wizard (which creates the central admin app correctly) THEN run the WSS B2TR followed by the MOSS B2TR.

Finally, after much gnashing of teeth and flailing of limbs, I have a clean MOSS2007 image to work from. Now it's on to custom site definitions which, based on the install experience, promise to be a all-out man vs. machine war. Stay tuned for reports from the battlefield.

Wednesday, September 13, 2006

Business Portals vs. Line of Business Applications

A primary focus of our business is building custom SharePoint-based applications for our clients.  Naturally, being SharePoint gearheads, we believe that everything under the sun can somehow be made to work in SharePoint (and we're not often wrong) but we run into a great deal of confusion when presenting clients with various customization options.  One of the most difficult ideas to grasp is the separation between a business portal (BP) and a line of business application (LOB).  Which is which and where/how do you use each one?

To begin with, a business portal is defined as any application or set of applications (and the default SharePoint experience is really a set of integrated applications) that share a common brand or visual presentation and is usually delivered as a packaged installation (as opposed to a fixed location extranet or intranet) to customers, partners, or other constituents.  An LOB, on the other hand, is a distinct application that is deployed within an existing inter/intra/extranet implementation. 

On a more technical level, a customized set of WSS site definitions, web parts, and templates that together combine to form a branded collaboration application for, say, the real estate market, would be a business portal.  On the other hand, a set of web parts, lists, roll-ups, controls, or other programmatic elements, delivered individually or packaged together, and installed within an existing company intranet for tracking sales and orders, would be an line of business application. 

Just to muddy up the waters a bit, it should be pointed out that the two are not mutually exclusive - an LOB can be deployed within a business portal and a business portal can be created to serve internal as opposed to external customers (an IT help desk solution for a company with multiple, independent locations comes to mind).  Many organizations start creating LOB's soon after they deploy a new portal solution without realizing that's what they are doing, as they roll out custom web parts that roll-up, consolidate, or provide access to various sources of company data.

Business portals can be a very powerful tool for organizations that need to deliver rich web-enabled applications on a limited budget.  WSS provides a comprehensive, flexible, and customizable (and let's not forget FREE!) platform for creating dynamic web applications.  The best thing about BP's is that the framework is already in place - navigation, data storage (via lists), security, browser-based site management - so developers can focus on customizing and extending the framework without reinventing the wheel at every turn.  With the introduction of SharePoint 2007 and the improved customization options, along with built-in workflow and item-level security, forms-based authentication, and the business data catalog, expect a dramatic upsurge in the number of business portals being created, many of which will be offered as stand-alone applications (hint: expect to see several from us before the end of the year).      

Thursday, August 31, 2006

eGroup List Viewer Web Part

Whenever I begin a new portal design engagement, one of the most difficult concepts to communicate to the client's design/architecture group is 'Content-Driven Design'. The theory is simple - create an architecture and taxonomy around the information that is most important within your organization. What makes it difficult is the almost Pavlovian instinct to organize content based on company structure - breaking away from the org chart sometimes requires superhuman effort.

Fortunately, once the initial shock wears off, the light goes on and heads start nodding around the conference table. It doesn't take long for people who couldn't pronounce 'taxonomy' the week before to suddenly become content design experts. This only makes sense, as they already have a picture in their minds of how their company's information should be organized, they just need a push in the right direction to translate those thoughts into a good architectural design.

One of the most critical elements to a good content-driven architecture is the concept of "Author Once, Publish Everywhere". In this model, information is created and managed in the most granular context applicable to it's function but published in the context where it is most often consumed. For example, an HR policy would most likely be created and stored in an HR team site, somewhere within the overall departmental hierarchy. This allows team members to collaborate effectively on documents that pertain to their job function while permitting the greatest degree of security and oversight. Users, on the other hand, shouldn't be poking around in the HR team site, they should be browsing a portal area that is generally classified to contain that type of information (such as 'Employee Resources' or 'New Hire Information').

Unfortunately, this design methodology reveals an inherent weakness in SharePoint - the inability to distribute list content throughout the portal. In the SharePoint structure, lists can only be viewed in the context in which they were created (in our example, the HR documents could only be viewed within the HR team site). SharePoint does not ship with out-of-the-box capabilities to create list items in one area/site and view them in another.

To meet this requirement, we created a web part which allows list content in any area or site to be viewed in another area or site by users with sufficient permissions to view items in the source list (they must at least be a 'Reader'). We've used it in numerous client engagements and it is a critical component in our Content-Driven Design methodology. Just add the web part to a page, give it the portal/site url, list name, and view, set the display options (toolbars and column titles), and voila - list content for everyone, everywhere!

The web part can be downloaded here. The zip file contains a ReadMe document with instructions on installing the CAB file (in case you haven't done it before) along with information on deploying it to a portal/site page and configuring the various options.

As always, post any questions, comments, or suggestions to this post.

Enjoy!

kick it on SharePointKicks.com

Friday, August 18, 2006

eGroup SharePoint Utilities

I am a big proponent of leveraging SharePoint to deliver enterprise line-of-business applications (LOB's). Much of the custom development we do at The eGroup involves the use of SharePoint lists as data repositories for dashboards, workflows, roll-ups and, of course, LOB's. Working extensively with SharePoint lists brings introduces its own set of challenges - coding against the web services, creating and maintaining a large number of custom views, managing security and migration of list structure/content from development to staging and production.

In the course of developing these applications we have created a set of tools to aid us in our efforts. To save our fellow SharePoint developers some of the headaches we've encountered, and to encourage other developers to contribute their time-saving apps, we'll be releasing various applications and utilities from our toolkit in the coming weeks and months. The first utility, the SharePoint List XML Viewer, received an enthusiastic response and generated a fair number of downloads. I hope it is serving everyone well and we will continue to improve it as we receive feedback from the SharePoint community.

The second tool to be released, the SharePoint List Creator, is a companion utility to the List XML Viewer. Using the XML output gathered from the XML Viewer, it provides developers with the ability to define custom lists in XML and easily deploy them to multiple sites/areas. This can be quite a time saver when you have a large number of heavily customized lists that must be moved to different environments, especially when each portal or site collection exists in disparate server farms and/or separate domains.

To use the SharePoint List Creator you'll need good working knowledge of XML and some CAML experience. Creating a new list requires a source XML file that contains the properties, fields, and views that will comprise the list. A sample file, DocumentLibrary.xml, has been provided in the \XML directory to give you a basic template to work from (remember to store all your custom list templates in this same directory). If you haven't done much CAML or manual list creation, a good first step would be to create a custom list in the SharePoint GUI then view the list structure with the List XML Viewer. Compare the output to the sample xml template and it won't take long to figure out how to create just about any list type from scratch. We'll release more samples in the future to aid new developers and in response to comments/requests.

To use the SharePoint List Creator, first download the eGroup SharePoint Utilities Windows Installer package from our web site. This package contains both the SharePoint List Creator and the SharePoint List XML Viewer. Next, install the MSI on your development machine and launch it from the program menu shortcut. Provide the site/area URL, list name, type, source XML document, and authentication credentials, and submit the changes. The tabs in the utility will display the source XML, new list XML being submitted, the results from the list updates, and the results from the view modifications. You'll also find any errors encountered under the appropriate tab (i.e. if view creation fails, check the "View Results" tab).

We'll update the Utilities suite with new apps as we convert or create them (many are ASP.NET applications that require migration to Windows Forms prior to deployment). As always, please post your questions, suggestions, feature requests, gripes and complaints as comments to the post. Feedback is the only method we have to gauge the community reaction to our efforts. I hope you find the tools useful. Enjoy!

kick it on SharePointKicks.com

Sunday, August 06, 2006

New Version of SharePoint XML List Viewer

I received some good feedback on the XML List Viewer utility and have posted a new version with the following modifications:

* Clear text entries hidden in password field
* XML displayed in structured view (similar to IE functionality)
* XML can be saved to local file (Right-click within XML field, choose 'Save')
* XML can be printed (Right-click within XML field, choose 'Print')
* XML can be searched for a specified string (right-click, 'Search')

Download the new version (1.1) here.

Please post any additional feature suggestions as comments to this post.

Enjoy!

UPDATE: Downloads from the earlier post had problems with the .NET 1.0 version of the tree view DLL. I have posted an updated version (use the same link above) that includes a recompiled .NET 1.1 version XmlTreeView source code within the executable (thanks to Thomas Siepe for making the source available on The Code Project).

Thursday, August 03, 2006

SharePoint List XML Viewer Utility

Many of us are rejoicing over the new web publishing features in MOSS2007 and the ability to create corporate web sites using SharePoint. Unfortunately, many enterprises are not planning to upgrade to 2007 for quite some time, and those that use SharePoint extensively are looking for ways to derive additional value from their portal investment. One of the best ways to do this is to use SharePoint 2003 as a basic content management system for a public web site (at least until a full 2007 migration can be completed).

I just finished a project where an existing - and very expensive - CMS application (I won't name names but it's not MCMS) is being phased out in favor of using SharePoint lists as the primary method for managing content on a standard ASP/ASP.NET public web site. When you think about, this makes perfect sense - SharePoint provides a form-based web interface for handling content submissions, security is built into the platform, content approvals and basic workflow are easy to implement, and every list in a portal/site is accessible via web services (for more information on using SharePoint as part of a basic CMS application, email me directly).

While working on this project I discovered that working with the SharePoint web services is no picnic; not only do you have to know all their little quirks (like the viewName argument requiring a GUID instead of the display name of the view) but you also have to make allowances in your code for all the funky things SharePoint does behind the scenes with the list XML. For example, when you name a field 'Field1', the list details show the field as just that - Field1 - but when you try to retrieve the list data using the Lists web service, you must refer to the field as 'ows_Field1'. And then there's the ever-popular trick of replacing all spaces in field names with '_x0020_'. Naturally, there are no tools in SharePoint that allow you to retrieve this information, invaluable though it might be. It's enough to drive you mad.

To maintain my sanity and bring some order to web service programming, I created a small utility to retrieve the XML for any list via the SharePoint web services. The SharePoint List XML Viewer is a small Windows app that programmers can use to retrieve the XML output for any list or list items (including any default or custom views) to aid them in building web service applications. You can download it here. Just unzip the file and run the executable. Give it the site/area url, list name, and view name, supply the necessary login credentials, pick which type of XML you want (list data or list items) and - voila - instant XML that can be cut-and-pasted into your favorite text editor.

The SharePoint List XML Viewer Utility isn't anything fancy - it's just a basic utility for developers - but it saved me countless hours programming against SharePoint's web services and I hope it helps you, too. Enjoy!

(Post comments to this post if you have any issues installing and using the tool)

BTW, I recommend using the application along with the CAML Query Builder and Execution Tool from the good folks at U2U. Sooner or later you'll need to execute a query in a web service call and the CAML Builder is the best thing going.

kick it on SharePointKicks.com

Friday, June 23, 2006

Extreme SharePoint Design 2007: Introduction to Customizing Default Pages

This is the first post in a new series covering advanced design in Microsoft Office SharePoint Server 2007 (MOSS2007). As with previous Extreme SharePoint Design posts, much of the material will be undocumented, some posts will walk the line on supportability, and some will downright obliterate the line just to show what can be done; therefore, all techniques should be tried first in a test environment and a good backup is always a necessity. Now on to the good stuff!

MOSS2007 takes a radically different approach to rendering pages, due mostly to the integration of Content Management Server features into the product and an ongoing effort on Microsoft’s part to migrate towards a more structured, data-bound architecture (i.e. CAML and XML). Much of what we learned customizing SPS2003 will still be applicable but a great deal of the behind the scenes machinery has changed. A good place to begin learning how to modify MOSS2007 to meet your needs is with default page customizations; changing the structure, appearance, and layout of the default site welcome pages.

Since MOSS2007 is built on ASP.NET 2.0, a solid understanding of master pages is required in order to grasp how site pages are constructed and rendered. A master page (any ASPX page with a .master extension) is nothing more than a template with placeholders for content, much like a regular ASP.NET page that invokes user controls to render content. In .NET 2.0 syntax, these placeholders are implemented using the <ASP:ContentPlaceHolder> tag. Placeholders can be nested, so that a top-level placeholder may have multiple levels of child placeholders, much like a parent DIV can have many nested child DIV’s.

The master page by itself usually contains very little actual content other than headers and navigation – it’s just a framework for one or more layout pages that comprise the body of the page. In MOSS2007, the master page DEFAULT.MASTER, located in WEB SERVER EXTENSIONS\12\TEMPLATE\GLOBAL, defines the standard top header and left navigation layout found throughout the basic site definitions. Unlike SPS2003, where the default page in each site definition contained all the code necessary to render the page, the new site definitions, located in 12\TEMPLATE\SITETEMPLATES, have a DEFAULT.ASPX page that references the master page but contains no actual content. Instead, the default page is built at runtime when the site is created by combining MASTER.DEFAULT with the layout page referenced in the PublishingPageLayout property of the Default.aspx File node of the Modules configuration in ONET.XML (~SiteCollection/_catalogs/masterpage/defaultlayout.aspx for the SPS site definition, which corresponds to 12\TEMPLATE\FEATURES\PORTALLAYOUTS\DEFAULTLAYOUT.ASPX in the server file structure). The combined file is then stored in the Pages list on the top-level site.

DEFAULT.ASPX = MASTER.DEFAULT + DEFAULTLAYOUT.ASPX

When you edit the default page using SharePoint Designer you are actually editing the combined code from two pages – the master page and the layout page. Fortunately, because the default page is stored in a list, the whole ghosting/unghosting issue no longer applies (hooray for that!); however, there is one major drawback – since the page doesn’t actually exist until the site is created, editing it only applies to the current site instance – new sites or subsites based on the same definition will have to edited manually each time they are created. To automate this process, the site definition must be modified in a similar manner to the methods used in SPS2003 but using the new master page methodology. Doing so requires making changes not just to a single default page but both the master and layout pages (we’ll cover creating new site definitions from scratch in a subsequent post).

The layout page works with the default page by specifying what content is to be placed in the placeholder zones using the <ASP:Content> tag and referencing the placeholder id. The page handler process then assigns the content in the layout page, which consists of the HTML markup we are used to seeing in SharePoint pages (server controls, web part zones, etc.), to the proper zone in the default page. The following illustration is a wireframe model of a combined DEFAULT.ASPX page with all the major placeholders, server controls, custom tags, content areas and publishing/web part zones placed in their proper context (click on the image to view it full size):


Blue areas in the model indicate placeholders, red is for server/user controls, purple represents new ASP-specific controls (in this case the breadcrumb navigation menu), green indicates the new PublishingWebControls objects, and grey is the standard web part zones. The yellow headers indicate the relationship between the default and layout pages. The final rendered page looks like this:


As you can see from the wireframe model, the page layout is not all that different from SPS2003, except that content is now separated from navigation by using two different file types. The beauty of this model is that changes to DEFAULT.MASTER are global; no more cutting and pasting code modifications into multiple site definitions. Likewise, the DEFAULTLAYOUT.ASPX page is also universal, making changes much easier to implement. If, for example, we wished to change the basic layout of the web part zones in the body of the page, we can modify the markup in DEFAULTLAYOUT.ASPX without touching the headers and navigation contained in the master page. We can also add content to the master page by using <ASP:Content> tags and specifying the placeholder with the ContentPlaceHolderId setting without actually modifying the master page itself.

In SPS2003 the customization process was cumbersome and inefficient; with the new master page model, Microsoft has given us far greater flexibility in customizing SharePoint sites to meet each organization’s unique requirements. In subsequent posts we will explore in greater depth the new MOSS2007 architecture, including the new list file structure, the long-overdue changes to the administration pages, and how to create new site definitions from scratch.

Happy SharePointing!


kick it on SharePointKicks.com Eric Shupps Eric Alan Shupps eshupps @eshupps SharePoint Cowboy BinaryWave SmartTrack

Wednesday, June 07, 2006

Extreme SharePoint Design: Using the AlternateHeader Property in WSS

I’ve done a number of customizations to administration pages (.aspx files located in the \LAYOUTS\1033 directory) by directly modifying the pages themselves. This is a cumbersome process, involving a lot of HTML search-and-replace operations. I felt it was time to use a more flexible approach so I attempted to create a more robust solution that works in both SPS and WSS. The first challenge to overcome was the fact that pages in a WSS context don’t inherit the AlternateHeader property from the Site Definition ONET.XML file. In the portal definitions, the following setting points the administration pages to a file called ‘PortalHeader.aspx’ and, if the file is not empty, renders the header contained therein:

< title="Team Web Site" listdir="Lists" ows="Microsoft SharePoint" alternateheader="PortalHeader.aspx" disablewebdesignfeatures="wdfbackup; wdfrestore; wdfpackageimport; wdfpackageexport; wdfthemeweb; wdfthemepage; wdfnavigationbars; wdfnavigationview; wdfpublishview; wdfpublishselectedfile; wdfNewSubSite">

This setting does not exist in the STS definition so it must be added (note that this will have no effect on existing WSS sites, only new ones created after the ONET.XML file has been modified). Unfortunately, the default PortalHeader.aspx file contains a number of < SPSWC: > control references which are portal-specific and will not render in a WSS context; simply adding this setting will not solve the problem. So the first step is to edit the ONET.XML file in TEMPLATE\1033\STS\XML to include the AlternateHeader setting and point it to a new header file, as follows:

Original code:

< title="Team Web Site" listdir="Lists" ows="Microsoft SharePoint">

Replacement code:

< title="Team Web Site" listdir="Lists" ows="Microsoft SharePoint" alternateheader="STSHeader.aspx">

Next, the new header file must be created (STSHeader.aspx in this example). This file must contain the proper WSS-context registrations to enable code execution (if necessary) and the content must be devoid of any portal-specific control references. Here is a sample STSHeader.aspx file:

< % @ Page language="C#" % >
< % @ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" % >
< % @ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" % >
< % @ Import Namespace="Microsoft.SharePoint" % >
< % @ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=11.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" % >

< link rel="'stylesheet'" type="'text/css'" href="'/_layouts/1033/styles/custom.css'">
< table width="100%" cellpadding="0" cellspacing="0" border="0">
< tr >
< td width="100%">
< div class="spsHeader" >
< !-- Insert Header HTML Here -- >
< % Execute Some ASP.NET Code Here % >
< /div >
< /td >
< /tr >
< /table >

After modifying the ONET.XML file and creating the new header file, copy ONET.XML to its original location and place the new header file in the \LAYOUTS\1033 directory. Perform and IISRESET on the server and create a new WSS site. Next select ‘Documents and Lists’ or ‘Create’ from the menu to see your new header code in action. If you plan to utilize custom server controls within the header file be sure to add the necessary registrations to the top of the page prior to deployment.

Tuesday, June 06, 2006

Ajax/Atlas in SharePoint?

A colleague of mine is trying to get Ajax/Atlas assemblies working in SharePoint. All is good if he hard-codes the functionality but the SharePoint safe mode parser is kicking the code out anytime he tries to use the precompiled assemblies. Anyone have experience with this? Post a comment and throw a fellow code monkey a banana or two!

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.