Tuesday, August 26, 2008
« Repairing TFS's Team Explorer Build Node... | Main | Registering Design-Time Changes Programm... »

Earlier this year I posted an article demonstrating how to use the SGEN.exe utility to generate a serialization assembly.  The article identified how to create a custom MSBuild task by editing the project file (e.g., csproj).  I've recently come to discover that the MSBuild task will fail when automating a build of the project through TFS Build.  The error presents itself as follows:

SGEN(0,0): error : File or assembly name 'C:....\bin\CustomLibrary.dll', or one of its dependencies, was not found.

Ultimately, the root of the problem goes back to the SGEN MSBuild task's usage of the $(OutputPath) variable.  Even in TFS Build this is pointing to same location that Visual Studio would point to.  TFS, however, will override the output locations of the compiled applications, but this variable doesn't get updated.  As stated in the MSDN documentation, "OutputPath has been deprecated and OutDir should be used instead whenever possible.".  I was happy to discover that by simply replacing the $(OutputPath) with $(OutDir) in the MSBuild task was all I needed to do; the task will execute properly both from my development machine as well as the build server.

My updated task resembles the following:

<Target Name="GenSerializationAssembly"
        DependsOnTargets="AssignTargetPaths;Compile;ResolveKeySource"
        Inputs="$(MSBuildAllProjects);@(IntermediateAssembly)"
        Outputs="$(OutDir)$(_SGenDllName)">
  <SGen BuildAssemblyName="$(TargetFileName)"
        BuildAssemblyPath="$(OutDir)"
        References="@(ReferencePath)"
        ShouldGenerateSerializer="true"
        UseProxyTypes="false"
        KeyContainer="$(KeyContainerName)"
        KeyFile="$(KeyOriginatorFile)"
        DelaySign="$(DelaySign)"
        ToolPath="$(SGenToolPath)">
    <Output TaskParameter="SerializationAssembly" ItemName="SerializationAssembly" />
  </SGen>
</Target>
<Target Name="AfterBuild" DependsOnTargets="GenSerializationAssembly" />

Tuesday, June 16, 2009 1:09:34 PM (Mountain Standard Time, UTC-07:00)
This was really helpful to me. Thanks!
Steve Sheldon
Friday, August 14, 2009 12:13:48 PM (Mountain Standard Time, UTC-07:00)
I've started using the SGen task recently, and I ran into a rather odd bug. It seems that if you have any references that are contained in a directory with a comma in it (In this case I'm using LEADTools, which installs its SDK to "C:\Program Files\Lead Technologies, Inc" by default), then the SGEN command line treats this as two different references and of course fails. Whoops.

Can anybody think of a way (aside from re-installing LEAD to a non-comma directory, which I am trying to avoid due to the effort involved in re-setting all of our dev boxes) to get SGen to escape the comma or something similar? I tried creating a shortcut that pointed to the name with the comma and just calling it "LEAD", but alas, shortcuts do not work like UNIX symbolic links, so Visual Studio just resolved it back to the full name. I may have to bite the bullet and install it somewhere else, or reference a network copy or some such. Oh well.
Mike Loux
Comments are closed.