Posted by Stuart Preston on May 18, 2010 under Development Practices, Visual Studio |
This post generated some interest on a discussion list so I’m re-posting here on my blog. Cutting a longer story short, the original poster wanted a way to start a process as Network Service rather than as the current Windows identity to mitigate the risk that you have more rights than you should have.
For those who have tried to use “runas” to achieve this you are left with the rather bleak message: “RUNAS ERROR: Unable to acquire user password”.

I’ll skip the reasons for this and go straight onto the solution. Create a dummy service using the Service Manager (sc.exe). This launches the application in the right session and is allowed to run as Network Service or even Local System (NT Authority\Local System).
@echo off
sc delete NetworkServiceCmd >nul:
sc create NetworkServiceCmd binpath= “cmd /K start c:\neverendingapp.exe” obj= “NT Authority\Network Service” >nul:
sc start NetworkServiceCmd >nul:
sc delete NetworkServiceCmd >nul:
Simply drop the above into a batch file and run it. You can then use “Attach to Process” in Visual Studio to attach to the process (don’t forget that your PDB’s must be in the same location as the assembly).

Here’s a screenshot of the debugger attached to my “NeverEndingApp” and viewing the current identity.

You need to manually kill off the process you started, you can use Task Manager as usual or here’s a macro I use that works in my scenario. You can attach this to a Keyboard Shortcut or even a Toolbar.
Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports EnvDTE90a
Imports EnvDTE100
Imports System.Diagnostics
Public Module TerminateProcess
Public Function TerminateProcess()
Dim processes As EnvDTE.Processes = DTE.Debugger.LocalProcesses
Dim process As EnvDTE.Process
For Each process In processes
If (process.Name.ToLower().Contains(“neverendingapp.exe”)) Then
process.Terminate(True)
End If
Next
End Function
End Module
I’m certain all the above can be improved on but I think all the basics are in here and customising it for your process is a challenge I’ll leave to the reader!
Posted by Stuart Preston on May 2, 2010 under Team Foundation Server |
There are many more sophisticated ways of achieving this but none seemed to give me exactly what I wanted, so here I present yet another way of doing assembly versioning with Team Build 2010. I wanted my Team Build number to exactly match that of my assembly versions (and not be derived), like this:

So here’s how I do it. To start off with I customise the BuildNumber format within my build definition:

In my case, I decided to customise it so that the Major and Minor version numbers “0.1” were added explicitly. This lets me control the first two parts of the version number which is what I want to achieve. I also added the macros $(Month)$(DayOfMonth) with a 1 in front of it. For the 2nd May 2010 this would generate a number 10502. (The reason I don’t use the full year here is that for today it would generate a build number of 100502 and a file version number cannot be higher than 65335).
When I decide to work on version 0.2, 0.3 or 1.0 all I have to do is increment the Build Number here and save the definition, I’m also happy to increment the number when the year changes. I said it was simple!
The final part of the build number format was left as-is (i.e. the Revision number that increments by 1 with each build on that day and resets for the next day).
Now all we need to do is retrieve this version number when MSBuild is run against the solution, split the version number and take the numeric portion into the Properties\AssemblyVersion.cs file (you will need to comment out the AssemblyFileVersion line in that file first and check it in).
Here’s the fragment that you’ll need to insert in your .csproj file (you’ll have to check it out then open it in Notepad or your favourite text editor).
<UsingTask
TaskName="Microsoft.TeamFoundation.Build.Tasks.GetBuildProperties"
AssemblyFile="$(MSBuildProgramFiles32)\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\Microsoft.TeamFoundation.Build.ProcessComponents.dll"
Condition="' $(BuildUri) '!=' '"/>
<Target Name="BeforeBuild" Condition="' $(BuildUri) '!=' '">
<GetBuildProperties TeamFoundationServerUrl="$(TeamFoundationServerUrl)" BuildUri="$(BuildUri)">
<Output TaskParameter="BuildNumber" PropertyName="BuildNumber" />
</GetBuildProperties>
<PropertyGroup>
<BuildNumberSplitLocation>$([MSBuild]::Add($(BuildNumber.LastIndexOf('_')),1))</BuildNumberSplitLocation>
</PropertyGroup>
<ItemGroup>
<AssemblyVersionLines Include="[assembly:AssemblyFileVersion("$(BuildNumber.Substring($(BuildNumberSplitLocation)))")]" />
</ItemGroup>
<Exec Command="attrib -r "$(ProjectDir)\Properties\AssemblyInfo.cs"" ContinueOnError="false" />
<Message Text="Lines being added: @(AssemblyVersionLines)" Importance="high" />
<WriteLinesToFile File="$(ProjectDir)\Properties\AssemblyInfo.cs" Lines="@(AssemblyVersionLines)" />
</Target>