Tales from the trenches… or Tips for Team Foundation Server Installations in Dual Tier, Mixed x64/x86 and Multi-Domain Environments…

Yes, after reading that title you are probably thinking: wtf is he doing? But trust me this is not some fancy environment, just a formal development environment. See here:

devlab_tfs1

We have a production AD and run our own development lab domain. Our developers work in production and our servers are virtualized in devlab. We have decided to run a development sharepoint, so TFS will be using just that, and we decided to go two-tier (application is on TFS, and data tier is on it’s own database, in case we need to scale out later and because it’s cleaner).

So far so good, I soon found out that TFS can only be installed on a 32-bit machine, so I scrubbed the VM and had to restart. But this was going to be only the first of many problems I encounter. This is not going to be an in-depth report, rather more a summary of problems I had and solutions I found with some tips…

Always use a slipstreamed SP1 TFS Setup CD. Look around on the internet to find guides on how to do that. Otherwise there are problems with connecting to SQL Server 2008.

1. Use any kind of snapshot technology (we run on Hyper-V so that’s no problem) and don’t try to repair a “went wrong” installation of any of the involved systems. That causes more hassle than redoing some of the steps.

2. Read the installation guide and install Reporting Services on the application tier.

3. Switch of User Account Control (at least during setup) on all machines. That caused a couple of problems. 

4. When installing TFS remember to use http://sharepoint:80/sites (the full url with the port).

5. If you encounter problems with Reporting Services, start RS manager and delete the encryption keys. Yes, DELETE the encryption keys. TFS will manage that. Also make sure you aren’t running the database as Sharepoint Integrated mode, use Native instead.

6. In Multi-domain environments, where your servers are srvXYZ.devlab.local always use the fully qualified domain name during setup. Otherwise your developers Visual Studio will try to resolve srvXYZ.production.local which of course doesn’t work. It’s a pain in the a** to correct those values later. (For Reporting Services it’s actually a known bug that you can’t change it in SP1.) If you do want to do that use TfsAdminUtil (in TFS\Tools on your hard disk) and the option changeconnections.

7. Once installed, you need to install the WSS Extensions for TFS on the Sharepoint. The version on the TFS setup CD will not work on 64-bit, so go download the Powertools for TFS (generally a good idea) from here. Install that and you might run into an error, try following this guide to get those templates into WSS. (Resolution 1 worked for me.)

8. Ok, you have TFS ready, you have WSS ready and you probably only have one last step. Make sure you have an Alternative Access Mapping in Sharepoint (the FQDN) pointing to your default web application. If you have a site running at srv1, create an access mapping from srv1.devlab.local to srv1.

I think that’s most of what I encountered and I hope it helps someone else. If I remember anything else I’ll update this post.

Quick Tip: System Center Operation Manager R2 Beta “failed to lower Monad ExecutionPolicy security level…”

Those of you trying out the BETA of SCOM R2 may run into an error during installation telling you to search for “value 3″ in the setup log files.

Doing that may uncover an error along the lines of:

GetRegistyStringValue: RegQueryValueEx failed.. Error Code: 0x80070002.
SetRegistyStringValue: RegOpenKeyEx failed to open registry key. Error Code: 0x80070005.
SetMonadExecutionPolicy: Unable to lower Monad ExecutionPolicy security level..
Action ended 12:38:48: _SetMonadExecutionPolicy.E1C3A829_C8F3_443F_B5FE_0CE01DB47829. Return value 3.

The simple solution is to disable User Account Control.

Actually if you launch PowerShell and try the “Set-ExecutionPolicy RemoteSigned” you will also get an access denied on the registry when UAC is activated. Same cause, same solution.

PS: No, I haven’t turned into a System Engineer, still a dev. Might talk a bit about what I’m doing here soon…

Add Web Reference instead of Service Reference in Visual Studio 2008

I’m just in the middle turning a 2-tier app into a 3-tier app (it was planned all along, so it’s been quite easy so gar). Anyway I added the service reference to my client project and wanted to reuse shared assemblies (which was a pain in the a** in ASP.net 2.0 Webservice – let me just say I had my set of batch scripts altering the generated proxy code). But in Windows Communication Foundation it’s really easy. When you add a reference just click on the ‘Advanced’ button and choose the options.

But that’s not actually what I wanted to blog about. Even with Visual Studio 2008 and .net 3.5 (3.0) I prefer to use old style Webservices sometimes but at the same time of course I don’t want to miss out on Linq etc. Until now I kept changing the target plattform to .net 2.0 to get my ‘Add Web Reference’ context menu item and then changing it back to .net 3.5. It works, but I kept grumbling why on earth they removed the option in VS08, well it turns out they didn’t remove it, the just moved it.

In the advanced dialog at the bottom you can add a web reference as before. (But it is still counter intuitive, why is adding an old style reference a suboption after picking a service reference? I would have preferred my context menu item.)

‘MSDTC unavailable for SQL Express Transactions’ or ‘Who took my MSDTC settings on Vista?’

Greeted this morning by the following error after starting my unit tests “MSDTC on server ‘LONDON\SQLEXPRESS’ is unavailable.”. Just moved development to a new Vista machine. Ok, that’s usually solved quickly by activating Network DTC Access (side note: System.Transactions promotes to MSDTC if it needs too).

On Win2003 and XP you opened up the Component Services, right-clicked Properties on the ‘My Computer’ node under Computer Services > Computers and opened the ‘MSDTC’ tab in the dialog. There you changed the security settings. On Vista (and Win2008 where we had similar troubles a week or so ago, and I had forgotten to ask exactly where and how our sysadmin fixed it) you have to run ‘dcomcnfg’ from the run prompt and if you take the above described path it looks like this:

Lot’s of blank space and no ‘Security Settings’. Ok, in Vista onward they moved the security settings to a new node. Expand the tree to see the ‘Local DTC’ node.

Properties on that look like this:

There you can switch to the Security tab and activate Network DTC access. Voila you’re done…

Dynamic Data – GUIDs/uniqueidentifiers as primary keys

I primarily use a GUID (uniqueidentifier) as my primary key data type. You never know when you need to synchronize your data, and I’d rather be prepared by using a GUID as a unique global identifier. Anyhow, it seems that the brand new Dynamic Data (released today as part of .net 3.5 Service Pack 1) does not really support a GUID as primary key.

The Entity Framework does not pass enough meta data to the Dynamic Data. When you use DD as a simple scaffold and add a record you will be greated with a textbox to enter the primary key for your record. Not sure about you, but I don’t have a GUIDGEN method in my brain, therefore I was looking for a solution.

There some talk of adding an attribute to the column in an inherited partial class in the forum, but that isn’t an option for large numbers of tables. So I though I’d come up with a simple solution with a little help of some jQuery goodness. (I’ve been doing a lot of jQuery lately and it’s I’m really starting to enjoy Javascript!)

My idea was to allow me to create a guid via a context menu in my dynamics data project. Like this:

You can implement the solution in your app in less than 5 minutes. You need to download

Then open your dynamic data project. You need to change 2 files:

1. Open Site.Master.cs and override the OnLoad method.

public partial class Site : System.Web.UI.MasterPage
{
    protected override void OnLoad(EventArgs e)
    {
        if (Request.QueryString["genguid"] != null)
        {
            Response.Clear();
            Response.Write(Guid.NewGuid());
            Response.End();
        }
        
        base.OnLoad(e);
    }
}

2. Then go to Site.master and insert the following directly after .

<!-- Guid Fix -->
<script src="/js/jquery-1.2.6.pack.js" type="text/javascript"></script>
<script src="/js/jquery.listen-1.0.3-min.js" type="text/javascript"></script>
<script src="/js/jquery.contextmenu.r2.js" type="text/javascript"></script>
<script language="javascript" type="text/javascript">
<!--
    $(document).ready(function() {
        // add a sticky listener to the click 
        // event of all input elements
        $.listen('click', 'input', function() {
            // add a ctx menu to each input box that 
            // creates a guid in the textbox
            $('input').contextMenu('ctxGuid',
            { bindings: { 'createGuid': 
                function(t) { genGuid(t); } } });    
        });
    });

    function genGuid(t) {
        $.ajax({
            url: location.href,
            type: 'GET',
            data: { genguid: 1 },
            dataType: 'text',
            timeout: 10000,
            error: function(XMLHttpRequest, textStatus, errorThrown) {
                alert('Error fetching guid: ' + textStatus + '/' + errorThrown);
            },
            success: function(guid) {
                $('#' + t.id).val(guid);
            }
        });
    }

-->
</script>

<div class="contextMenu" id="ctxGuid" style="display:none;">
    <ul>
        <li id="createGuid">Create GUID</li>
    </ul>
</div>
<!-- End Fix -->

Voila, you can now right-click on the primary key input textbox (or any input box for that matter) and let the server create a guid.

Hope it helps!

Entity Data Model generated from SQL 2008 and used with SQL 2005

Ok, this is of course is not a perfect scenario, because ideally my dev and test environments should be identical to my live enviroment. But anyhow, I had some troubles with Entity Framework today. After deployment my WCF services just threw exceptions (have I ever mentioned that I don’t like WCF for making everything including debugging so difficult – but that’s a different story). After I attached the debugger I finally saw what was really throwing my exceptions. It was one of my LINQ statements on the EDM, telling me:

The version of SQL Server in use does not support datatype ‘datetime2′.

Funny, I thought. Since I don’t use datetime2. It’s actually just a model imported from a SQL 2005 database to SQL 2008. But since I had generated it again from the SQL 2008 (or was it just an update, I can’t remember) it must have remembered this fact and now maps the datetime differently?

The solution in case anyone has the same problem is to open your EDMX in a file editor (or “open with…” in Visual Studio and select XML Editor). At the top you will find the storage model and it has an attribute ProviderManifestToken. This has should have the value 2008. Change that to 2005, recompile and everything works.

Hope it helps.

Sync Framework is now RTM – Go check it out!

It has finally arrived. Sync Framework as of now is live and available for download at http://www.microsoft.com/sync. Check out the release post or download it directly here. This is great and gives me a really good reason to post some more. I hardly posted anything about the last pre-release but in August check back soon for some interesting stuff.

Until then go download the bits, start playing, check my past articles in this section – the basics certainly apply, but I’ll update them to RTM status as soon as possible.

For all those in and around Vienna the ANUGA will be restarting the user group season with a special Sync Framework event on August 28th, so be sure to check the website.

Let’s keep the world in sync (how dramatic!).