Copying Files After a Successful Build With Robocopy on VS2010

The Problem
In one of the latest projects I’ve been working on, I needed to be able to interchange data providers. We decided to use Prism and MEF to load up the concrete instance of our IDataProvider at runtime, and created a separate project to contain the XML based implementation of that provider. Since we need a concrete instance to debug I wanted the latest .dll and .pdb of the XML data provider project to be copied into a Modules folder in the app’s output directory after it has successfully built. At first I thought I would use xcopy to copy the files, but after seeing that it has been deprecated, I switched to using Robocopy (which turned out to be just as easy). Once I figured what tool I would use to copy the files, I needed to figure out where to run the command from and I found 2 options.

Option 1: Project Post-build event
The quickest option I found was to enter the Robocopy command into the Post-build Event Command Line box in the project properties. Since Robocopy comes with Windows Vista and on you can open the Command Prompt and type robocopy /? to see everything that it is capable of. The command I used to copy the .dll and .pdb files was the following:
robocopy “$(TargetDir)\” “$(SolutionDir)\Application\$(OutDir)\Modules” $(TargetName).dll $(TargetName).pdb

With that command entered, I saved and then built the project, but the build was not successful and displayed an error staying robocopy exited with a code of 1. Wondering why I received this error, I went to the application’s output directory to find, to my surprise, that the Modules folder had been created and both the .dll and .pdb files had been copied successfully to that folder. Searching around for an answer I found this stackoverflow post explaining that unlike every other command line tool that returns a 0 when successful (which is what Visual Studio expects), robocopy returns a 1 when successful. So after adding a check to exit with a code of 0 if the error level was 1, it then built successfully.

Option 2: MSBuild Extension AfterBuild
On the stackoverflow post, mentioned above, there was an answer that recommended using the Robocopy task in the MSBuild Extension Pack as an AfterBuild target. I found this idea very intriguing (especially since it appeared to handle the return code of 1 issue) and attempted to use it to accomplish the same copying task. After a few hours of working with it I found that I could only get it functioning installing the MSBuild Extension Pack3.5 (even though I am on an x64 machine and building a .Net 4.0 project). I then edited my .csproj file and added the following code, which does the exact same thing as the post-build command, at the bottom of the file. After reloading and building the project, the files were copied to the Modules folder.

<Import Project="$(MSBuildExtensionsPath)\ExtensionPack\MSBuild.ExtensionPack.tasks"/>
<Target Name="AfterBuild">
	<ItemGroup>
		<OutputFiles Include="$(TargetName).dll"/>
		<OutputFiles Include="$(TargetName).pdb"/>
	</ItemGroup>
	<MSBuild.ExtensionPack.FileSystem.RoboCopy Source="$(TargetDir)\" Destination="$(SolutionDir)\Application\$(OutDir)\Modules" Files="@(OutputFiles)">
		<Output TaskParameter="ExitCode" PropertyName="Exit" />
		<Output TaskParameter="ReturnCode" PropertyName="Return" />
	</MSBuild.ExtensionPack.FileSystem.RoboCopy>
	<Message Text="ExitCode = $(Exit)"/>
	<Message Text="ReturnCode = $(Return)"/>
</Target>

The Decision
While Option 2 is very cool and clean looking, I decided to stick with Option 1 for the following reasons:

  1. Option 2 would require all the developers on the project to install the MSBuild Extension pack (not difficult at all but time consuming and annoying if your builds are failing and you didn’t know you needed the 3rd party pack)
  2. Writing the Post-build (Option 1) command was much quicker
  3. If any other developer is wondering how the files are being copied into the Modules folder (or needs to change it), with Option 1 they can quickly and easily look at (and change) the Post-build event in the properties window, but with Option 2 they have to know to go edit the .csproj file and then search it to find the AfterBuild target code

Installer Woes-Installing Dependencies

For the last week I have been working with a user of Informant to help them get the application installed. It seemed like they had all of the prerequisites and were following all of the correct installation steps. Today I finally had RECESS time to devote to this. After finding an unused laptop and installing a fresh copy of Win7 (no SP1) and .NET Framework 4 Client Profile, I found that Informant failed to install. This was a surprise to me, but decided to see if installing .NET 4 Extended Profile would solve the problem. This solved the problem. My coworker Travis Schilling proceeded to help me get the Informant installer to require the .NET 4 Framework Extended Profile. I then refreshed my dependencies for the Installer project. This caused one of the common libraries to move into its default location. The library was originally moved in order to make use of Probing Paths. To fix this problem I only needed to move the library into the correct folder again. I have now released Informant v0.1.6.0 with the fixed installer.

How to force the dependency:

  1. Right-click the Installer project
  2. Select Properties
  3. In the Properties window click the button Prerequisites…
  4. Check all of the correct prerequisites for your application
  5. Click OK
  6. Click Apply then OK
  7. Expand the Installer project
  8. Expand Detected Dependencies
  9. Double-click Microsoft .NET Framework
  10. In the Properties pane change the Version value to .NET Framework 4
  11. Fix the location of any common libraries that may have been moved in the installer package

Remote Debugging from Visual Studio 2010

In my latest project I was running into an issue where running my installed application on a test machine was crashing before it could even startup, but it ran perfectly when installed on my machine. I was almost to the point of taking the time to install Visual Studio 2010 on the test machine, when my coworker, Bryan Coon, reminded me of the Remote Debugging capabilities of VS and recommended trying that first.

I started off using Danny Warren’s Remote Debugging post to get both my machine(on domain) and the test machine(off domain) enabled so that I could Attach to Process (Ctrl+Alt+P) from VS 2010 on my machine. Here are the main points that I gathered from it:

  • 3 instances of the same username needed to exist as administrators (and have been logged into at least once)
    1. The domain username on my machine (domain\travis). This is the username that Visual Studio is run under.
    2. The machine username on my machine (MyMachine\travis)
    3. The machine username on the test machine (TestMachine\travis). This is the username that the remote application is run under.
  • The Visual Studio 2010 Remote Debugging Monitor needed to be installed on the test machine
    • Use the setup program that matches the OS (x86, x64, ia64)
    • I ran the application instead of setting it up as a service, so I needed to make sure it ran as an administrator
  • Everything from the bin\Debug folder of the application must be copied to the test machine.

Once the Remote Debugging Monitor was started, I was able to view all the running processes in VS by entering the name of the server that the Remote Debugging Monitor started (travis@TestMachine) into the Qualifier box.

In most cases this would have allowed me to then attach to my running application and hit debug points. My application, however, crashed before the application even became available in the list of available processes.

So the next step was to get Visual Studio 2010 configured on my machine to start the application on the remote (test) machine when I started the application with debugging (F5). I found what was needed here. All that was required was to modify the following properties in the Debug section of the application properties screen:

  • Select Start external program and specify the path to the application on the remote computer
  • Check Use remote machine and specify the remote machine

The gotcha I ran into was that again the remote machine name is the server name that the Remote Debugging Monitor started not the actual machine name.

With these final steps completed I was able to start the application with debugging and immediately found my issue. While this process took a little bit of time to setup, it saved a bunch of time that would have been spent installing Visual Studio 2010 and allowed me to keep the test machine clean of all developer tools. So if I run into an issue like this again I will definitely think to try Remote Debugging right away.

No more IIS7 WCF REST 404 Error!

Recently I’ve been trying to host a WCF REST .NET 4.0 service in IIS7. I downloaded the template for VS2010 used for creating REST services as explained here. Running the sample application found on that website worked fine from VS2010. I then switched to hosting the service in IIS7. The result however was a 404 error, not exactly what I was hoping for. My coworker Dan Hanan tried the same thing on his machine with complete success. We looked at the service configuration, IIS7 settings, among other obscure settings without success. Google wasn’t especially helpful since most of the results kept saying things like “add an *.svc file” (which is not required/used in .NET 4.0 REST services), others mentioned changing an IIS7 handler mapping so that the *.svc file would not be required, but none of these solutions helped. Tracing didn’t help me get any closer either.

Still the problem felt like a server issue, so I tried to narrow the search. I eventually came across this blog. There was a link to a question on the MSDN forums that mentions a handler mapping named “svc-Integrated-4.0”. When I looked at my handler mappings in IIS7 it did not contain that mapping. The last post on that question contained a link to the MSDN post One-Time Setup Procedure for the Windows Communication Foundation Samples explaining some steps that need to be taken in order to use the .NET 4.0 WCF services in IIS7. When I tried to run the aspnet_regiss and ServiceModelReg.exe commands explained in the post I only ran into more errors.

Frustrated I talked to my coworker Travis Schilling to see if he had any ideas and to see if his IIS7 contained the mapping. His IIS7 did contain the mapping and he was pretty sure it was installed by VS2010. After a little discussion we decided it would be best to do a repair install of VS2010. After the repair installation the mapping showed up in IIS7 and the REST service ran as expected. I’m not sure why the handler mapping wasn’t installed before, I can only assume it’s because I installed VS2010 before I installed IIS7.

Up and Running with GIT and Visual Studio

This is just a quick guide for those on windows using Visual Studio and wanting to start tinkering with GIT. If you want to know why Git is better than (Insert source control management system here), click this link. Or, if you more in the mood to hear why every other source control system in the world sucks, check out this video from Linus Torvalds who wrote GIT.

First, Git is new as of a few years ago and so the tooling support isn’t phenomenal. That being said, you need to start with by installing msysgit:

Obviously, windows version, download, install, all that good stuff. At this point, you could start using Git as this will install the windows command line tools to do so. However, a command line doesn’t completely cut it for me, and if your reading this, your probably not interested in what I’m writing anyways, so why are you here?

Moving on.

Now that the Git command line tools are installed, You’ll want to install GitExtentions, available here:

This will install tooling support into Visual Studio and also install windows explorer shell extensions and puts a few things into the explorer. Once you run it, you’ll quickly notice that your probably missing a diff tool. You can either install KDiff3 or your own diffing tool. Your preference. If you also don’t have a good text editor (Notepad doesn’t count) I recommend also getting Notepad++ and installing that as well.

Go into settings, and setup your settings to look something like this:

You now have GIT installed. Congratulations!

Now what?

Git 101.

Ok, I’m going to assume you’ve already had some experience with a source control management system of some kind or another (svn, tfs, etc…) before I jump into this. First, everything is local. When you start adding other people or services like GitHub, you realize that your local repository is a branch, and merging involves pulling in changes from other branches, but I digress.

Lets start off with a simple hello world project. Go into visual studio, create a new console project, give it a directory and start it up. Now, to create the repository find this little bar and click on the little folder icon that says ‘browse repository’. (Alternatively, you can simply directly select ‘Create new repository’ from the Git menu in visual studio)

Which will open this:

,

From here, select create new repository, if you allowed Visual Studio to create a directory for your project you’ll want to create the repository one directory down since every file in that directory and any sub directory (besides any listed in the .gitignore file) will be source controlled.

On the next page, I recommend clicking on ‘Edit .gitignore’ and copy the recommended list (this will cause git to ignore any files or directories that match this list).

You now have a repository, well on your way to rocking a Git controlled project. Finally, committing files. So go in make your project spit out hello world to the console, and hit commit. You’ll have the following window:

Select all the files in the Working Directory window, click stage, enter a commit message, hit commit, ok, and done! You’ve now made your first commit.

Now, this is something I didn’t understand right off the bat, when you open up this window everything that is different is listed in the working directory changes window, anything that has changed or is different from the previous version that isn’t in the .gitignore file. Now, to commit something, you ‘stage it’ which takes the current version of whatever file you select and puts it in the staging area (this allows you to make sure your only committing what you want to commit, because there’s many cases where you want to break up your commits into subsets of the entire change list) and commit will only commit those files that are in the staging area. If you go back to the ‘browse repository’ you’ll see something like this (I’ve added several commits):

There’s a lot more I could get into, and I may at some point, but this ought to get you on your way, feel free to leave questions in the comments, tell me where something in this post is wrong or outdated and so on.

Happy Git’ing