Contact

Alexander Groß
  • Send mail to the author(s) E-mail
  • del.icio.us
  • Skype
  • twitter
Feed Icon

Tags

Open Source Projects

Archives

Blogs of friends

Now playing [?]

  1. Sting – Soul Cake
  2. Sting – Gabriel's Message
  3. Miles Davis Quintet – Waiting for Miles
  4. Parov Stelar – Red Haired Woman
  5. Parov Stelar – Kisskiss
Audioscrobbler/Last.fm

ClustrMap

Page 1 of 2 in the NET 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()
        SetFontSize(10)
    End Sub

    Public Sub LargeFonts()
        SetFontSize(14)
    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.

Using the Microsoft Solver Foundation Add-In for Excel

Posted in .NET | Debugging | Office at Sunday, January 17, 2010 3:52 PM W. Europe Standard Time

After listening to the Hanselminutes episode on Microsoft Solver Foundation (MSF) I decided it’s time to give it a shot today. Solver Foundation seems to be a solution to a set of constrained problems I sometimes face:

  • Sharing costs and calculating minimal money transfers after trips with my friends, where each friend spent some money.
  • Giving out questions to attendees of our User Group “Boot Camps”: Speakers prepare ~20 questions, ranging from easy to moderate levels. We assign each attendee an easy question and one to chew a bit upon. Further, every question should be given out to two attendees, so in case someone doesn’t make it to the meeting we’re still able to cover the question.

Something I don’t remember Scott Hanselman and his guest talking about is that Solver Foundation comes with an Excel Add-In that is supposed to make creating models easy easier, no code needed. Along with the “Solver Foundation for Excel Primer” document that is installed along with the binaries I figured Excel would be a good way to start looking into Solver Foundation.

After the MSI ran, I started Excel but didn’t find the Solver Foundation tab that’s advertised in the primer. The COM Add-Ins dialog said something about that the Add-In could not be loaded. Nice! Luckily the Event Viewer was more helpful in terms of error messages where I found this beauty of an exception:

Microsoft.VisualStudio.Tools.Applications.Runtime.CannotCreateCustomizationDomainException:
Customization could not be loaded because the application domain could not be created.
---> System.IO.FileLoadException: Could not load file or assembly 'MicrosoftSolverFoundationForExcel, Version=1.0.6.4890, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies.
The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

My first guess was that an old MSF assembly was referenced and I decided to go with an assembly binding redirect for excel.exe. Didn’t help. The next step was to get into the innards of VSTO deployment. What I found in the MicrosoftSolverFoundationForExcel.vsto and MicrosoftSolverFoundationForExcel.dll.manifest files wasn’t surpising: Several references to old versions of MSF. None of which were deployed by the MSI installer, so Excel trying to load such dependencies failed.

<assemblyIdentity name="MicrosoftSolverFoundationForExcel" version="1.0.8.6048"…
<assemblyIdentity name="MicrosoftSolverFoundationForExcel" version="1.0.6.4890"…

I updated both references to the match the installed version 2.0.2.8632, just to find myself faced with another error saying that the manifest’s digital signature is broken.

Now was time to contact my friend Lars Keller who is an expert in VSTO development. Lars told me that I would have to re-sign the .vsto and .manifest files to make the signature reflect my changes. The Office Development with Visual Studio blog has the full details.

  1. I had to create a certificate that can be used for code signing:
    makecert -r -pe -n "CN=Your Name" -b 01/01/2010 -e 01/01/2099 -eku 1.3.6.1.5.5.7.3.3 -ss My
  2. Export the certificate as a PFX file using certmgr.msc
  3. Create a backup copy of the MSF Excel Add-In .manifest and .vsto files
  4. Open a Visual Studio Command prompt and navigate to the manifest's location
  5. Make edits to the manifest file correcting the assembly versions of MicrosoftSolverFoundationForExcel to 2.0.2.8632
  6. Update the digital signatures for both the manifest and the VSTO file:
    mage.exe -update MicrosoftSolverFoundationForExcel.dll.manifest -CertFile <your-cert.pfx> -Password <cert-export-password>
    mage.exe -update MicrosoftSolverFoundationForExcel.vsto -appmanifest MicrosoftSolverFoundationForExcel.dll.manifest -CertFile <your-cert.pfx> -Password <cert-export-password>
  7. Restart Excel, the Solver Foundation tab should be on the ribbon

(Tested with Office 2010 beta.)

Rewriting Git History: Relocating Subversion URLs

Posted in .NET | Git at Thursday, June 25, 2009 8:59 PM W. Europe Daylight Time

Git LogoToday we changed the URL of our Subversion server at work to a new domain. Subversion and TortoiseSVN offer a separate relocate command for that, which basically updates the local working copy metadata.

Not so for Git. Git keeps SVN metadata in two places: the commit log messages themselves which hold a git-svn-id entry for all commits that have been pushed to SVN, and in the .git/config file.

commit e82751b4872142679ba61e26fc0c57e97c698e8f
Author: agross 
Date:   Thu Jun 25 16:44:55 2009 +0000

    Adding FxCop to the code quality task

    git-svn-id: https://your.svn-server/svn/Crimson/trunk@67 8ed4a44c-bfb4-4748-a28a-fad9255c4788
[core]
	repositoryformatversion = 0
	filemode = false
	bare = false
	logallrefupdates = true
	ignorecase = true
[svn-remote "svn"]
	url = https://your.svn-server/svn/Crimson/trunk
	fetch = :refs/remotes/git-svn

To update the SVN URL it’s required to update the Git configuration file (an easy edit) and also to rewrite the commit log messages, updating the values of git-svn-id to reflect the new SVN server URL. The latter can be achieved with the git-filter-branch command which allows you to dissect the project history in interesting ways.

Having several local Git repositories to update, I went for the scripted solution. I found this article on how to change the SVN repository URL and added some scripting goodness to it (aside from fixing the syntactic errors). It worked pretty good for my ~10 repositories.

  • You pass two arguments:
    • The old SVN URL, i.e. http://old.server
    • The new SVN URL, i.e. https://new.server
    • The old URL will be matched against git-svn-id entries with a regular expression, and the matched parts get replaced with the new URL.
  • Rewrite the commit log messages, thus updating git-svn-id
  • Create a backup copy of .git/config
  • Replace the old SVN URL in .git/config
  • Delete all metadata Git has aquired about SVN
  • Rebase against SVN, recreating the SVN metadata
#!/bin/sh

# Must be called with two command-line args.
# Example: git-svn-relocate.sh http://old.server https://new.server
if [ $# -ne 2 ]  
then
  echo "Please invoke this script with two command-line arguments (old and new SVN URLs)."
  exit $E_NO_ARGS
fi  

# Prepare URLs for regex search and replace.
oldUrl=`echo $1 | awk '{gsub("[\\\.]", "\\\\\\\&");print}'`
newUrl=`echo $2 | awk '{gsub("[\\\&]", "\\\\\\\&");print}'`

filter="sed \"s|^git-svn-id: $oldUrl|git-svn-id: $newUrl|g\""
git filter-branch --msg-filter "$filter" -- --all

sed -i.backup -e "s|$oldUrl|$newUrl|g" .git/config

rm -rf .git/svn
git svn rebase

Migrating SharePoint Content Databases To A New Farm While Keeping Security Settings

Posted in .NET | SharePoint | SQL Server at Saturday, April 25, 2009 4:40 PM W. Europe Daylight Time

The server this blog is hosted on was upgraded recently, i.e. is now run on a new dedicated server. Actually, next to this blog there’s a lot more going on. We, a bunch of geeks, are self-hosting mail, web sites, blogs and some collaboration tools like SharePoint (Windows SharePoint Services, in our case). Yeah, SharePoint, a true beast in and of itself. I can’t tell you how much I do not miss developing software for it and setting up customer sites.

I wanted to make the move to the new server as smooth as possible for our SharePoint users. Because we do not use Active Directory to authenticate our users, we obviously had to migrate the SharePoint user accounts manually. That is, re-create each user on the new server giving them a random password and communicate the change.

Moving a SharePoint site is surprisingly pretty well documented on TechNet, but won’t tell you about one important aspect: When you move the site to a new farm and the site does not use Active Directory, you will have to set up security anew.

Why? Because SharePoint matches user accounts by their SID, a value that is unique for each user account, even across machines: OLDMACHINE\foo’s SID is different from NEWMACHINE\foo’s SID. Burdening the four site collection administrator with this task is simply a no-go.

During my research how to work around that I found the Dustin Miller’s excellent post “Fix those SIDs”. It describes the process of massaging a SharePoint site collection database to replace old SIDs with the account SIDs of the current machine. I’ve extended it a bit, because I also decided to rename the SharePoint Search account while moving to the new server (note the extra REPLACE in line 11).

DECLARE @login nvarchar(255), @SystemId varbinary(512)

DECLARE curUsers CURSOR LOCAL FOR 
SELECT tp_Login, tp_SystemID FROM UserInfo WHERE tp_Deleted = 0

OPEN curUsers
FETCH NEXT FROM curUsers INTO @login, @systemid

WHILE @@FETCH_STATUS = 0
BEGIN
    DECLARE @newLoginName AS nvarchar(255) = REPLACE(REPLACE(@login, 'OLDMACHINE', 'NEWMACHINE'), 'spsearch', 'sharepoint-search')
    DECLARE @newSID varbinary(85) = SUSER_SID(@newLoginName)
    
    IF @newSID IS NOT NULL
    BEGIN
        PRINT 'Resetting user ' + @login + ' to new login ' + @newLoginName  + ' with SID '
        PRINT SUSER_SID(@newLoginName)

        UPDATE UserInfo
        SET    tp_SystemID = SUSER_SID(@newLoginName),
               tp_Login = @newLoginName
        WHERE CURRENT OF curUsers
    END
    
    FETCH NEXT FROM curUsers INTO @login, @systemid
END

CLOSE curUsers
DEALLOCATE curUsers
GO

After the script ran, take a look at the UserInfo table and SELECT rows that still contain OLDMACHINE in the tp_Login column. This helps you get a quick overview of what accounts have been missed during account re-creation.

As an extra step, I found it appropriate to update the site’s user entry as well (the account name that shows up in the site’s user list when no full name is given) to reflect the new machine name.

UPDATE    [AllUserData]
SET       [nvarchar1] = REPLACE(REPLACE([nvarchar1], 'OLDMACHINE', 'NEWMACHINE'), 'spsearch', 'sharepoint-search'),
          [nvarchar2] = REPLACE(REPLACE([nvarchar2], 'OLDMACHINE', 'NEWMACHINE'), 'spsearch', 'sharepoint-search'),
          [nvarchar3] = REPLACE(REPLACE([nvarchar3], 'OLDMACHINE', 'NEWMACHINE'), 'spsearch', 'sharepoint-search')

ChkDskAll ‒ ChkDsk For All Drives

Posted in .NET | Tools and Software | Windows at Saturday, February 14, 2009 4:41 PM W. Europe Standard Time

The Windows file systems (NTFS and FAT) are able to automatically detect if they are broken. You can even specify when that automatic check should be performed. But sometimes you would want to force a file system check, for example when Windows suddenly behaves strangely for no obvious reason. (For example last year, the day before I went on a month-long vacation, Vista suddenly refused to boot.)

In order to schedule a file system check for the next reboot you will have to

  1. Open an elevated command prompt or log in as an administrator,
  2. Run chkdsk <Drive>: /f,
  3. Rinse and repeat for all installed drives.

This task isn’t easy for inexperienced users, especially given that they might not know about the chkdsk command line tool in the first place. They could use the UI, but would have to repeat the process for each and every drive nonetheless.

Chkdsk UI

To make this task easier, I wrote a little .NET application that automates scheduling file system check for all drives at the next boot. Just double-click ChkDskAll.exe, enter administrative credentials and wait for the goodness to happen.

ChkDskAll In Action

If a drive has already been scheduled for scanning, it won’t be scheduled a second time. To exclude drives from being included in the scan, have a look at ChkdskAll.exe.config. For example, TrueCrypt drives should be excluded if you do not mount them as fixed drives.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>
        <!-- The list of excluded drives, e. g. "CDE". -->
        <add key="ExcludeDrives" value="YZ"/>
    </appSettings>
</configuration>
Page 1 of 2 in the NET category Next Page