Author Archives: mglaser


Microsoft is releasing the first of many 2008 products. Not only Visual Studio and SQL Server will become 2008, also Windows Live Writer.

Windows Live Writer

You can download Windows Live Writer from here. Use this link so you can chose which language user interface you want to use.

Here a some of the Highlights

  • Vista x64
    x64 is becoming more popular every day. So a wise decision.
  • WYSIWYG editing
    Writer knows your blog’s visual theme. So you can see exactly what your posts will look like as you write them, before you publish. No more wasting time previewing your posts online.
  • Support for more spell checking languages.
    Still not nearly as many as possible, but it’s a start. English spell checking is now available in all builds.


  • Localized versions for lots of new languages/markets.
    Select your own on the above link
  • Powerful editing features
    Creating compelling blog posts is much easier with the ability to insert and edit tables, check spelling as you type, and format and hyperlink content at your fingertips.
  • Rich media publishing
    Writer makes publishing rich media as easy as sending e-mail. Insert and customize photos, videos, maps, tags, and lots of other cool content—then click the “Publish” button. It’s that easy.
  • Offline editing
    Now you can blog anytime, from anywhere. Writer synchronizes drafts on your blog with changes you make when you’re offline, so you don’t have to worry about reconciling different versions.
  • <pre> handling in XHTML mode is fixed.
    Beta 3 would collapse whitespace in all tags, including <pre>, in XHTML mode.
  • Print / Print Preview -
    You can print blog posts directly from WLW just like you would do inside Microsoft Word or any word processor.


  • Embed YouTube Videos in Blogs - Earlier you had to download a separate Insert Video plugin to embed web videos in your blog posts but now that feature is inbuilt - just type the video URL and WLW will automatically generate the embed code. Pretty handy. More Windows Live Writer Plugins.


Windows Live Writer supports YouTube, Splashcast, Brightcove, Google Video, MySpace, Revver and MSN Soapbox.

Another great product from Microsoft and it's free as well. Besides its own features, you can also download dozens of plug-ins. So start blogging!


Technorati Tags: ,

Christmas comes early this year. Microsoft is releasing cool tools by the day. One of these tools is the TFS to TFS Migration Tool. With this tool you're able to migrate your work items and source from one TFS server to another. Since a lot of my customers started with TFS as soon as it was available, they started putting code in it. But before you can add code to the Version Control of TFS, you have a process as well. Most of my customers chose MSF Agile, but in time they changed, chose another one or deleted some of its features. In some cases you just want to start all over again, but nobody is willing to offer the history of their sources.


Check for the full details. Download it today and tomorrow you can rearrange all you projects. Keep in mind this tool will work for the same server as well on other servers. When you migrate on the same server, your sources won't be destroyed since TFS 2005 doesn't support such a feature. You sources will deleted but still be visible for users who wants to see deleted files.


This tool was built using the Migration and Sync Toolkit, so it should prove to be useful for anyone that is writing a custom migration tool.  We have received some comments in the past about the WSS to TFS sample tools containing too much WSS specific code that makes it hard to understand the toolkit.  Although this tool has plenty of TFS specific code, it will probably more closely resemble a tool built to integrate with another version control or work item tracking system.  There is also a GUI built on top of the tool to make configuration easier, which also serves as a good example of how to build a configuration layer for a custom migration tool.


Technorati Tags: ,


More and more people are migrating their Report Server environment to SharePoint. This migration will give you the ability to open your reports in SharePoint instead of just another UI. For a complete explanation on this migration check a previous blog of my at SQL Server 2005 Service Pack 2 (Integration between Reporting Services and SharePoint 2007). Before you can integrate between Reporting Services and SharePoint you have to decide if you'll setup a separate Application Tier. Almost all my customers have a similar setup as pointed out below.

SERVER 1 - Data Tier

.NET Framework 2.0

SQL Server 2005 SP2 (Database)

SERVER 2 - Application Tier

Internet Information Server 6.0

.NET Framework 2.0 & 3.0

Windows SharePoint Services 3.0

SQL Server 2005 SP2 (Reporting Services)

Reporting Services Add-in for Microsoft SharePoint Technologies

It's also possible to install all these products on one machine, but it isn't advisable. Reporting Services installs some Web Services and a Web manager (will be replaced by the Reporting Services Add-in for Microsoft SharePoint Technologies). After installation you can find all files at the Program FilesSQL ServerMSSQL.#Reporting ServicesReportServer directory. If you've installed al of the above products and updated it with the latest service packs and updates you can start the Reporting Services Configuration Manager. This tool can  be started for the Start menu at All Programs - SQL Server 2005 - Configuration Tools - Reporting Services Configuration. Depending on the choice of installation you will see a similar screen like this.


If some of the above sections displays a red cross mark fulfill these steps.

  • The Report Server virtual Directory should point to the web site where you installed and configured SharePoint.
  • The Report Manager Virtual Directory will become obsolete, so it isn't necessary to implement this step.
  • The Windows Service Identity is used under which the Report Server Windows service runs. The Report Server Windows service performs initialization, reversible encryption, database maintenance tasks, and all scheduling and delivery. The service runs in the background. It performs end-to-end processing for reports that run on a schedule (specifically, it creates report snapshots and runs subscription reports).
    Because it performs all encryption operations, the Report Server Windows service must be running whenever you specify or use encrypted values. Specifying stored credentials, running a report that uses stored credentials, and publishing a report to a report server (data source information is encrypted) are all operations that require the Report Server Windows service.
  • The Web Service Identity creates or uses a application pool under which the identity runs in IIS.

Now all steps are completed and Reporting Services is initialized you can start completing the last step to complete SharePoint Integration. Click on the Database Setup section and Change the Server Mode from Native to SharePoint Integration. After hitting the change button fill out the following screen and make sure the Create the report server database in SharePoint Integrated mode is selected. 


Type in new Database Name (e.g ReportServerWSS). Note. Don't start to create a database which starts with WSS because in some cases the connection will fail. After creating the database the SharePoint integration is completed.


Although it isn't hard to install and configure the add-in, it will give you a lot of steps to fulfill. First of all you have to make a decision about your server topology. Secondly you must setup Reporting Services to use you're data tier (remote or local). Third upgrade your database, so all content will be added to SharePoint and the rendering and caching stays in SSRS. In my next blog I'll explain how Activating SharePoint for Reporting Services works.


I wasn't blogging for a long time, but now I'm back with a strong rhyme.
Look, near the camera, snap my picture. I'll sign my name on it, then I get richer.
Like LL said don't call it a comeback and face the fact Jack I'm all that.

The last couple of months I spend a lot of time developing and giving courses. Like a few of my colleagues already posted on their blogs, I spent a lot of time on our Summer Classes . Check Update summer classes 2007 at and Summer Classes 2007 at for the details. My part in these classes was the developing an teaching the BI part. I had lots of fun with all my students and they appreciated my experiences as well. By the way these classes will be held again in January or February of 2008. See Class-A Summer Classes become Winter Classes at for full details.

Besides the BI part, I also developed a couple of our SharePoint modules. SharePoint is the reason why I was unable to post blogs for a long time. Our SharePoint courses SHAREPOINT 2007 DEVELOPMENT UNLEASHEDSHAREPOINT 2007 BI and SHARPOINT INSTALLING & CONFIGURING are almost every week sold out. I'm not surprised because SharePoint is HOT and other course provides can't deliver a training because the MOC (Microsoft Official Curriculum) material isn't available yet.

Here is some info about my next posts. More and more people are migrating their Report Server environment to SharePoint. I already received a couple of emails how to setup such an environment, but I never had the time to create a post. Today I received another mail requesting me to explain this. So my next posts will be about this subject. I'll divide this subject in three post.

  1. Post: Installing & Configuring the Integration between Reporting Services and SharePoint
  2. Post: Activating SharePoint for Reporting Services
  3. Post: Developing Reports for Reporting Services under SharePoint

I'll keep you posted.



Since almost everyone wanted to upgrade TFS V1 to use WSS 3.0, Microsoft added two guides to MSDN in which they explain how to update. In this guide I'll explain how to update your Reporting Services to your WSS 3.0 site as well. This will give you the ability to completely shut down the old TFS Web Site. Only I can of emergency or an update you can restart it temporarily again.

To take advantage of one site instead of two you can configure SSRS on the WSS 3.0 site.

  1. Configure SSRS using the Reporting Services Configuration Manager. You can find this by clicking Start, pointing to All Programs, pointing to Microsoft SQL Server 2005 -> Configuration Tools, and clicking Reporting Services Configuration

  2. Create and Configure Virtual Directories
    The report server and Report Manager are ASP.NET applications accessed through URLs. Each URL includes a virtual directory that you specify in the Reporting Services Configuration tool.

    Select Report Server Virtual Directory and click New..

    • For Website Select SharePoint v3
    • For Virtual Directory leave the suggested name
    • Click Ok

      Select Reports Virtual Directory and click New..

    • For Website Select SharePoint v3
    • For Virtual Directory leave the suggested name
    • Click Ok
  3. Change the Web Service Identity
    Select ReportServer application Pool for both Virtual Web Servers

  4. Click Apply and OK
  5. Change the permissions of your SharePoint v3 Web site.
    e.g. C:InetpubwwwrootwssVirtualDirectories81
    NETWORK SERVICE Account(Read & Execute)
  6. To update the registry key for SQL Report Server
    • On the Team Foundation application-tier server, click Start, click Run, type regedit, and then click OK. Registry Editor opens.
    • In Registry Editor, expand HKEY_LOCAL_MACHINE, expand Software, expand Microsoft, expand Visual Studio, expand 8.0, expand Team Foundation, and then click ReportServer.
    • Right-click Key and then click Modify.
    • In the Edit String dialog box, in Value data, change the value to reflect the https address of your Team Foundation application-tier server, and then click OK. For example, if the name of your application-tier server is Contoso1, you would change the value of the data from:




    • Close Registry Editor.
  7. Modify the sample XML below, substituting the entries for [protocol], [WSS Server 3.0], [port] with those of the new WSS 3.0 instance. Typically protocol will refer to http or https, whereas the port number will be the port number you specified for the new Web application during previous steps.

                    <Url>[protocol]://[WSS Server 3.0]:[WSS 3.0 admin port]/ ReportServer/ReportService.asmx
                    <Name> BaseReportsUrl</Name>
                    <Url>[protocol]://[ WSS Server 3.0]:[port]/Reports</Url>

  8. Save your changes to the sample as SSRS_registration.xml making sure that the file can be accessed by the Team Foundation Server application tier computer.
  9. Open a Command Prompt window on the Team Foundation Server application tier computer and execute the following commands (substituting your Team Foundation Server data tier machine name for myDTserver in the TFSReg.exe command here):

    iisreset /stop

    cd “%programfiles% Microsoft Visual Studio 2005 Team Foundation ServerTools”

    TFSReg.exe SRSS_registration.xml myDTserver

    iisreset /start

  10. Confirm that the changes have been made successfully. To do this, follow these steps:

    Check that the service interface changes that you made through running TfsReg.exe are present in the resulting XML.

  11. Team Explorer cache. Team Explorer, which is the add-in within Visual Studio 2005 which provides integration with Team Foundation Server functionality, receives the WSS URL from Team Foundation Server. This value is cached with a default cache timeout of 7200 seconds (two hours). If you are performing this update with sufficient downtime before clients will begin connecting again, then no further action is required. However, if clients will need to connect to the team project portals before the cache time has expired, then you may wish to manually invalidate the cache. To do so, each client should close all open instances of Visual Studio 2005 then delete the following folder: ““%USERPROFILE%Local SettingsApplication DataMicrosoftTeam Foundation1.0”

Again you're just a few clicks a way for creating a single web site which contains WSS 3.0 and Reporting Services.


1 Comment

A couple of weeks ago I posted a post about creating a couple of data generators for DataDude. In mine first data generator I used aggregation extensibility. Microsoft divided each form of extensibility in another section. Since I created one or more instances of the standard data generator classes and use those to do the work its called aggregation extensibility. Another thing I created is the use of multiple generators in one class. The base class implementation constructs outputs that are based on public properties that are marked with the OutputAttribute. The inputs are set by using the InputAttribute. Using properties that are marked with attributes provides a simple mechanism for declaring input and output values that are strongly typed. The code below uses multiple outputs, a numeric and a regular expression data generator to do the work.

    1 using Microsoft.VisualStudio.TeamSystem.Data.DataGenerator;
    2 using Microsoft.VisualStudio.TeamSystem.Data.Generators;
    3 using System;
    4 using System.Globalization;
    6 namespace DutchGenerator
    7 {
    8     public class DutchDataDetails : Generator
    9     {
   10         #region Fields
   11         private string _prefix;
   12         private string _seperator;
   13         private CasingType _casing;
   15         private RegexString _regex;
   16         private Int _numeric;
   17         private Random _rand = new Random();
   19         private string genPostCode;
   20         private string genProvince;
   21         private string genProvinceAbbrev;
   22         private string genPhoneNumber;
   23         private string genMobilePhoneNumber;
   24         #endregion
   26         #region Enumerators
   27         public enum CasingType
   28         {
   29             NormalCase,
   30             LowerCase,
   31             UpperCase,
   32             TitleCase
   33         }
   35         private string[] Provinces = new string[] {
   36               "Drenthe"
   37             , "Flevoland"
   38             , "Friesland"
   39             , "Gelderland"
   40             , "Groningen"
   41             , "Limburg"
   42             , "Noord-Brabant"
   43             , "Noord-Holland"
   44             , "Overijssel"
   45             , "Utrecht"
   46             , "Zeeland"
   47             , "Zuid-Holland"};
   49         private string[] ProvincesAbbrev = new string[]
   50         {
   51               "DR"
   52             , "FL" 
   53             , "FR"
   54             , "GL"
   55             , "GR"
   56             , "LI"
   57             , "NB"
   58             , "NH"
   59             , "OV"
   60             , "UT"
   61             , "ZH"
   62             , "ZL"
   63         };
   64         #endregion
   66         #region Inputs
   67         [Input(Name = "Prefix", Description = "Prefix for (mobile)phonenumbers. (e.g. +31)", DefaultValue = "")]
   68         public string Prefix
   69         {
   70             get
   71             {
   72                 return _prefix;
   73             }
   74             set
   75             {
   76                 _prefix = value;
   77             }
   78         }
   80         [Input(Name = "Seperator", Description = "Seperator for postcodes (e.g. space char) and (mobile)phonenumbers (e.g. parenthes and minus char).", DefaultValue = " ")]
   81         public string Seperator
   82         {
   83             get
   84             {
   85                 return _seperator;
   86             }
   87             set
   88             {
   89                 _seperator = value;
   90             }
   91         }
   93         [Input(Name = "Character casing", Description = "Character casing of generated string.", DefaultValue = CasingType.NormalCase)]
   94         public CasingType CharacterCasing
   95         {
   96             get
   97             {
   98                 return _casing;
   99             }
  100             set
  101             {
  102                 _casing = value;
  103             }
  104         }
  105         #endregion
  107         #region Outputs
  108         [Output(Name = "Province name", Description = "The long form of the province name.")]
  109         public string Province
  110         {
  111             get
  112             {
  113                 return genProvince;
  114             }
  115         }
  117         [Output(Name = "Province abbreviation", Description = "The 2 letter form of the province name.")]
  118         public string ProvinceAbbrev
  119         {
  120             get
  121             {
  122                 return genProvinceAbbrev;
  123             }
  124         }
  126         [Output(Name = "Postcode", Description = "A valid _regex.")]
  127         public string PostCode
  128         {
  129             get
  130             {
  131                 return genPostCode;
  132             }
  133         }
  135         [Output(Name = "Phonenumber", Description = "A valid phonenumber, including area code.")]
  136         public string PhoneNumber
  137         {
  138             get
  139             {
  140                 return genPhoneNumber;
  141             }
  142         }
  144         [Output(Name = "Mobile Phonenumber", Description = "A valid mobile phonenumber.")]
  145         public string MobilePhoneNumber
  146         {
  147             get
  148             {
  149                 return genMobilePhoneNumber;
  150             }
  151         }
  152         #endregion
  154         protected string FormatOutputValue(string originalOutput)
  155         {
  156             string formattedValue = String.Empty;
  158             if (originalOutput != null)
  159             {
  160                 //format character casing
  161                 switch (_casing)
  162                 {
  163                     case CasingType.NormalCase:
  164                         formattedValue = originalOutput;
  165                         break;
  167                     case CasingType.LowerCase:
  168                         formattedValue = CultureInfo.CurrentCulture.TextInfo.ToLower(originalOutput);
  169                         break;
  171                     case CasingType.UpperCase:
  172                         formattedValue = CultureInfo.CurrentCulture.TextInfo.ToUpper(originalOutput);
  173                         break;
  175                     case CasingType.TitleCase:
  176                         formattedValue = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(originalOutput);
  177                         break;
  179                     default:
  180                         break;
  181                 }
  182             }
  184             return formattedValue;
  185         }
  187         protected override void OnInitialize(GeneratorInit initInfo)
  188         {
  189             base.OnInitialize(initInfo);
  191             switch (this.OutputKey)
  192             {
  193                 case "Province":
  195                 case "ProvinceAbbrev":
  196                     _numeric = new Int();
  197                     _numeric.Distribution = new Normal();
  198                     _numeric.Min = 0;
  199                     _numeric.Max = 11;
  200                     _numeric.Initialize(initInfo);
  201                     break;
  203                 case "PostCode":
  204                     _regex = new RegexString();
  205                     _regex.Expression = "[1-9]{1}[0-9]{3}##([a-z]|[A-Z]){2}";
  206                     _regex.MaximumLength = 8;
  207                     _regex.Initialize(initInfo);
  208                     break;
  210                 case "PhoneNumber":
  211                     _regex = new RegexString();
  212                     _regex.Expression = "0[123457]{1}[0-9]{1}##[0-9]{7}";
  213                     _regex.MaximumLength = 12;
  214                     _regex.Initialize(initInfo);
  215                     break;
  217                 case "MobilePhoneNumber":
  218                     _regex = new RegexString();
  219                     _regex.Expression = "06##[0-9]{8}";
  220                     _regex.MaximumLength = 12;
  221                     _regex.Initialize(initInfo);
  222                     break;
  224                 default:
  225                     break;
  226             }
  227         }
  229         protected override void OnGenerateNextValues()
  230         {
  231             string result;
  232             base.OnGenerateNextValues();
  234             switch (this.OutputKey)
  235             {
  236                 case "Province":
  237                     _numeric.GenerateNextValues();
  238                     genProvince = FormatOutputValue(Provinces[_numeric.Result]);
  239                     break;
  241                 case "ProvinceAbbrev":
  242                     _numeric.GenerateNextValues();
  243                     genProvinceAbbrev = FormatOutputValue(ProvincesAbbrev[_numeric.Result]);
  244                     break;
  246                 case "PostCode":
  247                     _regex.GenerateNextValues();
  248                     genPostCode = FormatOutputValue(_regex.Result.Replace("##", _seperator));
  249                     break;
  251                 case "PhoneNumber":
  252                     _regex.GenerateNextValues();
  253                     result = _regex.Result.Replace("##", _seperator);
  255                     if ((_seperator.Length > 0) && (_rand.Next(0, 2) == 0))
  256                     {
  257                         result = result.Replace(_seperator, result.Substring(3 + _seperator.Length, 1));
  258                         result = result.Remove(4, 1);
  259                         result = result.Insert(4, _seperator);
  260                     }
  261                     genPhoneNumber = FormatOutputValue(_prefix.Length > 0 ? _prefix + result.Substring(1) : result);
  262                     break;
  264                 case "MobilePhoneNumber":
  265                     _regex.GenerateNextValues();
  266                     result = _regex.Result.Replace("##", _seperator);
  268                     genMobilePhoneNumber = FormatOutputValue(_prefix.Length > 0 ? _prefix + result.Substring(1) : result);
  269                     break;
  271                 default:
  272                     break;
  273             }
  275         }
  277     }
  278 }

Dutch data generator (Provinces, Postcodes, Phone - and Mobile phone numbers)

To register the class in the Visual Studio environment a XML file has to be created where all objects are registered through

  • XML file naming convention <AssemblyFilename>.Extensions.xml
  • The file extension .Extensions.xml is mandatory
  • The Extensions.xml file has to be placed in the %ProgramFiles%Microsoft Visual Studio 8DBPro directory
  • Must implement the schema defined in %ProgramFiles%Microsoft Visual Studio 8DBPro Microsoft.VisualStudio.TeamSystem.Data.Extensions.xsd
<?xml version="1.0" encoding="us-ascii"?>
<extensions assembly="DutchGenerator, Version=, Culture=neutral, PublicKeyToken=d6ddc2e862439c84" version="1" xmlns="urn:Microsoft.VisualStudio.TeamSystem.Data.Extensions" xmlns:xsi="" xsi:schemaLocation="urn:Microsoft.VisualStudio.TeamSystem.Data.Extensions
    <extension type="DutchGenerator.DutchDataDetails" enabled="true" />


There are two options where the extension assemblies can be placed

  • %ProgramFiles%Microsoft Visual Studio 8DBProExtensions directory
  • GAC, requires the assembly to be strong name signed

Do use the extension assembly the following steps have to be done

  • Copy .extensions.xml file to DBPro directory
  • Copy assembly to DBProExtensions directory
  • GAC the extension assembly

Since this isn't handy when your developing you Extension, you could create a generic post build event:

copy "$(ProjectDir)$(TargetName).Extensions.xml" "$(ProgramFiles)Microsoft Visual Studio 8DBPro$(TargetName).Extensions.xml" /y 
copy "$(TargetDir)$(TargetFileName)" "$(ProgramFiles)Microsoft Visual Studio 8DBProExtensions$(TargetFileName)" /y 
"$(DevEnvDir)....SDKv2.0bingacutil.exe" /if "$(ProgramFiles)Microsoft Visual Studio 8DBProExtensions$(TargetFileName)"

In the next screendumps the Dutch Data Generator is used to select and modify one of the data generator outputs and create the generated output.

Generator properties

Generated output

I love the data generators option. More and more often companies prohibited you to use you production data in a test environment, probably because of SOX (Sarbanes-Oxley). So you have to create your own test data with the same amount of records. Before DataDude this was hard to do, but with DataDude you can do this easily and even create your own generators. I hope lots of people will create useful generators and maybe we can collect them on codeplex.


On June 11 and 12, I attended a 2-day Visual Studio Team Edition for Database Professionals workshop at Class-A. This event was hosted by Gert Drapers (also aka DataDude), see his blog post announcing the event. Gert discussed all the important features of the tool and some of my fellow attendees complained the workshop was too short for such an enormous set of features and exercises. I have to agree a bit, because we not only discussed all the features of DBPro, we also covered the features of SR1 and the not yet released power tools. The Power Tools are listed on the Future Release page of VSTS. So there was hardly time for any of the exercises, but I don’t give a ****, because I’m more interested to hear and see what DBPro can do. After this workshop and the DevDays, I started to do my own exercises. One of the things, which I will give my full attention, is the ability to extend DBPro. I will focus on all extensions, but data generation in particular.

The power of VSTE DBPro data generation, lays in the fact you can generate data that closely matches your domain values allowed in your environment. The problem is that knowledge of the allowed and disallowed domain values cannot always be derived from the schema, so you have to go in to the designer and configure the generators for your columns. By using the built-in data generators, you can generate random data, generate data from existing data sources, and control many aspects of data generation. If the functionality of the built in generators is insufficient, you can create custom data generators. To create custom data generators, you use the classes in the Microsoft.VisualStudio.TeamSystem.Data.DataGenerator namespace.

Let me start by motivating the data generators that I would like to build. I often find databases which contain Dutch related information, such as postal code, phone number, provinces, e.t.c. Furthermore a lot of columns contain data which could be generated with a DataBound generator, but some of these data could also be retrieved from a number of web services (Cities, Countries, Currencies, ISO-codes e.t.c.). Last but not least I have credit card background, not that I misused other peoples card, but I build a card number controller to prevent this.

The extensibility API provides classes from which developers can inherit. In addition to classes, the API includes attributes that you can apply to your derived classes. By applying these attributes, you reduce the amount of code that is required in custom generators for common cases.

You can use the extensibility API in the following four ways to create custom data generators:




Declarative Extensibilty

  • Inherit from the Generator class.
  • Add custom input and output properties.


Normal Extensibility

  • Inherit from the Generator class.
  • Add custom input and output properties.
  • Override one or more Generator methods (for example, OnGenerateNextValues and OnInitialize).

Medium. This method is recommended in most cases.

Aggregation Extensibility

  • Inherit from the Generator class.
  • Add custom input and output properties.
  • Override one or more Generator methods.
  • In your class, create one or more instances of the standard data generator classes and use those to do the work.


Base Extensibility

  • Create a class that implements the IGenerator interface.
  • Implement all methods that are required by your generator.
  • Create a custom designer for the generator that implements the IDesigner interface.
  • Implement all methods that are required by your designer.


Since I hope to be better than the average, I will use Aggregation Extensibility for my Dutch data generator, in which I will probably use the Regular Expression generator to build my data details. For one of the other two data generators I will be using Base Extensibility and give them their own designer. So keep in touch and follow my posts.



As you can read in my previous post I received a request from Yogita Manghnani to share my experiences. This is the second post concerning options I struggle with in TFS. Almost all people where I introduce TFS come up with the same question "Can I relate my Work Items?" and I always have to reply "Yes you can, but there is no hierarchy." Personally I think relationship between Work Items is the base of good project, especially if it contains a hierarchy. Hierarchy is in all projects and most tools which contain project management i.e. Look at MS Project. Of course you can almost use TFS without this notion and use Areas and Iterations, but it is harder to manage your projects if you can’t relate your Work Items with a true relationship.

Loïc Baumann created the tool for relating all your Work Items in TFS. After installing the MSI and configuring your Web Server and Work Items you're able to relate as you can see in this screen dump. Every Work Item Type can have its own icon which is pretty handy.


What is this all about? There are two simple answers to this question:

- WICreator is a standalone application that let a Team System user to create Work Items in a hierarchical way. You also have the ability to send existing one to a “Recycle Bin” to get rid of them (useful as you can’t delete Work Items).

- WINetwork is a web service triggered by the TFS Alert System when a Work Item has a field change.
The main purpose of WINetwork is to analyze the changes regarding to their environment, and then respond by modifying fields of surrounding Work Items. (E.g. when a child Work Item turned to Active, then WINetwork will turn the parent from Proposed to Activate)

Work Item Creator and WINetwork are both available in codeplex:

Customize Work Items
Before you use those tools you need to some customization of the Work Item Types. To enable the hierarchy you have to add custom fields in your Work Item Types definition. Use the Process Templates Editor from Imaginet Resources or the one shipped with the latest Team System Power Tools.

Add the following three fields:

Name Type RefName Name Description
ParentWI integer Cegedim.ParentWI 0 Relation between child and parent
FirstChildWI integer Cegedim.FirstChildWI 0 First child to display beneath a parent
NextWI integer Cegedim.NextWI 0 Order of Work Item, Relation between siblings

What a nice tool. I could only dream of such a solution, but Loïc managed to build one. It will cost you some time to setup, even with the document and the use of Team System Power Tools, but when you finally manage to do so you can easily see how your Work Item is related in your project. One of the downsides is, it doesn't integrate in Team Explorer (VSTS) even I like his Click Once thought and the other is, the hierarchy can't be related to MS Project or Excel yet. Furthermore it would be nice if there was a relation between the hours of all items and the ability to only start a new work item if previous work items are finished. So it's up to us TFS lovers or MSFT'ers to support Loïc. For the record it's only downloaded 17 times. Shame on you TFS gurus out there.



This week I received an email from Yogita Manghnani, a Program Manager in the TFS Office Integration team who requested me to share my experiences with TFS. Since the beginning of TFS I'm one of those people who really adore TFS, but unfortunately not everything is implemented the way I like it. Two options I constantly struggle with are comparing Office files and the hierarchy of Work Items.

In this blog post I will discuss how I resolved my problem with comparing Office files. Still it isn't the best solution; my hope is on Microsoft to solve this problem completely. In one of my latest blogs I talked about using TFS for other IT related projects. We are using TFS to setup training material which consist of slide decks in PowerPoint, practicum description in Word and depending on the training examples and solutions in Visual Studio .NET. The best thing Source Control can do when you try to compare two Office files is displaying a message "Binary files differ". I know Microsoft is targeting on SharePoint for Office files and I'm a great admirer of SharePoint, but since I want to branch and compare the documents it isn't suitable for me and I hoped Source Control could do better.

So it's up to me to find a proper solution. I haven't check out what the possibilities are to extend Source Control so I first setup VS.NET to use another program to see the differences between Office files.

In Tools menu select Options

Within the tree follow this exact path

Source Control -> Visual Studio Team Foundation Server -> Configure User Tools ...


As you can see I wanted to let Word or PowerPoint decide what the differences are, but this is not possible. These two programs doesn't support the proper command-line switches. To check all command-line switches of the preferred Office tools, click these links:

Document-Comparison-Thumb2We're now in the stage of testing Diff Doc to this job. 'Diff Doc' is a powerful yet easy to use folder/file compare and remediation utility. You can use it to compare files of all types including MS Word/Excel/PowerPoint, PDF, RTF, Text, HTML, XML, WordPerfect and more.

When comparing to PowerPoint files it will result in the following screen dumps. 



And as you can see I'm now able to show if my branched Office files differs from the original. After this simple differ check I still want to use Word and PowerPoint to do the real compare and merge to both files. Within Word 2003 / 2007 it isn't a problem at all. Word supplies a great feature to see all differences, not only text, but also styles. Besides this it has a perfect interface to merge the two files.


PowerPoint 2007 on the other hand, has removed its feature to 'Compare and Merge Presentations', as you can see in the picture below. Who is responsible for such an act? I wonder how and when this is decided. Somebody had to say something like this. "You know what, since nobody complained about we forgot the 'Compare and Merge Presentations' feature in the 2007 beta phase, we'll just leave it out. And if we’re trying to release Office 2010 we'll mark it as a new feature again. This is a win/win situation. We got less to program now and add it as an additional feature in Office 2010." And all people of the Microsoft Office Team replied "You're the man".


So we're back to PowerPoint 2003 again which still contain this feature. To support 2007 File Formats in Office 2003 you'll need the Microsoft Office Compatibility Pack for Word, Excel, and PowerPoint 2007 File Formats. See After installing this Pack which becomes almost a must for every old-fashioned Office user, we can compare PowerPoint Decks which we created in PowerPoint 2007.


What have you done Microsoft? How could you remove the astonishing compare function on PowerPoint files? You're absolutely not the man. Furthermore why doesn't Office give us the opportunity to compare two files using a command-line options. Please VSTS Team and Office Team talk to each other. Make your customers happier than they now are and please people respond if you've found another solution, I keep myself recommended.


SQL Server Code name

Microsoft is planning to release the next version of its SQL Server database, which is codenamed "Katmai," in 2008. Everybody is waiting anxiously what this version will bring us. Like everybody I've a personal wish list for SSRS and it seems MS is working hard to fulfill this list.

  • Rich Text support
  • RTF/DOC/PPT rendering
  • Shared Styles (Styles sheets)
  • Templates
  • Font embedding in PDF
  • Many Chart enhancement (Dundas)
  • Edit in Preview

At the Microsoft Business Intelligence (BI) Conference Jeff Raikes announced that Microsoft likes to acquire OfficeWriter from SoftArtisans. OfficeWriter is the only product available today that works with Reporting Services to preserve 100% of the features in your sophisticated spreadsheets and documents. Reporting Services currently does not support MS Word and has limited support for MS Excel. This is a huge win for folks who want to render reports to Word.

Another thing which is quite remarkable is the Report Designer will get a new look and feel. This could mean that MS is integrating the original Report Designer which is a part of BIDS and Report Builder to one product or the Report Designer is leaving the Visual Studio environment. Here is screen dump of the new Report Designer.

New Report Designer

Furthermore Microsoft added a new Katmai informational site Your Data, Any Place, Any Time. This site will inform you about the latest evolvements of "Katmai".

Unfortunately not all sessions from the Microsoft Business Intelligence (BI) Conference are and will be available on the net, so it's hard to understand where MS is heading to. Maybe the organizers could learn something from the MIX organizers because all sessions were available on the net within 24 hours after each live presentation. Great job guys! Besides this I hope you're are as enthusiastic as I'm about "Katmai" and I can hardly wait till the first CTP of "Katmai" will come out public.