Nelson Correia

.NET Thinking Machine

My Links

News

Search



Blog Stats

Archives

Post Categories

.NET

Links

Login
    u:
    p:
    Remember Me:
     

Monday, February 18, 2008 #

Visual Studio 2008 COMException when loading a web project from source control

Today I had an issue loading a web project from source control: when I open the solution file, I get an error about a System.Runtime.InteropServices.COMException:

COMException1

And when I try to reload the project:

COMException2

These errors occured somewhere in the communication between Visual Studio and IIS (By the way, I'm using Visual Studio 2008 and IIS 7, in a Windows Vista machine).

I could remove this error by simply editing the .csproj file, specifying that I don't want to use IIS:

<Project ...>
<ProjectExtensions>
<VisualStudio>
<FlavorProperties GUID="{...}">
<WebProjectProperties>
<UseIIS>False</UseIIS>
...

But although on this machine I optionally could not use IIS, in my other development machine, I want to use it.

This error was occuring because I don't have the website configured on this machine. This is most likely to occur when we are first downloading a source controlled web project and don't have IIS configured yet.
So, I've configured IIS for having the URL specified in the .csproj pointing to my project directory. And now, everything should work ok!

Wrong! I get the same error...
Apparently I have to run VS2008 with administrative privileges for it to access IIS metadata. I don't like it, but at least until find a better solution, everything works as expected! :)

posted @ 10:05 PM | Feedback (3)

eScrum, TFS and RSS

Em português.

A few days ago I was building an application that generates an RSS feed with the Scrum projects updates from our TFS server.

As I've said a few posts ago, we use the eScrum tool, that in turn uses the TFS database to store all data it needs. The fact that this tool integrates with TFS seems to be (a priori) a great advantage, but in this specific case, I don't know if this is realy an advantage.

The only advantage that I see is the bug database integration, that allows us to create bug reports in VS itself and then associate them with eScrum tasks. But... That's it! And this, I've already said the first time I talked about this tool and since then I've never found any new advantage from TFS integration.

I'm not going to talk about the disadvantages / "non-documented features" of eScrum, but this integration impose some restrictions to the associated information system. For better expose the problem, think about the (e)Scrum components: we have the Scrum projects, that in turn have products. Each of these products has a Product Backlog, that in turn has Backlog Items. Each project has sprints too and each sprint contains some Backlog Items in the Sprint Backlog with the associated subtasks. Obviously, for each of these items there are several information associated with them, as for example, name, dates, description, number of hours, etc. And besides all these things, we have the Product Owner, the Scrum Master, the team members and from these, those that are part of a specific sprint.

After saying this, you could imagine an information system well organized, where the items in bold (and maybe some other, depending on the implementation) could be transformed in entities / tables. Now, forget everything you though about: eScrum stores all this stuff in the WorkItem table from the TFS database, where the records have references ones to the others and the columns correspondent to that references change depending on what they refer to. In some cases IDs are used, in others the name or other textual columns. What a mess...

For me, the supposed advantage of having TFS integration (at least in this specific case) is made through a "hack" that only complicates the system. I think that eScrum has much more to gain if it stored data in an internal and well organized structure.

There are cases that for optimization purposes it's usefull to have an unnormalized database, but this doesn't seem to be the case.

Given the "complex" organization of eScrum information system, it is a little bit complex to build an application that reads that information. At a certain time, I don't know anymore if I'm building a query that returns the Product Backlog or the Sprint Backlog...

Nothing that the old engineering maxim doesn't solve: all engineering problems are solved by adding an aditional abstraction level (or something). Let's pass to the problem resolution that, if you still remember, was generating an RSS feed with the Scrum projects updates.

This application uses WIQL (Work Item Query Language) to obtain data from TFS, that is a query language similar to SQL.
Here is an example for getting the Product Backlog tasks of a given project:

                     SELECT
                        [System.Id],
                        [System.State],
                        [System.AssignedTo],
                        [Microsoft.VSTS.Common.Priority],
                        [Microsoft.eScrum.Common.Order],
                        [System.Title],
                        [Microsoft.eScrum.Common.Category],
                        [Microsoft.VSTS.Scheduling.BaselineWork],
                        [System.AreaPath]
                    FROM WorkItems
                    WHERE [System.TeamProject] = '<ProjectName>'
                        AND [System.WorkItemType] = 'eScrum Product Backlog Item'
                        AND [System.State] <> 'Deleted'
                    ORDER BY [System.Title]

Where <ProjectName> is the project name. To obtain all sprints, we have:

                    SELECT
                        [System.Id],
                        [System.State],
                        [System.AssignedTo],
                        [System.IterationPath],
                        [Microsoft.eScrum.Sprint.StartDate],
                        [Microsoft.eScrum.Sprint.EndDate]
                    FROM WorkItems
                    WHERE [System.TeamProject] = '<ProjectName>'
                        AND [System.WorkItemType] = 'eScrum Sprint Details'
                        AND [System.State] <> 'Deleted'
                    ORDER BY [System.Id]

As you see, these two queries are too similar and return completely different things. These are the simple cases os the Product Backlog and sprints. For the sprint tasks and subtasks, it gets a little more confuse.

To execute one of these queries, we use the WorkItemStore Query method:

TeamFoundationServer tfs = new TeamFoundationServer(serverURI, new NetworkCredential(username, password, domain));
tfs.Authenticate();
WorkItemStore workItemStore = new WorkItemStore(tfs);
string query = string.Format(sprintsQuery, project);
WorkItemCollection sprints = workItemStore.Query(query);

Having identified the most significant queries, those can be encapsulated in app's operations, that have a more user-friendly name. These operations return objects collections that then are used to make the desired feed.

To build the feed, I've used the RSS.NET library, that allows us to work with .NET objects instead of XML code, which I think that's much more error prone.
The application that I've built, each time it executes, it makes several RSS files per project and with all projects summary. Those files are integrally constructed each time the process runs and not in an incremental way. For this, I use the date associated with each WorkItem, the ChangedDate field. Using the WorkItem ID as GUID of an RSS item and the WorkItem ChangedDate field as PubDate, it's possible do detect changes in every item.

Finally, to create an RSS file with the sprints of a given project, it's as simple as:

           RssChannel channel = new RssChannel(
                "Scrum Sprints - " + project,
                "Scrum Sprint's Updates",
                new Uri("http://myserver/escrum/"));
           channel.LastBuildDate = DateTime.Now;

            foreach (WorkItem sprint in sprints)
            {
                RssItem item = GetSprintRssItem(project, sprint);
                channel.Items.Add(item);
            }

            RssFeed feed = new RssFeed();
            feed.Encoding = Encoding.UTF8;
            feed.Version = RssVersion.RSS20;
            feed.Channels.Add(channel);
            feed.Write(filename);

The final result, for the summary feed, is something like:

image

posted @ 6:58 AM | Feedback (0)