March 17, 2012 - 10:16, by Steven Van de Craen
Categories: General, Windows 8, Windows Server 2008 R2
A few days ago I tweeted about having moved to Windows 8 Consumer Preview as main Operating System. So far still really happy with it.
My previous OS was Windows Server 2008 R2 with Hyper-V for virtualizing my SharePoint development environments. I had tweaked Windows Server as much as possible to be more of a desktop OS than server OS, but the fact remained that it just hadn’t optimized audio and video drivers. Surely they’re adequate to perform basic tasks, but there still was a little bit mouse and audio stuttering when a YouTube started playing, let alone playing a recent game such as Modern Warfare 3 or Skyrim. For those I kept a Windows 7 dual boot environment around.
Hyper-V 3.0
The main driver to move to Windows 8 for me was to have Hyper-V. Mind you that it’s not a straightforward path to migrate your Windows Server 2008 R2 images. I tried the export and import feature; it complained about not being able to use Saved State but it kindly asked me if it could delete that, I said yes. The import went fine but still I could start up a snapshot due to some obscure error. Perhaps this is a beta issue and will be fixed in RTM.
I decided to make a copy of the entire VMDISK folder and then just create new Virtual Machines in Windows 8, linking to existing disks (.vhd and .avhd). Nothing new here but note that you can use the “Edit Disk” functionality to merge a snapshot disk with its parent disk.
So I now had “base” images of all my machines in Windows 8 and booted them up. The next thing you’ll probably do is install the new Hyper-V Integration Tools in each virtual machine. This will upgrade the HAL in the VM.
Hyper-V networking has changed in 3.0 as well, using network bridging to overcome some issues from the past. This new Network Adapter will be seen as a new NIC in the VM as well, so you’ll have to reconfigure any static IP’s you had before.
A final thing is Windows Activation. Since you’re using a new HAL in the virtual machines, Windows will need to reactivate.
After that you can shut down the machines and make a base snapshot to start each new project on.
Note: the general experience might improve in the RTM version, but if you’re using Hyper-V then you’re probably tech savvy enough to migrate the more difficult way
Metro
A lot has been said about the Metro UI already. In Windows 8 there are two UI modes: Metro and Desktop (as I call them). Metro is the thing for mobile devices, slates and is very slick and touch driven (even if you can still operate it with a mouse and keyboard). Desktop mode is what we all know from Windows 7 and before.
Applications come in two forms; either it’s a Metro app (downloaded through the App Store), or a Desktop app (every piece of Windows software that is known to man). You can have a split screen of two apps.
The Start menu has been removed in favor of the Metro Start Page.
A lot of the navigation now happens by moving the mouse to a screen corner
- Top Left will show the Metro Task Manager for app switching or dragging split screen
- Bottom Left (where the Start Menu used to be) jumps to the Start Page
- Top Right or Bottom Right will bring up the Settings Menu
Start Menu
I had the Windows 8 Developer Preview and there were some tools that allowed you to disable some Metro features so that you basically only had Desktop Mode (with Start Menu). It seems Microsoft is really pushing Metro and none of the tools to date allow this on the Consumer Preview.
I’m fine with using Metro since it’s a lot like my Windows Phone. I can get used to the Start Page by rearranging tiles, but in Desktop mode I do want my Start Menu back !!
ViStart to the rescue. Designed for Windows XP it renders the Vista or Win7 Start Menu with most functionalities you’d use it for. During some shutdowns it throws a buffer overrun or other error, but in general it works really great on Windows 8 and should Microsoft decide to permanently drop the Start Menu then this is your friend!
The road goes on
It’s been only a few days since I installed it. I’m very pleased with overall performing and hope it will remain stable. Should things go wrong then I have an image of my previous OS at hand.
March 2, 2012 - 08:28, by Steven Van de Craen
Categories: Advanced Computed Field, SharePoint 2010
Yesterday I updated the download and source code for the Advanced Computed Field at the Ventigrate Public Code Repository with an XSL stylesheet. This was needed to fix an issue with the field not rendering values when filtered through a Web Part Connection.
The Advanced Computed Field relies on CAML to have the most flexibility of formatting, since SharePoint 2010 introduces XSL based Fields I updated it with the CAMLRendering=”TRUE” flag. This seemed to work for everything except an issue reported by Federico Sanchez regarding Connected Web Parts.
Federico came with the solution to the problem by adding the XSL stylesheet (nothing else needed to be changed), so it really is a nice solution.
xml version="1.0" encoding="utf-8" ?> <xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema" xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http://schemas.microsoft.com/ASPNET/20" xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal"> <xsl:template match="FieldRef[@FieldType='AdvancedComputedField']" mode="Computed_body"> <xsl:param name="thisNode" select="."/> <xsl:value-of select="ddwrt:HtmlDecode($thisNode/@*[name()=current()/@Name])" disable-output-escaping="yes"/> xsl:template> xsl:stylesheet>
Solution upgrade
If you’re using the Advanced Computed Field in SharePoint 2010, it is advised to update the Solution Package (WSP) to the latest version (available in the download). It won’t break the existing use.
Download: link
March 1, 2012 - 16:31, by Steven Van de Craen
Categories: BIWUG, General, SharePoint 2010
Join SharePoint architects, developers, and other professionals on 28th April for the second Belgian ‘SharePoint Saturday’ event. SharePoint Saturday is an educational, informative & lively day filled with sessions from respected SharePoint professionals & MVPs, covering a wide variety of SharePoint-orientated topics. SharePoint Saturday is FREE, open to the public and is your local chance to immerse yourself in SharePoint!
SharePoint Saturday () is organised by BIWUG (), the Belux Information Worker User Group.
Extra details and registration information can be found here: http://bit.ly/spsbe2012.
See you there,
February 8, 2012 - 17:38, by Steven Van de Craen
Categories: SharePoint 2010, Sandbox Solutions, Ribbon, jQuery/JavaScript
A SharePoint 2010 Sandboxed Solution that adds a Ribbon Button that recycles all items in a Document Library with a single mouse click.
I' have created this miniproject more as an academic exercise in creating a Ribbon Button than for real business value. It can come in handy for development environments sometimes.
Installation and activation
Download from here (Ventigrate Codeplex Repository)
Upload the WSP (sandbox solution) to the Site Collection Solution Gallery and activate it
Activate the Site Collection Feature
Final note
Some lessons learned and things worth noting:
- Use a Module to deploy resource files to a folder or library like the Style Library (Sandbox cannot access the Layouts folder)
- The Module will overwrite the existing resource files with a newer version, but will not delete them
- Working with ECMAScript seems to have no effect on resource or resource quota
- Use InPrivate Browsing for testing Ribbon development, this avoids caching of Ribbon resources
-
CustomAction.ScriptSrc points to the Layouts folder when using relative URLs. Use ~SiteCollection if you want to reference a resource in the Site Collection
February 2, 2012 - 11:59, by Steven Van de Craen
Categories: SharePoint 2010, Taxonomy, Event Receivers, .NET
Issue
Today I was troubleshooting a customer farm where Managed Metadata would remain empty in SharePoint, even though it was filled in correctly in the document’s Document Information Panel.
Digging through the internal XML structures of the DOCX and also the Content Type Schema and Field XML, I couldn’t find a reasonable explanation.
The library was configured with multiple Content Types, but the issue occurred only on some of them. It appeared that for those Content Types, the Managed Metadata field was Optional, not Required.
I tried reproducing that configuration in a new document library but there everything kept working, so the issue had to be with the existing library.
Further analysis, comparison and reflection showed that the problematic library was missing some Taxonomy-related Event Receivers.
There appear to be four (4) Taxonomy Event Receivers:
-
TaxonomyItemSynchronousAddedEventReceiver (ItemAdding) and TaxonomyItemUpdatingEventReceiver (ItemUpdating) are added when a Managed Metadata field is added to the List
-
TaxonomyItemAddedAsyncEventReceiver (ItemAdded) and TaxonomyItemUpdatedEventReceiver (ItemUpdated) are added when “Metadata Publishing” is enabled in the List Settings
The problematic library at the customer was lacking the first set of Event Receivers, which are responsible for syncing the hidden field.
Fix
I’ve written a one-off script (Console App) that loops all lists with a Managed Metadata field on all sites in the site collection and ensures the Taxonomy event receivers. That code was taken directly from TaxonomyField.AddEventReceiverIfNotExists.
using System; using System.IO; using System.Text; using System.Windows.Forms; using Microsoft.SharePoint; using Microsoft.SharePoint.Taxonomy; class Taxonomy_Fix { public static StringBuilder sb = new StringBuilder(); public static string nl = "\r\n"; public static string url = "http://intranet"; public static void FIXALL() { using (SPSite site = new SPSite(url)) { foreach (SPWeb web in site.AllWebs) { FixTaxonomyReceiverOnWebLists(web); web.Close(); } } File.AppendAllText(String.Format("c:\\{0:HH_mm_ss}.txt", DateTime.Now), sb.ToString()); MessageBox.Show(sb.ToString()); } private static void FixTaxonomyReceiverOnWebLists(SPWeb web) { for (int i = 0; i < web.Lists.Count; i++) { SPList list = web.Lists[i]; if (HasTaxonomyField(list)) { sb.AppendFormat("{0}{1} has Taxonomy Field{2}", url, list.RootFolder.ServerRelativeUrl, nl); EnsureTaxonomyHandlers(list); } } } private static bool HasTaxonomyField(SPList list) { bool result = false; foreach (SPField field in list.Fields) { if (field is TaxonomyField) { result = true; break; } } return result; } private static void EnsureTaxonomyHandlers(SPList list) { AddEventReceiverIfNotExists(list.EventReceivers, SPEventReceiverType.ItemAdding, typeof(TaxonomyField).Assembly.FullName, "Microsoft.SharePoint.Taxonomy.TaxonomyItemEventReceiver", "TaxonomyItemSynchronousAddedEventReceiver", SPEventReceiverSynchronization.Synchronous); AddEventReceiverIfNotExists(list.EventReceivers, SPEventReceiverType.ItemUpdating, typeof(TaxonomyField).Assembly.FullName, "Microsoft.SharePoint.Taxonomy.TaxonomyItemEventReceiver", "TaxonomyItemUpdatingEventReceiver", SPEventReceiverSynchronization.Synchronous); } private static void AddEventReceiverIfNotExists(SPEventReceiverDefinitionCollection eventReceiverCollection, SPEventReceiverType type, string assembly, string className, string receiverName, SPEventReceiverSynchronization sync) { if (eventReceiverCollection == null) { throw new ArgumentNullException("eventReceiverCollection"); } if (string.IsNullOrEmpty(assembly)) { throw new ArgumentNullException("Valid assembly name required"); } foreach (SPEventReceiverDefinition erd in eventReceiverCollection) { if (erd.Assembly == assembly && className == erd.Class && type == erd.Type && erd.Synchronization == sync) { sb.AppendFormat("\t>> no action required{0}", nl); return; } } SPEventReceiverDefinition erd2 = eventReceiverCollection.Add(); erd2.Name = receiverName; erd2.Type = type; erd2.Assembly = assembly; erd2.Class = className; erd2.Synchronization = sync; erd2.Update(); sb.AppendFormat("\t>> Added TaxonomyEvent Receiver{0}", nl); } }
Disclaimer: not responsible for this code. Run at own risk. Feel free to adapt or improve as desired or required.
Conclusion
I can’t really explain why only some Content Types were affected. I’m guessing the Optional/Required setting of the Managed Metadata field is involved somehow, but I didn’t really confirm that through testing.
Also not sure why the Event Receivers were missing in the first place. It could be because some “questionable” actions happened during the setup of the site, but it could as well be a bug in SharePoint 2010 RTM or later.
January 26, 2012 - 13:09, by Steven Van de Craen
Categories: SOAP, SharePoint 2010
Today we were experimenting with SharePoint 2010 CSOM (Client Side Object Model) and we noticed strange errors such as HTTP ERROR 417 were returned. When browsing to Lists.asmx and Sites.asmx we got the following error:
The top XML element 'string' from namespace 'http://schemas.microsoft.com/sharepoint/soap/' references distinct types System.String and Microsoft.SharePoint.SoapServer.SoapXml.SoapXmlElement. Use XML attributes to specify another XML name or namespace for the element or types.
One of the MSDN Forums’ answers stated that you could use direct WSDL link (http://url/_vti_bin/sites.asmx?wsdl) and that would work, which it does in the browser but not for CSOM. And besides, I don’t like these kind of errors on one of my environments while other environments work fine.
Turned out someone had disabled HttpGet, HttpPost and HttpPostLocalhost protocols in the web.config of the ISAPI folder (maps to _vti_bin).
Uncomment those lines and your Web Services should be fine again.
January 5, 2012 - 11:22, by Steven Van de Craen
Categories: SharePoint 2010, Search
Posting this for personal reference:
SharePoint 2010 - Configuring Adobe PDF iFilter 9 for 64-bit platforms
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\14.0\Search\Setup\ContentIndexCommon\Filters\Extension\.pdf]
@=hex(7):7b,00,45,00,38,00,39,00,37,00,38,00,44,00,41,00,36,00,2d,00,30,00,34,\
00,37,00,46,00,2d,00,34,00,45,00,33,00,44,00,2d,00,39,00,43,00,37,00,38,00,\
2d,00,43,00,44,00,42,00,45,00,34,00,36,00,30,00,34,00,31,00,36,00,30,00,33,\
00,7d,00,00,00,00,00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\14.0\Search\Setup\Filters\.pdf]
"Extension"="pdf"
"FileTypeBucket"=dword:00000001
"MimeTypes"="application/pdf"
sps2010pdf.reg
January 3, 2012 - 07:20, by Steven Van de Craen
Categories: SharePoint 2007
You can configure the permission level of anonymous users to allow for viewing versions of documents and items, but no matter what you do, they get prompted for credentials.
The Version History page has the property “AllowAnonymousAccess” set to false. It is a virtual property in the Microsoft.SharePoint.ApplicationPages.UnsecuredLayoutsPageBase class that needs to be overridden in those layout pages that should be visible for anonymous users.
SharePoint 2007
The solution is an identical copy of the original Version History page of SharePoint 2007 but with the aforementioned property set to true.
The farm solution contains the page and a Site Collection Feature for activation which will add links to the page in the Toolbar and ECB menu for Document Libraries and Lists. You could hide or replace the link to the original page, but that isn’t straight-forward using CustomAction elements.
Installation and activation
Download from here (Ventigrate Codeplex Repository)
Deploy the WSP (farm solution) to the SharePoint Farm
STSADM -o addsolution -filename Ventigrate.Shared.AnonymousVersionHistory.wsp
STSADM -o deploysolution -name Ventigrate.Shared.AnonymousVersionHistory.wsp -allowgacdeployment -immediate
Activate the Site Collection Feature where you want this functionality
SharePoint 2010
SharePoint 2010 suffers from the same issue. You need to adapt the above solution to make it work for SharePoint 2010
- Copy the markup of the SharePoint 2010 Version History page (and add the property override)
- Adapt the CustomAction elements to add links to UI elements for SharePoint 2010 (and optional Dialog UI)
January 3, 2012 - 06:24, by Steven Van de Craen
Categories: SharePoint 2010, Excel Services, Office Web Applications
Recently a colleague wanted to display a with Excel Services rendered workbook inside a cross-domain iframe:
- Excel Services: http://intranet/_layouts/xlviewer.aspx?id=%2FShared%20Documents%2FBook1%2Exlsx&DefaultItemOpen=1
- Other domain web site with iframe: http://lux
But because Excel Services and Office Web Apps render a HTTP response header X-FRAME-OPTIONS: SAMEORIGIN this won’t work and you get “This content cannot be displayed in a frame”
Not used to seeing such a straight-forward error :)
I did a bit of investigating but couldn’t find an easy way to configure this through UI or Powershell, so I was left with the following options:
- Strip the header in a reverse proxy (between client and SharePoint server) like Apache or ForeFront
- Remove the header with development of a HttpModule
PermissiveXFrameHeader
I wrote up a quick HttpModule that can be activated by Web Application Feature and will remove the X-FRAME-OPTIONS header no questions asked.
You might want to adapt the code for additional checks on referrer, querystring, client, or similar for conditional removal of the header (see final note below).
Installation and activation
Download from here (Ventigrate Codeplex Repository)
Deploy the WSP (farm solution) to the SharePoint Farm
STSADM -o addsolution -filename Ventigrate.Shared.PermissiveXFrameHeader.wsp
STSADM -o deploysolution -name Ventigrate.Shared.PermissiveXFrameHeader.wsp -allowgacdeployment -immediate
Activate the Web Application Feature to the Web Application referred to in the iframe
Final note
The header was designed to protect against clickjacking. If you intend to use the above solution keep this in mind and plan for it accordingly.
December 27, 2011 - 10:43, by Steven Van de Craen
Categories: jQuery/JavaScript, SharePoint 2010
Here’s a small fix for which I didn’t have time to investigate more properly:
Issue
The User Profile Page of another user shows a link “Add as colleague” when that user isn’t already a colleague:
It seems however that the link behind “Add as colleague” directs to the Default AAM URL rather than the current URL you’re using.
Example:
Zone: Default |
http://internalserver
|
Zone: Intranet |
http://intranet
|
When browsing to the page using http://intranet the link will refer to http://internalserver. This is not the desired behaviour (think mixed authentication or extranet scenario’s).
Quick fix using jQuery
<script type="text/javascript" src="/my/Style Library/js/jquery-1.7.1.min.js"></script> <script type="text/javascript"> $(function() { var el = $('.ms-my-addcolleague'); if (el.attr('onclick') != undefined) { el.attr('onclick', el.attr('onclick').replace('http:\\u002f\\u002finternalserver:80', '')); } }); </script>
I’m referencing jQuery in the Style Library of the My Site Host, which you need to add or modify the link. I’ve hardcoded the internal URL (default zone public URL), might be better to look that up dynamically but as said this is a quick fix.
You can view the source of your own User Profile Page to find the internal URL for your environment.
You can add this in a Content Editor Web Part to the User Profile page and it should work just fine making the link relative.
Applies to
I’m seeing this issue in a SharePoint 2010 + Service Pack 1 + August 2011 Cumulative Update (14.0.6109.5002). Might be fixed in a later CU or SP.
Next >>