BHT0001 with MSBuild/TeamBuild

Topics: Developer Forum
Mar 19, 2009 at 4:16 PM
Hello,
I'm trying to integrate my documentation build in my teambuild script but i have the following warning (same with msbuild):

"BHT0001: Unable to get executing project: Unable to obtain internal reference. The specified project will be loaded but command line property overrides will be ignored."

Since i'm using command line parameters to override HelpTitle and OutputPath i'm stuck.

I've seen there's already a workitem 21197 but i need to know if there's a workaround ?

Thanks
Guillaume
Coordinator
Mar 19, 2009 at 8:12 PM
There isn't a workaround right now.  The issue will be fixed in the next release.

Eric
Mar 20, 2009 at 1:00 PM
Thanks for the answer.
Any ETA on next release ? :-)

Guillaume
Coordinator
Mar 20, 2009 at 4:02 PM
It'll be out in a couple of weeks.

Eric
Apr 2, 2009 at 9:26 PM

I have a temporary solution that I am using for this problem which involves using <exec> task and and an msbuild response file.
I added the following  to my common targets to build Sandcastle help documentation.  The SandcastleDocsToBuild is specific to my build but the MakeSandcastleDoc target could be somewhat generic. 
Note the use of %22 for quotes.  Paths with spaces should be quoted (although quoting them for properties used within the .shfbproj file doesn't always work [workitem:21905])
The line            <ResponseFileLines Condition="'@(TCustomProperties)'!=''" Include="/p:%(TCustomProperties.Identity)" />
is used to break multiple semicolon separated properties into lines that start with /p:.
- Dick


<ItemGroup>
    <
SandcastleDocsToBuild Include="$(SolutionRoot)\BuildScripts\Corvus\*.shfbproj">
        <
Configuration>Release</Configuration>
        <
Properties>sourceFilePath=&quot;$(BinariesRoot)\Release\&quot;;test=value</Properties>
        <
OutputPath>$(DeploymentTargetPath)Documentation\DevGuide</OutputPath>
    </
SandcastleDocsToBuild>
</
ItemGroup>

<Target Name="MakeSandcastleDocs" 
            Condition="'$(SkipSandcastleDocs)'!='true' and '@(SandcastleDocsToBuild)'!=''" 
            Outputs="%(SandcastleDocsToBuild.Identity)">
    <
Time Format="MMMM dd, yyyy hh:mm:ss">
          <
Output TaskParameter="FormattedTime" PropertyName="FormattedTimeStamp" />
    </
Time>

 

    <

PropertyGroup>
            <
SandcastleOutputPath Condition="'%(SandcastleDocsToBuild.OutputPath)'!=''">%(SandcastleDocsToBuild.OutputPath)</SandcastleOutputPath>
            <
SandcastleOutputPath Condition="'$(SandcastleOutputPath)'==''">$(MSBuildProjectDirectory)..\Documentation\%(SandcastleDocsToBuild.Filename)</SandcastleOutputPath>
            <
HelpFileVersion Condition="'$(OBuildVersion)'!=''">HelpFileVersion=$(OBuildVersion);</HelpFileVersion>
            <
FooterText Condition="'$(OBuildVersion)'!=''">FooterText=%22$(OBuildVersion)- $(FormattedTimeStamp)%22;</FooterText>
            <
DocConfigurationToBuild Condition="'%(SandcastleDocsToBuild.Configuration)'!=''">%(SandcastleDocsToBuild.Configuration)</DocConfigurationToBuild>
            <
DocConfigurationToBuild Condition="'$(DocConfigurationToBuild)'==''">Release</DocConfigurationToBuild>
            <
CustomProperties Condition="'%(SandcastleDocsToBuild.Properties)'!=''">%(SandcastleDocsToBuild.Properties);</CustomProperties>
    </
PropertyGroup>

 

<!--

Workaround for failure to pass properties correctly to Sandcastle utilities-->
    <
PropertyGroup>
          <
ResponseFileName>%(SandcastleDocsToBuild.FullPath).rsp</ResponseFileName>
          <
SCTBWorkingDirectory>@(SandcastleDocsToBuild->'%(RootDir)%(Directory)')</SCTBWorkingDirectory>
    </
PropertyGroup>

    <
ItemGroup>
           <
TCustomProperties Condition="'$(CustomProperties)'!=''" Include="$(CustomProperties)" />
    </
ItemGroup>
    <
ItemGroup>
           <
ResponseFileLines Include="%22%(SandcastleDocsToBuild.Identity)%22"/>
           <
ResponseFileLines Include="/p:Configuration=$(DocConfigurationToBuild)"/>
           <
ResponseFileLines Include="/p:OutputPath=%22$(SandcastleOutputPath)%22"/>
           <
ResponseFileLines Condition="'$(HelpFileVersion)'!=''" Include="/p:$(HelpFileVersion)"/>
           <
ResponseFileLines Condition="'$(FooterText)'!=''" Include="/p:$(FooterText)"/>
           <
ResponseFileLines Condition="'@(TCustomProperties)'!=''" Include="/p:%(TCustomProperties.Identity)" />
    </
ItemGroup>
    <
WriteLinesToFile File="$(ResponseFileName)"
                                      Lines="@(ResponseFileLines)"
                                     Overwrite="true" />
     <
Exec Command="msbuild %40%22$(ResponseFileName)%22" WorkingDirectory="$(SCTBWorkingDirectory)" />

 

<!--

DISABLED FOR WORKAROUND - REENABLE WHEN THE PROCESS IS FIXED

 

<MSBuild Projects="%(SandcastleDocsToBuild.Identity)"

Properties="Configuration=$(DocConfigurationToBuild);OutputPath=$(SandcastleOutputPath);$(HelpFileVersion)$(FooterText)$(CustomProperties)" />

 

-->

 

</

Target>

 

Jul 30, 2009 at 3:08 PM

Just a followup here. 

I have downloaded and installed release 1.8.0.2 (it's only been available since June 1) and confirmed that the BHT0001 error has been corrected.  The workaround that I created is no longer necessary.

Dick

May 14, 2010 at 4:10 PM

Hello all,

I'm using release 1.8.0.3 with MSBuild 4.0.30319.1 (VS2010 final) and I'm seeing this same error. Are there any suggestions for workaround or resolution?

Thanks,

Sam

Coordinator
May 14, 2010 at 8:23 PM

The build tasks in SHFB are built against MSBuild 3.5 and they have not been tested with MSBuild 4.0.  Most likely it will build the help project but any property overrides specified on the command line will be ignored.  Use MSBuild 3.5 to build the SHFB project.  You may need to use an Exec task to execute MSBuild 3.5 if it's nested within another project file.

Eric

 

May 14, 2010 at 10:27 PM

Hi Eric,

Thanks for your reply. I have done some more digging - it is just as you say. The help project gets built OK with MSBuild 4.0 but the overrides are ignored - and of course the warning message is generated. I stepped through the source to find where things were going wrong. For now, it's no problem for me to use MSBuild 3.5 instead, and that's all working fine.

Cheers,

Sam

Jun 2, 2010 at 9:36 AM
Edited Jun 2, 2010 at 9:37 AM

Hi Eric,

As far as I can see the reason .shfbproj can only be compiled reliably in .NET 3.5 is due to a reflection call to get the current MSBuild project inside the BuildHelp task in order to be able to pass command line parameters and correctly handle property overrides.

Actually, I am not sure this reflection call is the right thing to do. MSBuild already can handle the command line parameters and associated property overrides for you – given the build process is actually driven by MSBuild. From what I have seen the build process is driven by manually loading and analyzing the MSBuild project using the MSBuild object model inside of the SandcastleProject class. At least that is what the BuildHelp task does.

If you would have implemented the build process completely in MSBuild by providing a couple of low-level MSBuild tasks and chaining them together in the SandcastleHelpFileBuilder.targets file the whole problem would disappear and one could probably build .shfbproj files with MSBuild 4.0 just fine.

Do you have any plans to fix this in future releases?

Best,
Immo

Coordinator
Jun 2, 2010 at 9:22 PM

I have no plans to rewrite the entire build process anytime soon.  It would be no small task and, the reflection issue aside, is working fine as it is.  There are also a number of advantages related to managing the project and building sub-projects that would be lost if it were switched to a purely MSBuild-based implementation.  MSBuild 4.0 appears to expose a global public collection containing the currently loaded projects so, once compiled for use under .NET 4.0, I can probably use that rather than reflection and everything else can remain the same.

Eric

 

Jun 6, 2010 at 7:03 PM

Hi Eric,

I did not know that things are changing with MSBuild 4.0. If that is the case leaving the build process as is pobably makes more sense.

-Immo

Jun 10, 2010 at 2:17 AM

I'm hitting this issue using TFS Build 2010. I don't think I have a choice but to use MSBuild 4.0.

Eric, you seem to indicate that there will be a fix to get this working with MSBuild 4.0. Are there any details? I don't really want to fall down to the EXEC with a response file workaround as I'm using the workflow support in TFS Build 2010.

Jun 10, 2010 at 2:37 AM

This is my build log for running under TFS Build 2010.

Built $/Sandpit/MyCompany.Sandpit/Solution Items/MyCompany.Sandpit.shfbproj for default targets.
 SHFB: Unable to get executing project: Unable to obtain internal reference.  The specified project will be loaded but command line property overrides will be ignored.
MSBuild Log File
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe /nologo /noconsolelogger "C:\Builds\1\Sandpit\MyCompany.Sandpit\3\Sources\Sandpit\Solution Items\MyCompany.Sandpit.shfbproj" /m:1 /fl /flp:"logfile=C:\Builds\1\Sandpit\MyCompany.Sandpit\3\Sources\Sandpit\Solution Items\MyCompany.Sandpit.log;encoding=Unicode;verbosity=diagnostic" /p:SkipInvalidConfigurations=true  /p:OutDir="C:\Builds\1\Sandpit\MyCompany.Sandpit\3\Binaries\\" /p:Configuration="Release" /p:Platform="Any CPU" /p:VCBuildOverride="C:\Builds\1\Sandpit\MyCompany.Sandpit\3\Sources\Sandpit\Solution Items\MyCompany.Sandpit.shfbproj.Any CPU.Release.vsprops"  /dl:WorkflowCentralLogger,"C:\Program Files\Microsoft Team Foundation Server 2010\Tools\Microsoft.TeamFoundation.Build.Server.Logger.dll";"Verbosity=Diagnostic;BuildUri=vstfs:///Build/Build/162;InformationNodeId=31752;TargetsNotLogged=GetNativeManifest,GetCopyToOutputDirectoryItems,GetTargetPath;TFSUrl=http://tfs-server:8080/tfs/MyCompany;"*WorkflowForwardingLogger,"C:\Program Files\Microsoft Team Foundation Server 2010\Tools\Microsoft.TeamFoundation.Build.Server.Logger.dll";"Verbosity=Diagnostic;"

When it says "command line property overrides will be ignored", I was assuming that to mean custom overrides like help title. It seems that the OutDir value is also being wiped out because the documentation is compiling to C:\Builds\1\Sandpit\MyCompany.Sandpit\3\Sources\Sandpit\Solution Items\Help rather than C:\Builds\1\Sandpit\MyCompany.Sandpit\3\Binaries\Help.

Coordinator
Jun 10, 2010 at 3:02 AM

Since the MSBuild API has changed and the VS 2010 project files include new attributes that MSBuild 3.5 cannot load, I'll most likely release two version of the next SHFB release.  One will be built under .NET 3.5 as it currently is and the other will be built under .NET 4.0 which will work with MSBuild 4.0 and will also be able to load the new MSBuild 4.0 project files created by VS 2010.  Since .NET 4.0 is relatively new, I'm not ready to force everyone to install .NET 4.0 just to run SHFB.  If Sandcastle itself requires .NET 4.0 that would change but, as far as I know, it won't since the CCI engine that it uses can handle parsing assemblies compiled under different framework versions.

Eric

 

Jun 10, 2010 at 9:30 AM
rprimrose wrote:

I don't really want to fall down to the EXEC with a response file workaround as I'm using the workflow support in TFS Build 2010.

 If the response file is your only concern, you can simply use the Exec task with the appropriate command line:

<Exec Command="&quot;$(windir)\Microsoft.NET\Framework\v3.5\MSBuild.exe&quot; &quot;@(ShfbProj)&quot; /p:OutputPath=&quot;$(HelpDir)WiX&quot; /p:HelpFileVersion=&quot;$(HelpVersion)&quot;" />

This does not look too nice, but at least it will work and does not need any additional files written to disk.

Jul 8, 2010 at 6:42 AM

Hi Eric,

I feel bad asking this question after your quick response today to a problem with the latest release, and I don't want to pressure you.

I still have the BHT0001 error when using MsBuild 4.0. Do you have any ETA on when you might release a version of SHFB built against .NET 4.0?

Thanks,

Trevor

Coordinator
Jul 8, 2010 at 4:06 PM

I ran out of time this past weekend so I'll probably take a look at it this coming weekend.

Eric

 

Jul 26, 2010 at 5:44 PM

Any new version that works with TFS 2010 coming soon?

Coordinator
Jul 26, 2010 at 8:52 PM

I don't currently have an estimate of when I will have a .NET 4.0 specific version out.  The MSBuild 4.0 build engine was completely reimplemented.  As such, it's not just the build task that is affected but all of the project management code and the code related to loading and parsing solutions and projects as documentation sources.  I have a version that works for the most part but I still have some testing to do.  The Exec task method noted above can be used as a workaround.

Eric

 

Aug 2, 2010 at 1:18 AM

Nice to hear you have a version that works for the most part. Any chance you can share a version, or do you have an ETA on it's availablity?

Aug 9, 2010 at 4:06 PM

(bump)

Aug 9, 2010 at 4:46 PM
Edited Aug 9, 2010 at 4:47 PM

Hi Allen,

Please do not take this as an offense, but honestly: what do you expect Eric to say other than "I don't currently have an estimate of when I will have a .NET 4.0 specific version out"? Besides, the workaround I proposed above works fine for me. Sure it is not nice, but since it works I do not see a strong need to urge Eric to release full support for MSBuild 4.

-Immo

Coordinator
Aug 9, 2010 at 8:49 PM

There are still some issues to fix up with MSBuild 4.0 project support.  Until everything is working as expected as compared to the current version, it's not ready for release, alpha or otherwise.

Eric

 

Aug 12, 2010 at 3:34 PM

Looking forward to a fix. Thanks for your hard work.

Aug 25, 2010 at 11:09 AM

Just a small update on a more generic command line:

<Exec Command="&quot;$([MSBuild]::GetRegistryValue('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\3.5', 'MSBuildToolsPath'))MSBuild.exe&quot; &quot;@(ShfbProj)&quot; /p:OutputPath=&quot;$(HelpDir)WiX&quot; /p:HelpFileVersion=&quot;$(HelpVersion)&quot;" />

  

 

Oct 2, 2010 at 10:50 PM

If your help project is already configured, all you need is:

<Exec Command="&quot;$(windir)\Microsoft.NET\Framework\v3.5\MSBuild.exe&quot; MyProject.shfbproj" />

Thanks!

Apr 1, 2011 at 9:17 PM

Well, I'm currently trying to compile using msbuild following instructions of http://broadcast.oreilly.com/2010/09/build-html-documentation-for-y.html, I got the following error in VS2008. Could you help me out?

From *.shfbproj, I setup to .Net3.5, but no success. 

Thank you,

C:\CVS\SandCastle_Examples>msbuild Guy.shfbprojMicrosoft (R) Build Engine Version 3.5.30729.4926[Microsoft .NET Framework, Version 2.0.50727.4952]Copyright (C) Microsoft Corporation 2007. All rights reserved.
Build started 4/1/2011 1:08:34 PM.Project "C:\CVS\SandCastle_Examples\Guy.shfbproj" on node 0 (default targets).Project file contains ToolsVersion="4.0", which is not supported by this version of MSBuild. Treating the project as if it had ToolsVersion="3.5".c:\Program Files (x86)\EWSoftware\Sandcastle Help File Builder\SandcastleHelpFileBuilder.targets(23,5): error MSB4062:The "SandcastleBuilder.Utils.MSBuild.BuildHelp" task could not be loaded from the assembly c:\Program Files (x86)\EWSoftware\Sandcastle Help File Builder\SandcastleBuilder.Utils.dll. Could not load file or assembly 'file:///c:\Program Files (x86)\EWSoftware\Sandcastle Help File Builder\SandcastleBuilder.Utils.dll' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded. Confirm that the <UsingTask> declaration is correct, and that the assembly and all its dependencies are available.Done Building Project "C:\CVS\SandCastle_Examples\Guy.shfbproj" (default targets) -- FAILED.

Build FAILED.
"C:\CVS\SandCastle_Examples\Guy.shfbproj" (default target) (1) ->(CoreBuildHelp target) ->  c:\Program Files (x86)\EWSoftware\Sandcastle Help File Builder\SandcastleHelpFileBuilder.targets(23,5): error MSB4062: The "SandcastleBuilder.Utils.MSBuild.BuildHelp" task could not be loaded from the assembly c:\Program Files (x86)\EWSoftware\Sandcastle Help File Builder\SandcastleBuilder.Utils.dll. Could not load file or assembly 'file:///c:\Program Files (x86)\EWSoftware\Sandcastle Help File Builder\SandcastleBuilder.Utils.dll' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded. Confirm that the <UsingTask> declaration is correct, and that the assembly and all its dependencies are available.
    0 Warning(s)    1 Error(s)
Time Elapsed 00:00:00.01

Coordinator
Apr 2, 2011 at 3:26 AM

The latest release is built using .NET 4.0 and the MSBuild 4.0 assemblies.  You need to run the .NET 4.0 version of MSBuild.exe to build projects created with the latest release.  If you have an existing project, make sure you've opened and saved it in the GUI or edited it and set the ToolsVersion to 4.0 as well.  Note that will still build help for any assembly built with any version of .NET from 1.1 to 4.0.

Eric

 

Apr 4, 2011 at 6:15 PM

Thank you Eric,

 

It would be great if we can selection any version of .Net when building help. Would you be possible to give me ETA for that?

Coordinator
Apr 4, 2011 at 6:55 PM

You can already.  Set the FrameworkVersion property in the project to specify what version of .NET the assemblies are built against.  SHFB needs .NET 4.0 to run but it and Sandcastle can document assemblies for any framework version.

Eric

 

Apr 4, 2011 at 7:13 PM

Thank you, Finally I can build the help at VS2010. Appreciate again.