As I wrote in January "WSS 3.0, SharePoint 2007 and Project Server SP1 support ends soon". But today I discovered Microsoft has extended the support for installations of Windows SharePoint Services 3.0 SP1, Microsoft Office SharePoint Server 2007 SP1 and Project Server 2007 SP1.
On the Microsoft Lifecycle pages for "Windows SharePoint Services 3.0 Service Pack 1" and "2007 Microsoft Office Servers Service Pack 1" the new retirement date is set for July 13th, 2010.
The Microsoft Surface is a Windows Vista computer running the Microsoft Surface Shell. This shell is by default localized for US English. It’s possible to localize for other locales, but there is no configuration screen to set the desired localization.
This post will summarize the different steps to localize the Surface shell.
Microsoft Surface Device vs. Microsoft Surface Simulator
The settings work for both the Microsoft Surface device and the Surface Simulator.
Note for x64 machines (Running the SDK)
If you’re running the Surface Simulator on a x64 machine (see my post about "Installing the Microsoft Surface SDK on Windows 7 x64") the registry entries are slightly different.
For x86:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Surface\v1.0
For x64:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Surface\v1.0
All my examples in this post will use the x86 path.
Setting the Surface Shell interface language
With service pack 1 the Shell now supports 10 UI languages.
| Language | UILanguageName value |
|---|---|
| Danish | da-DK |
| Dutch | nl-NL |
| English (United States) | en-US |
| French | fr-FR |
| German | de-DE |
| Italian | it-IT |
| Korean | ko-KR |
| Norwegian (Bokmål) | nb-NO |
| Spanish | es-ES |
| Swedish | sv-SE |
To set the required language you need to edit the registry.
Look for the following key
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Surface\v1.0\InternationalSupport
Change the UILanguageName value into the desired language name you find in the table. For example to set the language to Dutch you enter "nl-NL".
Restart the shell
The modified registry entry to localize the Surface Shell language.
Close button with caption "Close everything" in English (default).
Close button with caption "Alles sluiten" in Dutch (localized).
Setting the Surface Keyboard mapping
There are 19 supported keyboard mappings.
| Keyboard layout | InputLanguageID value |
|---|---|
| Belgian (Comma) | 0x1080c |
| Belgian French | 0x80c |
| Canadian French | 0×1009 |
| Canadian Multilingual Standard | 0×11009 |
| Danish | 0×406 |
| French | 0x40c |
| German | 0×407 |
| Italian | 0×410 |
| Korean | 0×412 |
| Latin American | 0x80a |
| Norwegian | 0×414 |
| Spanish | 0x40a |
| Swedish | 0x41d |
| Swiss French | 0x100c |
| Swiss German | 0×807 |
| United Kingdom | 0×809 |
| United Kingdom Extended | 0×452 |
| US English | 0×409 |
| US-International | 0×20409 |
To set the desired keyboard mapping you need to edit the registry.
Look for the following key
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Surface\v1.0\InternationalSupport
Change the InputLanguageID value into the desired keyboard mapping you find in the table. For example to set the shell to Korean you enter "0×412" (Hexadecimal).
Restart the shell
The modified registry entry to localize the Surface Keyboard mapping.
Surface Keyboard with US English mapping (default).
Surface Keyboard with Korean mapping (localized).
Setting the Surface Date and Number formatting
For date and number formatting you can use all locales supported by the .NET Framework. The complete list can be found on the Language Identifier Constants and Strings MSDN page.
Just combine the primary language, for example: Dutch (nl), with the sublanguage, for example Netherlands (NL): nl-NL.
To set the desired date and number formatting you need to edit the registry.
Look for the following key
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Surface\v1.0\InternationalSupport
Change the LocaleName value into the desired formatting locale. For example to set the formatting to Dutch you enter "nl-NL".
Restart the shell
The modified registry entry to localize the date and number formatting.
Date formatting in US English (default).
Date formatting in Dutch (localized).
If you want to develop for the Microsoft Surface you need a Surface device. But using the device to develop is not always practical, specially when there are more developers than Surface devices. The solution for this is to install the Surface SDK Workstation Edition on your local development machine. This post will address some limitations you have to work around.
The Microsoft Surface SDK
The Microsoft Surface SDK was released to attendees of the PDC in 2008, where I was one of the lucky few. You can still view the "Developing for Microsoft Surface" session on Channel 9.
With the PDC 2009 the Microsoft Surface SDK 1.0 SP1 Workstation Edition was publically released.
Prerequisites
Before you can install the Surface SDK there are some prerequisites:
- Windows Vista (not Starter Edition) x86
- Microsoft XNA Framework Redistributable 2.0
- Microsoft Visual C# 2008 Express Edition or Microsoft Visual Studio 2008
When you’re running Vista x86
Assuming you’re not running Windows Vista Starter Edition you can install the Surface SDK without problems and can start developing immediatly!
When you’re not running Vista or x86
Well let’s face it, Windows Vista is old and gone, and everybody is running Windows 7 nowadays. So does this mean no more Surface development?
Lucky enough Brian Peek wrote a great blog post about this and I will summarize it here.
Naturally this makes the installation not supported by Microsoft.
Extracting the installer
There are two installers on the web available at the moment. An executable if you download the SDK from the partner site and a MSI if you download the SDK from the public Microsoft download site.
For the MSI:
msiexec /a SurfaceSDKWE.msi /qb TARGETDIR=c:\surface
For the executable:
"Microsoft Surface SDK 1.0 SP1, Workstation Edition.exe" /extract c:\surface
Patching the installer
Get the Orca tool from the Windows SDK, or if you don’t want to download 4GB for a tool not bigger than 2MB, try a less supported site.
Open the extracted SurfaceSDKWE.msi file with Orca.
Select the table "LaunchCondition"
Select the row with "Installed OR NOT VersionNT64" and choose "Drop row"
Save & Close Orca
Patching the Custom Actions
This is only needed on a x64 machine.
Get the CorFlags tool from the Windows SDK, or if you still don’t want to download 4GB, try an even lesser supported site.
Open a command prompt with elevated privileges (Run as administrator).
Go to the location of the extracted installer
cd "Microsoft Surface\v1.0"
CorFlags setupcustomaction.exe /32BIT+ /Force /nologo
Ignore the warning with the code CF011 about strong named signing.
Installing the SDK
This is pretty straightforward.
If you are running on a x86 system you can start developing!
Patching the executables
This is only needed on a x64 machine.
To make sure the Surface SDK executables are using the x86 CLR you have to patch them all.
cd "C:\Program Files (x86)\Microsoft SDKs\Surface\v1.0\Tools\GenTag"
for %i in (*.exe) do CorFlags %i /32BIT+ /Force /nologo /UpgradeCLRHeader
cd "C:\Program Files (x86)\Microsoft SDKs\Surface\v1.0\Tools\Simulator"
for %i in (*.exe) do CorFlags %i /32BIT+ /Force /nologo /UpgradeCLRHeader
cd "C:\Program Files (x86)\Microsoft SDKs\Surface\v1.0\Tools\SurfaceStress"
for %i in (*.exe) do CorFlags %i /32BIT+ /Force /nologo
cd "C:\Program Files (x86)\Microsoft Surface\v1.0"
for %i in (*.exe) do CorFlags %i /32BIT+ /Force /nologo
Patching the Sample Applications
This is only needed on a x64 machine.
Modify all projects files (*.csproj) and change the build type from "Any CPU" to x86.
For example, add the following to the appropriate PropertyGroup tags:
<PlatformTarget>x86</PlatformTarget>
Working on a Project Server project we discovered it’s quite easy to get issues with data integrity when users start retracting and deleting timesheets. After discussing the issue with Microsoft they gave us a workaround which solves our problem.
The problem
After a user has submitted a timesheet and the timesheet manager approves this timesheet as well the data is exported to an external system for invoicing.
The user however still is able to retract the timesheet, modify it and resubmit. It’s even possible to delete the timesheet.
Our first thought was to close the period of the submitted timesheets. But this only works partially. The user can’t modify the timesheet anymore, but is still able to retract and delete it. Not a very solid solution.
The cause
After discussing the issue with Microsoft we got this reaction:
Period close is designed to block new entries not changes which include deletions.
So this is pretty much "by design".
The solution
Lucky enough for us the answer of Microsoft didn’t stop there:
There is a Flag field in the PSI dataset that is called TS_IS_PROCESSED.
This can be set by a custom event or script when the period is closed for timesheets within the period or as originally designed, when the timesheet has been exported to a third party system for processing.
In 2007, we are looking at the data from a position where the system of record can modify the data and to help customers determine when Project Server is no longer the system of record, we are leaving it up to the customer to check that flag.
After the flag is set to true then no action can be performed on the timesheet except by duly authorized system administrators for adjustments theoretically coming from the third party system.
I already knew about the TS_IS_PROCESSED property as it is described by the Project Server SDK. But the description there only states:
Indicates whether the timesheet is finalized and should not be changed.
When TS_IS_PROCESSED is true, the timesheet cannot be recalled, changed, or deleted.
The, important, missing peace of information is that this field is supposed to be altered by custom code instead of project server itself.
The past couple of weeks I’m working with Silverlight controls embedded in SharePoint 2007.
For one of the controls I need to retrieve the data using the Search Query Web Service.
I was using the following code:
private void Page_Loaded(object sender, RoutedEventArgs e) { var endpoint = new EndpointAddress(GetParam("SharePointWeb") + "/_vti_bin/search.asmx"); var binding = new BasicHttpBinding(BasicHttpSecurityMode.None) { Name = "QueryServiceSoap", MaxReceivedMessageSize = 2147483647, MaxBufferSize = 2147483647 }; var client = new QueryServiceSoapClient(binding, endpoint); client.QueryExCompleted += this.ClientQueryExCompleted; client.QueryExAsync(GetParam("Query")); }
This was working perfectly in the development environment. But when deploying the control to the production environment it didn’t work.
After some digging I found that the control did work, but only when the page was visited over an HTTP connection. As everybody accesses the page over an HTTPS connection I was pointed in the direction of the connection between the control and the web service.
As can be seen in the code the WCF client is used and I remembered that the binding security mode is different if you want to work with HTTPS. So I changed the BasicHttpSecurityMode from None to Transport.
-var binding = new BasicHttpBinding(BasicHttpSecurityMode.None) +var binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport)
After deploying the control again it worked nicely over the HTTPS connection, so I know what the source of my problem is. But naturally I want a generic solution so the configuration of the access mapping is not influencing the functioning of the control.
The question is how to detect if the control is hosted on a page over an HTTP or HTTPS connection. This can be found in the SilverlightHost.Source property which can be compared against the Uri.UriSchemeHttp field or the Uri.UriSchemeHttps Field.
As a result this is my final code:
private void Page_Loaded(object sender, RoutedEventArgs e) { var basicHttpSecurityMode = (Application.Current.Host.Source.Scheme == Uri.UriSchemeHttp) ? BasicHttpSecurityMode.None : BasicHttpSecurityMode.Transport; var endPoint = new EndpointAddress(GetParam("SharePointWeb") + "/_vti_bin/search.asmx"); var binding = new BasicHttpBinding(basicHttpSecurityMode) { Name = "QueryServiceSoap", MaxReceivedMessageSize = 2147483647, MaxBufferSize = 2147483647 }; var client = new QueryServiceSoapClient(binding, endPoint); client.QueryExCompleted += this.ClientQueryExCompleted; client.QueryExAsync(GetParam("Query")); }
Works like a charm.
The problem
With the introduction of the August Cumulative Update for SharePoint 2007 (KB973399) we encountered "System.NullReferenceException: Object reference not set to an instance of an object." on all pages inheriting from MySitePublicWebPartPage.
As can be seen in the stack trace the error occurs from a call by the ProfilePropertyImage control which is on the page by default.
The cause
This call was not present in the control prior to the august update, so let’s take a look at the description of the update (KB973409).
A Shared Services Provider administrator edits the About me property or the Picture property to make the property display "Only me." However, these properties continue to be visible when the profile owner sets their As Seen By option to "Everyone," "My Colleagues," "My Workgroup" or "My Manager" on their own Person.aspx page.
So this explains why the control was changed, it now looks if the image should be rendered for the current visitor of the page.
The reason
We already know the problem starts inside the ProfilePropertyImage which is calling the MySitePublicWebPartPage.GetEffectivePrivacy method. This method reads the value of the MySitePublicWebPartPage.PrivacySelected property. Inside the getter of the property the following code is used:
object obj2 = this.ViewState["__PrivacySelected__"]; return (Privacy) obj2;
As we all know SharePoint’s code is never about defensive programming and so is the case here if there is no viewstate property available, it will return a null. And of course there is no check anywhere for that.
But this code works for the default person.aspx page, so the setter for this property has to be called somewhere. Analysis of the code shows only the AsSeenBy class ever calls the setter. As this control is on the person.aspx page by default the property is set and that page works fine. As we don’t have this control on our page we get a NullReferenceException.
The solution
If you’re bound to the August release the solution is simple: add the AsSeenBy control to your page.
But what if you don’t want to have the control on your page? We get lucky, because if you don’t make it visible it will still work, so add:
<SPSWC:AsSeenBy runat="server" id="ddlAsSeenBy" SelectionMode="Single" autopostback="True" Visible="False" />
If you’re not bound to the August upgrade you can upgrade to the October Cumulative Update or newer. Microsoft has fixed the issue in those versions.
Update March 24th, 2010: Microsoft extends support for WSS 3.0, SharePoint 2007 and Project Server SP1
Stefan Goßner reminds us of the fact that support for WSS 3.0 SP1, SharePoint 2007 SP1 and Project Server SP1 will soon end.
Support ends when the next service pack is out for over a year. And SP2 was released April 28th 2009 so SP1 won’t be supported from April 29th 2010, so roughly in 3 months.
Be sure to test & deploy your upgrade soon!
I was having trouble with the clock in my Linux Hyper-V VM’s.The time was constantly drifting forward. Using NTP only slowed the drift a bit down but often NTP gave up after several days.
I tried a lot of NTP configurations, but basically the local clock was just unreliable. Even using rdate every 10 minutes was already showing backwards jumps of several seconds. As one of my VM’s is running dovecot this really was a problem because dovecot hates time moving backwards.
I finally found the solution posted by Mat Mirabito in his blogpost “Linux (specifically CentOS running trixbox) gains excessive time on system clock”.
Edit your grub.conf and add the following to the kernel line:
divider=10 clocksource=acpi_pm
After this it works like… clockwork
I’m running Linux in Hyper-V VM’s since the launch of the Windows Server 2008 RTM. But in the beginning it was quite complex to get real performance and support for the network drivers.
But recently with the launch of R2 there are also new Linux Integration Components which also work for Windows Server 2008 RTM. So here is the list of steps to install CentOS with the integration components.
Download the latest CentOS distribution from http://mirror.centos.org/centos/5/isos/ (I use the x86_64 version).
Create a VM
I suggest >400MB memory
Add a Legacy Network Adapter (connect to network)
Add a Network Adapter (connect to network)
Mount the CDROM and install CentOS (I used a minimal setup)
After the installation is done make certain you’re up to date
yum update
Install the required components for the Linux Integration Components
yum install gcc make gnupg kernel-devel
Reboot into the latest kernel
Download the Linux Integration Components
Mount the CDROM
mkdir -p /mnt/cdrom
mount /dev/cdrom /mnt/cdrom
cp -rp /mnt/cdrom /opt/linux_ic
umount /mnt/cdrom
Build the drivers
cd /opt/linux_ic
./setup.pl drivers
If you get the message “No kernel-xen-devel or kernel-source package installed. You must install this package before installing the drivers.”
Edit the setup.pl file and change the following
-$kernel = `rpm -q kernel-xen-devel`;
+$kernel = `rpm -q kernel-devel`;
If everything went OK you can now see a new nic called seth0 using ifconfig
You can now remove the Legacy Network Adapter.
Remember, every time you update the kernel you have to run the setup.pl drivers command.



