About Me · Send mail to the author(s) E-mail · Twitter

At GROSSWEBER we practice what we preach. We offer trainings for modern software technologies like Behavior Driven Development, Clean Code and Git. Our staff is fluent in a variety of languages, including English.

Feed Icon


Open Source Projects


Blogs of friends

Now playing [?]

Error retrieving information from external service.


Page 1 of 3 in the VisualStudio category Next Page

Visual Studio Tip: Setting Indent Width and Tabs/Spaces Quickly Using Macros

Posted in .NET | Presentations | Visual Studio at Sunday, January 24, 2010 5:07 PM W. Europe Standard Time

Over the last years I’ve been contributing to several Open Source software projects, just to name the most recent:

All of the above projects follow their own style how to lay out the source code using indents. It seems like everybody has a different opinion you would have to cater for, for example:

  • Indenting is done with tabs
  • 4-space indents
  • 2-space indents

Often times these conventions are implicit, you have to read the source code to see the actual style the authors follow. It is encouraged to apply these guidelines to your patches ensure they will be accepted.

I often switch between developing for projects, so before writing a single line of code I have to hit Visual Studio’s Tools | Options | Text Editor Options dialog and change the indent settings to match the project’s conventions.

Visual Studio Text Editor Options

This has become very tedious, additionally, I often forget to adjust the indent settings before writing code. (Perhaps I forget it because it’s so annoying.)

To scratch that itch I sat down and wrote some Visual Studio macros that apply the most commonly used settings:

Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics

Public Module Fonts
    Sub TwoSpaces()
        Dim textEditor As Properties

        textEditor = DTE.Properties("TextEditor", "AllLanguages")
        textEditor.Item("IndentStyle").Value = vsIndentStyle.vsIndentStyleSmart
        textEditor.Item("TabSize").Value = 4
        textEditor.Item("IndentSize").Value = 2
        textEditor.Item("InsertTabs").Value = False
    End Sub

    Sub FourSpaces()
        Dim textEditor As Properties

        textEditor = DTE.Properties("TextEditor", "AllLanguages")
        textEditor.Item("IndentStyle").Value = vsIndentStyle.vsIndentStyleSmart
        textEditor.Item("TabSize").Value = 4
        textEditor.Item("IndentSize").Value = 4
        textEditor.Item("InsertTabs").Value = False
    End Sub

    Sub OneTab()
        Dim textEditor As Properties

        textEditor = DTE.Properties("TextEditor", "AllLanguages")
        textEditor.Item("IndentStyle").Value = vsIndentStyle.vsIndentStyleSmart
        textEditor.Item("TabSize").Value = 4
        textEditor.Item("IndentSize").Value = 4
        textEditor.Item("InsertTabs").Value = True
    End Sub

    Public Sub NormalFonts()
    End Sub

    Public Sub LargeFonts()
    End Sub

    Sub SetFontSize(ByVal size As Int32)
        Dim textEditor As Properties

        textEditor = DTE.Properties("FontsAndColors", "TextEditor")
        textEditor.Item("FontSize").Value = size
    End Sub
End Module

These macros are associated with toolbar buttons:

Visual Studio Toolbar Buttons

The first two buttons are associated to the LargeFonts and NormalFonts macros that set the editor font size. I like to invoke these when doing presentations. No more fiddling with Tools | Options to ensure your audience is able to read the code on the wall.

The last three buttons should be self-explaining, they’re to quickly set tabbed, two-space and four-space indents, respectively.

Reconfiguring Team Foundation Server URLs

Posted in Visual Studio at Wednesday, February 06, 2008 8:15 PM W. Europe Standard Time

Microsoft's solution to integrated software project management, the Team Foundation Server product, offers a lot of services. Beyond Source Control they have a work item tracking, build services and reporting in stock (I suspect there is even more functionality under the hood). You might be tempted to think that such an "all-in-one" solution can become complex to manage pretty soon. Let me tell you, it does! A couple of months ago I set up a Team Foundation Server (beta 2) for a project some friends of mine do for Microsoft (you will hear of it, I promise).

The server was initially installed as a virtual machine on our pretty decent server connected to the DSL line at home. The installation alone took me a week to complete since there was a bug in some XML file that made Visual Studio 2005 misinterpret the file's contents. (I don't remember exactly the source of the problem.) It was quite a hassle to get my first TFS project created.

The project hosted on that server went well, but it became pretty soon obvious that the team needed more resources in respect to bandwidth and virtual machines for testing the application they build. That's something we could not handle with our 640 kbit/s upload bandwidth and 1,5 GBs of RAM in the server. We moved the TFS virtual machine to another physical machine (more RAM) and hooked it up to the University network (lots of free bandwidth).

After moving the server we found that new projects could not be created due to one misconfigured Team System service URL, i. e. that service could be accessed on the home network (think http://tfs/) but not over the Internet. Specifically it was the URL to the SharePoint Central Administration Web Site, but that doesn't actually matter. I checked TFS' Registration Service to see if the corrected URL has been applied. The Registration Service URL looks like this:

http://<TFS Server>:<Port>/Services/v1.0/Registration.asmx

Registration Service

The WssAdminService has a publicy known URL. Good to go! I tried creating a new project, but received that same error as before.

Project Creation Failed

The error message above is a bit misleading because the Team Foundation Client did not try to connect to, but rather to the (old) tfs server, as Fiddler revealed.

Team Foundation Client Connects To The Wrong URL

Looking through the other HTTP requests originating from Visual Studio's Team Foundation Client I found that the Registration Service has never been queried to get the updated service URLs. On Buck Hodges' blog I found a hint:

When a client app, such as tf.exe, VS, or your own custom application, needs to use version control, the TF client code must request the service definition from registration service on the server.  To avoid constantly requesting service registration information that rarely changes, the client-side registration code maintains a cache and only makes the server call when the cache is out of date.

Whatever it means that the client re-requests that piece of information when it's out of date. On my machine the Team Foundation cache mentioned above is located at the folder

C:\Users\<User name>\AppData\Local\Microsoft\Team Foundation\2.0\Cache\

I wiped the cache folder and, just to make sure, I also deleted the TFS server registration in Visual Studio.

After re-adding the TFS server in Visual Studio I can now create new Team Foundation projects. Wow!

Now Playing [?]: The Cinematic OrchestraHorizonOregon

Cleaning Visual Studio from ReSharper 2.5 Leftovers

Posted in Visual Studio at Monday, July 09, 2007 11:58 PM W. Europe Daylight Time


Visual Studio 2005 has a vast amount of functionality and makes editing and refactoring code a lot easier than it was the case in Visual Studio .NET 2003. The refactoring and inline-fixing functionality like "using namespace" introduced in 2005 is responsible for a great deal of that. By the time Visual Studio 2005 hit the market I was pretty impressed by the built-in tools, but I wasn't aware of the tools taking the ideas one step further. Since then I had the chance to work with CodeRush and ReSharper. Scott Hanselman likes CodeRush a lot, but was fairly overwhelmed by its vast array of options and tweaks. Sometimes it has even been a productivity killer when some shortcut was misinterpreted, but this might have been a configuration issue on my part.

Half a year the folks at JetBrains introduced me to their productivity solution for Visual Studio named ReSharper. ReSharper has a lots of features that may be comparable to CodeRush, but I like it better primarily because there's not too much pre-configured. Also, ReSharper can reformat code according to your own/your team's conventions, which is a blast. You can slowly work your way into using ReSharper over time, I recommend reading the excellent introduction by Joe White. Read one post per day and try to apply the functionality immediately afterwards. It's very likely you'll be sold to the product, it's a huge productivity gain.


That's been a rather long introduction, so without further ado let's advance to the core of the discussion. I'm a huge fan of ReSharper but updating has been a real hassle until now. At work I use two ReSharper versions, one for Visual Studio .NET 2003 and another built for Visual Studio 2005. Upgrading one version sometimes seems to have effects on the other. Last week for example I lost my user-defined templates for VS 2003 when I upgraded to ReSharper 3.0 which only runs on VS 2005. Finding a highly customized IDE reset for no apparent reason is pretty much of a dealbreaker for me because I really don't like starting over.

Duplicate Commands

At home, after working with ReSharper 2.5 for about four months, I recently upgraded to ReSharper 3.0. Both versions run as a Visual Studio 2005 Add-In. What I see here is duplicate context menu entries and old entries in the Visual Studio commands window. (The new commands start with "ReSharper.")

Duplicate Menu Entries

These issue have been documented on the support forums and the official excuse is that

… the uninstaller is not always capable of removing [the menus] nicely.

According to the posts on the forums JetBrains has introduced a new method of inserting menu items which hopefully solves these issues in the future. For now they actually recommend resetting your ReSharper settings. Thank you, great idea!


Because I didn't want to lose my settings I wrote a couple of macros for Visual Studio that should help you getting rid of ReSharper 2.5 remnants. The macro project has two runnable methods.

Key bindings

The first one, GetKeyboardBindings,  looks at all of Visual Studio's commands and filters those relevant to ReSharper. A Visual Studio command is a unit of work, i.e. "Save that file" or "Refactor this class". Those starting with "ReSharper" will be included, so 2.5 and 3.0 commands will be on that list. You can use the macro to get quick overview of your keyboard bindings specific to ReSharper. Take a look at the output window in the Visual Studio Macro IDE:

Key Bindings

Paste the contents of the window to a text file for later reference.

Getting Rid of the Old Stuff

The CleanupReSharperLeftOvers macro basically scans all menus of Visual Studio, which also include context menus that can't be accessed using the Tools/Customize… menu. Because I couldn't find a way to get the associated command of a specific menu item (is there one?), things are getting a bit tricky.

I've collected a list of duplicate context menu items from my machine. Maybe there are some more on your box, maybe there are less. JetBrains supports our noble intent as they introduced keyboard shortcuts for some of my duplicates, which changes the menu item's name from "Reformat Code…" in ReSharper 2.5 to "Re&format Code…" in 3.0. Some items like "Go to Base/Declaration/Inheritor", on the other hand, didn't change the macro will affect both the old and the new menu items. I couldn't care less since I didn't use them anyway.

Important note: ReSharper will not recreate any of the menu items you removed using the macro. You can change the items to be removed by editing the _reSharperDuplicates list:

Dim _reSharperDuplicates() As String = {"Reformat Code...", _
                                        "Optimize Usings...", _
                                        "Run Unit Tests", _
                                        "Debug Unit Tests", _
                                        "New from template", _
                                        "Refactor", _
                                        "Find usages", _
                                        "Find usages advanced", _
                                        "Go to Base", _
                                        "Go to Declaration", _
                                        "Go to Inheritor"}

To play safe I included a global named _testMode which will keep everything as-is as long is it's set to true, which is the default.


Hopefully these macros don't break anything, at least they didn't for me. Please, make a backup and use at your own risk. Keep in mind that YMMV.

Sorting Visual Studio's "Add New Item" Dialog

Posted in PowerShell | Visual Studio at Saturday, March 03, 2007 6:33 PM W. Europe Standard Time

While browsing my ever increasing stack of unread The Daily Grind posts I came across a blog post by K. Scott Allen that describes how to sort Visual Studio's "Add New Item" dialog with PowerShell. Neat idea, as I always disliked the fact that Visual Studio has no way of sorting these items alphabetically but relies on a property inside vstemplate files.

Visual Studio Default Sort Order

After downloading and running the PowerShell script he provides on my machine, I was greeted with some error messages. Some WinFX templates were destroyed, as these have an App_Code subfolder inside the zip that the Scott's script doesn't handle well. Fortunately the script creates backups so it wasn't a dealbreaker but rather a point to start from revisiting the script and making it more compatible.

# sort-vsItems
# scott at OdeToCode dot com
# Modified by AlexanderGross at gmx dot de
# Use at your own risk!
# Script will make a backup of each template just in case.
# vjslib for .zip support.
[System.Reflection.Assembly]::Load("vjslib, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") | out-null
# Get list of VS installed templates.
$installDir = [System.IO.Path]::Combine((gp HKLM:Software\Microsoft\VisualStudio\8.0).InstallDir, "ItemTemplates")
$templateFiles = gci -recurse $installDir | ? {$_.extension -eq ".zip"}
# Append list of custom templates.
$installDir = [System.IO.Path]::Combine((gp "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders").Personal, "Visual Studio 2005\Templates\ItemTemplates")
$templateFiles += gci -recurse $installDir | ? {$_.extension -eq ".zip"}   # Sort all templates by filename. $templateFiles = $templateFiles | sort name   $i = 1 $count = 0 $tmpDir = new-item ([System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), [System.IO.Path]::GetRandomFileName())) -type directory $buffer = new-object System.SByte[] (8192)   # Iterate through all template files. foreach($templateFile in $templateFiles) {     write-host "Processing" $templateFile.FullName       # Extract all files (no methods available to modify zip in place).     $zip = new-object$templateFile.FullName)     $entries = $zip.entries()     while($entries.hasMoreElements())     {         $zipEntry = $entries.nextElement()           # Ensure output directory exists.         $filename = [System.IO.Path]::Combine($tmpDir.FullName, $zipEntry.getName())           # $zipEntry.isDirectory() does not work for Microsoft zips (e.g. Web\CSharp\         $directory = [System.IO.Path]::GetDirectoryName($filename)         if ([System.IO.Directory]::Exists($directory) -ne $true)         {             mkdir $directory | out-null               # In case the zip tells us it's a directory entry, skip the entry to prevent exceptions.             if ($zipEntry.isDirectory())             {                 continue             }         }           $in = $zip.getInputStream($zipEntry)         $out = new-object$filename)           while(($count = $$buffer, 0, $buffer.Count)) -gt 0)         {             $out.write($buffer, 0, $count)         }           $out.Close()         $in.Close()     }     $zip.Close()       # Tweak the sort order element.     $vst = gci -recurse $tmpDir | ? {$_.extension -eq ".vstemplate"}     if ($vst -eq $null)     {         # The zip file does not contain a vstemplate.           # Clean temporary directory for the next template file.         del $tmpDir\* -force -recurse         continue     }       $xmlDoc = new-object System.Xml.XmlDocument     $xmlDoc.Load($vst.FullName)     if ($xmlDoc.VSTemplate.TemplateData.SortOrder -ne $null)     {         # Sort by zip name. Sort order must be a multiple of 10.         $xmlDoc.VSTemplate.TemplateData.SortOrder = ($i++ * 10).ToString()           # Sort by item name in Visual Studio.         # Uncomment this line if you want to let Visual Studio sort by item name.         # $xmlDoc.VSTemplate.TemplateData.SortOrder = "10"           $xmlDoc.Save($vst.FullName)     }       # Backup existing zip file.     $backupName = $templateFile.FullName + ".bak"     if(test-path $backupName)     {         # Remove previous backups.         remove-item $backupName     }     move-item $templateFile.FullName $backupName       # Zip up modified version.     $zip = new-object$templateFile.FullName))     $files = gci -recurse $tmpDir     foreach($file in $files)     {         if ($file.Attributes -contains "Directory")         {             # Subfolders are created automatically with files residing in subfolders.             continue         }           # Create a file entry.         # Replacing the last backslash from $tmpDir.FullName is crucial, the zips would work with any other         # zip editor but Visual Studio doesn't like files with a leading backslash (though one doesn't see         # it in WinZip).         $zipEntry = new-object$file.FullName.Replace($tmpDir.FullName + "\", ""))         $zip.putNextEntry($zipEntry)         $in = new-object$file.FullName)         while(($count = $$buffer, 0, $buffer.Count)) -gt 0)         {             $zip.write($buffer, 0, $count)         }         $in.close()         $zip.closeEntry()       }     $zip.close()       # Clean temporary directory for the next template file.     del $tmpDir\* -force -recurse }   del $tmpDir -force -recurse   write-host "Running Visual Studio to refresh templates" $vstudio = (gp HKLM:Software\Microsoft\VisualStudio\8.0).InstallDir & $vstudio\devenv /setup

DownloadDownload the updated script.

Please note the part highlighted in red: If you leave that last red line commented, the item template entries will be sorted based on the zip file name. Just like Scott's original script did. As you can see in the screenshot below, this will get you some pseudo-grouping as all WinFX templates are at the bottom.

Sorted by Zip File Name

If you want to let Visual Studio do the sorting, uncomment the last red line and you'll get truly sorted item templates.

Sorted by Item Name

There's also another solution to the problem, but FixVsItemSortOrder has a bug that prevents "<Language>ProjectItems" folders from being sorted (so says the readme). Not sure what he means there because there's no ProjectItems folder, maybe he means the ProjectTemplates folder. FixVsItemSortOrder, in contrast to the PowerShell script above, also doesn't take user-specific item templates into account.

Now Playing [?]: AirThe Virgin Suicides O.S.T. – Bathroom girl

ASP.NET Web Site Administration Tool Flaws

Posted in ASP.NET | Visual Studio at Thursday, February 01, 2007 3:47 PM W. Europe Standard Time

While trying to configure an ASP.NET Web Application using the Web Site Administration Tool in Visual Studio I encountered the following error:

An error was encountered. Please return to the previous page and try again.

The following message may help in diagnosing the problem:
System.Configuration.ConfigurationErrorsException: A configuration file cannot be created for the requested Configuration object.
at System.Configuration.MgmtConfigurationRecord.SaveAs(String filename, ConfigurationSaveMode saveMode, Boolean forceUpdateAll)
at System.Configuration.Configuration.SaveAsImpl(String filename, ConfigurationSaveMode saveMode, Boolean forceSaveAll)
at System.Configuration.Configuration.Save(ConfigurationSaveMode saveMode)
at System.Web.Administration.WebAdminPage.SaveConfig(Configuration config)
at System.Web.Administration.WebAdminPage.VerifyAppValid()

Is the ConfigurationErrorsException really helpful? Actually not, because it's not a configuration error the admin tool encounters but rather a compatibility issue. Consider the path the project is located in, it begins with: D:\Benutzer\Alexander Groß\…. The admin tool doesn't expect paths containing special characters like my last name's "ß".

To work around the issue I created a junction named D:\Benutzer\agross pointing to D:\Benutzer\Alexander Groß and lo and behold, the Web Site Administration tool works now.

Now Playing [?]: Mark Knopfler – What it is

Page 1 of 3 in the VisualStudio category Next Page