This weekend I started playing with Automated Builds in TFS 2008. Over the next few weeks I am going to setup automated builds for my various projects so I can start running automated integration testing and automated staging releases at certain intervals (nightly, weekly, etc). Unfortunately I hit a snag when I tried building one of my solutions that contained a Web Application Project.

image

After some digging around, I eventually opened up the “Release.txt” log file which can be found in the deployment directory, I found the following error:

error MSB4019: The imported project "C:\Program Files\MSBuild\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" was not found. Confirm that the path in the <Import> declaration is correct, and that the file exists on disk.

Now I am no where near an expert on MSBuild or the delicacies of .csproj files, so I did my best to poke around in there and see what might be going on. For those unaware, every .csproj file is actually just an XML file with various details about your actual project. In order to view/edit the project definition you can simply right-click on the project and select “Unload Project.” Once it has been unloaded, you can right-click again and select “Edit YourProject.csproj”

image image

Once open, a search for the <Import> tag revealed the exact line causing the problem.

<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />

It would appear the Visual Studio 2008 will install all necessary MSBuild targets into the v9.0 directory – which is exactly what brings us to our problem. My Build Server does not have Visual Studio installed, it is just a basic Server 2008 box with .NET 3.5 and nothing fancy (aside from all the TFS gear). The problem is that these v9.0 targets were not available on my build machine, so I found 2 completely different solutions that ended up resolving my issue.

 

Solution 1 – Add Conditional Imports (Not Recommended)

A google search of the actual MSBuild error brought me to a single post by Steven Harman which seemed helpful but I was skeptical because it was related to multi-targeting and problems with a machine running both VS 2008 and VS 2005. I decided to try it out by editing my csproj to the following:

I replaced the original <Import> declaration to the following

<ImportCondition="'$(Solutions.VSVersion)' == '8.0'"   
  Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v8.0\WebApplications\Microsoft.WebApplication.targets" />
<
ImportCondition="'$(Solutions.VSVersion)' == '9.0'
  Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v9.0\WebApplications\Microsoft.WebApplication.targets" />

With this change in place, I re-ran by TFS Build and it worked successfully. Unfortunately, this is extremely tedious to manually edit all of my .csproj files to facilitate automated builds.

 

Solution 2 – Copy the v9.0 Targets to Build Machine (Recommended)

Once I started really thinking about the error, another solution seemed very clear and simple – just provide my build server with the target files. This solution ends up being much simpler and does not require editing any csproj files:

On your development machine, copy everything in “C:\Program Files\MSBuild\Microsoft\VisualStudio\v9.0”  to the same folder on your build machine. This will provide your build machine with the correct target files required by your projects. I have only tested the Web Application projects but I see no reason that everything else would not work properly. Please let me know if anyone runs into issues with this.

image

Categories: TFS | Visual Studio kick it on DotNetKicks.com

This post is part of an on-going series focusing on .NET Developer Tools that I have read about at one time or another, and decided it was time to start getting my hands dirty and trying them out. This series of articles will be my first impression of various tools which I will apply toward real-world scenarios.

  1. Visual Studio Snippets with Snippet Designer and ReSharper Live Templates
  2. Assembly documentation with Sandcastle and DocProject
  3. Creating and hosting plug-ins with the Managed AddIn Framework (System.AddIn)
  4. Mocking unit tests with Rhino.Mocks
  5. Dependency injection with Unity

Just what exactly are these snippets?

I believe that snippets are an underused feature built into Visual Studio. This post is my attempt at comparing the two tools I have used for snippet creation, and hoping to make more developers out there aware of just how easy they are to create and use in your existing projects. I am by no means an expert with either of these tools, but I think that is the point: they take a few minutes to create and can be reused for immediate time savers.

Much to my surprise there exists a significant number of .NET developers that are not taking advantage of code snippets, built-in or otherwise. No doubt you have all seen them in intellisense before: they appear with a partially-jagged piece of paper as seen below. When selected, they expand into a template of code that has select editable variables. A number of predefined code-snippets ship with Visual Studio, many of which I use regularly, including ctor, prop, exception, try, etc.

image

The “prop” snippet “expands” into the following code:

image

So the big question is how can we create our own snippets? Let’s take a real-world example and find out.

Snipper Designer

A few weeks ago a project was released on CodePlex called Snipper Designer. Snippet Designer is a plugin for Visual Studio that was previously used internally by Microsoft and has since been released for all of us to enjoy. After downloading the MSI, it istalled in no time and I was on my way to creating a basic snippet I wish I had created long ago.

To start off I took some Configuration Property code that I had already written as the starting point for my snippet. Anyone who has done extensive configuration with the System.Configuration assembly should be very familiar with this code: it is a property declaration for automatic strongly-typed reading and writing to an XML attribute in your app.config. There are a number of similar code snippets I will be creating for various Configuration-related tasks, and I hope to update this post with my complete list of Configuration snippets shortly.

image

As you can see, the Snipper Designer has added a context menu item to export highlighted code as a snippet. In doing so, the code below was produced in my Snippet Designer:

image

From here all I had to do was decide which “variables” would be available in my snippet. This is identifiable by the twin dollar signs ($) at the beginning and end of the variable. Finally, I assigned the snippet a shortcut, which is how we will invoke the snippet expansion in a code file. The shortcut I chose was “configProp.”

image 

Our final bit of customization lies in a property pane below the snippet code. From here I can define tooltips to help other developers who may be using my snippets, as well as set default values and expected data types associated with a variable. As you can see, I specified that the isRequired variable should be a Boolean that defaults to true.

image

 

ReSharper Live Templates

Many of you will probably be familiar with the Visual Studio plugin ReSharper. ReSharper has quickly become a favorite of mine over the last year or so, and I feel as though I have only scratched the surface of it’s productivity potential. One of said features is their own snippet framework (which they have named Live Templates). ReSharper Live Templates are slightly more powerful than the aforementioned Snippet Designer.

image

As you can clearly see, the ReSharper snippet code is almost identical to Snippet Designer. This is a great thing. In fact, I copy-pasted my Snippet Designer code into ReSharper and it instantly recognized it, so the two are very interoperable in that regard.

image

The variable definition pane is where ReSharper really shines. It has significantly more customization over Snippet Designer, given it’s very nice macro support. I have certainly not experimented with all of these predefined macro’s but they seem like they would be great features for advanced and more intelligent snippet scenarios. I hope to play with them a bit more in the near future. Above you will notice that I have used the “Constant value” macro to specify defaults for the isRequired and DataType variable, which are “true” and “string”, respectively..

image

So what exactly did the last few minutes do for us? Well for me, any time in the future where I need to define a new Configuration Property in code, I will no longer by force into vastly error-prone copy-pasting. Instead, I simply trigger my snippet by it’s predefined shortcut. In my case, I chose “configProp.”

image

When selected, it expands into this simple code block, which allows me to [tab] through the 5 variables and be on my way. And if you happen to think this won’t save you much time, then I would challenge the fact that you have probably not copy-pasted a significant number of these configuration properties before. As I mentioned in the beginning, I will be creating an army of these snippets, ranging from not only my Configuration-related ones, but repeatable tasks like ViewState-backed property wrappers, etc.

image

 

Download

Categories: DevTools | ReSharper | Tools | Visual Studio kick it on DotNetKicks.com

February 25, 2008
@ 01:24 AM

Honestly, I'm not sure if this setting is new to Visual Studio 2008 or not, but I just stumbled onto it. Typically when I'm debugging an ASP.NET application I test one page at a time, by right-clicking on the aspx and selecting View in Browser.

image

I prefer this method because I can keep the browser open at all times during development and not have to compile the whole site to quickly test something simple like markup changes. The caveat to this however, is that the Visual Studio debugger is not attached to the cassini process, so I cannot hit any break points I have set. For scenarios when I need to debug and step through code, I press the Debug button, wait for the site to compile and spawn a new browser window, and then I manually navigate to the page I want to debug. Sure this isn't a very big deal, but it would be more convenient to use the browser window I already have open, which is usually already on the page I want to test.

So I found this setting in the Web Application Properties for my site. Now when I enter debug mode, Visual Studio won't spawn a browser, it will simply wait for me to hit Refresh on the browser I already have open. It's a pretty minor change, but I find it to be very convenient.

image

Categories: ASP.NET | Visual Studio kick it on DotNetKicks.com

January 29, 2008
@ 11:07 PM

Well after some inspiration from a co-worker of mine, I have decided it's high time I joined the ranks of the virtual realm so affectionately known as the blogosphere.

Naturally, the hardest part of this venture has not been the choice of blog engine, hosting provider, nor the ____. Nay, the hardest part of this, like many bloggers [Spell-check suggests I change this to "floggers"] out there, will be coming up with some content. So now that the day is coming to a close, I figured I would recap the choices I ended up making for my blogging solution. Possibly other people out there looking to get started will find some of these tips helpful.

Step 1 - The Engine

As far as the engine was concerned I knew I didn't have many requirements. Now I had heard legends of the beast known as Community Server throughout my career as a .NET developer, and being the only real blog engine I had ever heard of, I figured I would give it a shot.

What a mistake.

The legends held true. Community Server is indeed a wild beast to tame. It is an absolutely massive application. After I finally managed to FTP the files to my host and work out the installation kinks, I was quite simply overwhelmed by the product that was presented to me. Now don't get me wrong, Community Server (despite all the negative buzz you may hear about it), has it's place in the world. A personal blog is certainly not that place. It has so many options for hosting a number of different blogs, forums, photo galleries, wikis, etc. This would all be very nice, for say,  a small business wanting to offer a blog to each of their developers, a wiki for each of their products... but not for me, and my humble 1-subscriber blog -- Hi mom!

That said, I heard good things about a product called dasBlog. The only thing that seemed strange about this engine was that it did not rely on a database back-end at all. It uses XML files for it's storage, as such the only real requirements are that your worker process have write access to the virtual directory. I'm happy with my decision thus far. It offers plenty of customization, ships with some nice themes, and was extremely easy to get up and running.

Step 2 - Authoring Tool

Ok, so I'm up and running. As I started to google and look around for what many people were using to author their blog content, I remembered an application that my co-worker told me about many months ago:

Windows Live Writer

image

This application rocks. It Just Works(TM). It has built in knowledge of many of the most popular blogging engines out there, and can determine your engine based simply on the URL to your blog. As soon as I fed it http://blog.matthidinger.com Windows Liver Writer was able to determine that I am using dasBlog, it even pulled my CSS theme down so that I can preview my entries exactly as their will appear on the site. Live Writer also knows know to publish to the engine, with the click of a button my latest blog entry is published to my site for my readers mom to read with great anticipation!

Step 3 - Syntax Highlighting

This blog will primarily be a .NET development blog. As such, I will be pasting a lot of code snippets and markup. Back to google.

Bingo - A Live Writer Plug-in called Paste from Visual Studio 

image

Now all I have to do, is highlight my code in Visual Studio, and click that Link in Live Writer to paste nice, syntax-highlighted code!

protected void btnUpdate_Click(object sender, EventArgs e)
{
    lblUpdate.Text = DateTime.Now.ToString();
}
<div class="login">
    <p>Hi</p>
    <asp:Button ID="Button1" runat="server" Text="Button" />
</div>

Step 4 - Screen Capture

Another co-worker of mine told me about some software he used (for a totally unrelated use), SnagIt.

image

This extremely convenient software has a lot of common capturing options, from whole windows, menus, selectable regions, etc. It also has a very fluid interface to take you from step to step, in quite simply the quickest way possible. I can highlight a rectangle of the screen in visual studio, add some "torn" edges, a drop-shadow, and some red-highlighting on a key area in less than 15 seconds. Very convenient. Live Writer also takes care of uploading images and linking them for me too, so these images never have to leave my desktop clipboard. What a brave new world we are living in.

This software costs $39.95 for an individual copy, but if you intend on being an avid blogger, it will pay for itself very quickly I'm sure.

solution

Wrap-Up

Well that should get me started I think. If anyone out there somehow stumbles onto this and has any other suggestions for tools please let me know! With any luck someone out there will find this information useful.

Until next time...

Categories: Blogging | Visual Studio kick it on DotNetKicks.com