views:

124

answers:

1

I have a project in my solution which started life as a C# library project. It's got nothing of any interest in it in terms of code, it is merely used as a dependency in the other projects in my solution in order to ensure that it is built first. One of the side-effects of building this project is that a shared AssemblyInfo.cs is created which contains the version number in use by the other projects.

I have done this by adding the following to the .csproj file:

<ItemGroup>
  <None Include="Properties\AssemblyInfo.Shared.cs.in" />
  <Compile Include="Properties\AssemblyInfo.Shared.cs" />
  <None Include="VersionInfo.targets" />
</ItemGroup>
<Import Project="$(ProjectDir)VersionInfo.targets" />
<Target Name="BeforeBuild" DependsOnTargets="UpdateSharedAssemblyInfo" />

The referenced file, VersionInfo.targets, contains the following:

<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;
  <PropertyGroup>
    <!--
      Some properties defining tool locations and the name of the
      AssemblyInfo.Shared.cs.in file etc.
    -->
  </PropertyGroup>
  <Target Name="UpdateSharedAssemblyInfo">
    <!--
      Uses the Exec task to run one of the tools to generate
      AssemblyInfo.Shared.cs based on the location of AssemblyInfo.Shared.cs.in
      and some of the other properties.
    -->
  </Target>
</Project>

The contents of the VersionInfo.targets file could simply be embedded within the .csproj file but it is external because I am trying to turn all of this into a project template. I want the users of the template to be able to add the new project to the solution, edit the VersionInfo.targets file, and run the build.

The problem is that modifying and saving the VersionInfo.targets file and rebuilding the solution has no effect - the project file uses the values from the .targets file as they were when the project was opened. Even unloading and reloading the project has no effect. In order to get the new values, I need to close Visual Studio and reopen it (or reload the solution).

How can I set this up so that the configuration is external to the .csproj file and not cached between builds?

+1  A: 

As far as I know, you can't. Visual Studio is not using 'real' MSBuild, it uses an internal build engine that behaves very similar to MSBuild.exe, but still have some subtle differences. This build engine caches the targets, so you have to restart VS once you change something. I believe, it is even documented somewhere, and there is no known workaround (I searched for it about a year ago and found nothing).

You could possibly force the VS to reload the targets via VS API - so, you'll have to create (or find) a custom add-on to do this.

Another option is to use something other than .targets file to store your configuration. For instance, you could use a plain text file and parse it with MSBuild (not that elegant, but it should work).

Upd.

That's what I did some time ago. MSBuild calls an external tool via Exec with WorkingDirectory="$(SolutionDir)", the tool "knows" all the conventions about file names, locations etc., so a working directory is enough to get the job done. Miscellaneous configuration data is stored in the external tool's config, so no problems with caching.

Also, have a look at this question about reading items from a file. I suppose, that better suites your needs.

VladV
Thanks, @VladV. The external config option sounds like a possibility. I'm a complete MSBuild newbie though - could you recommend some reference material for reading properties from external files?
Damian Powell
MSBuild Reference at MSDN: http://msdn.microsoft.com/en-us/library/0k6kkbsd.aspx. MSBuild Community Tasks (some useful extensions to MSBuild): http://msbuildtasks.tigris.org/.
VladV
I have implemented a kind of dependency resolver for MSBuild and it used some external configuration, but I don't have the code at hand right now. I'll try to find some examples for you in a few hours.
VladV
Cool. Thanks, @VladV.
Damian Powell
Sorry, I wasn't able to look at the stuff yesterday. Just updated my answer.
VladV