从CC.Net中的错误HRESULT ='8000000A'中恢复

时间:2014-04-24 20:11:30

标签: visual-studio-2010 cruisecontrol.net

我看到" An error occurred while validating. HRESULT = '8000000A'"使用CC.Net在VS2010上构建时很多。我已经安装了其中描述的修补程序,但仍然看到错误。

几乎总是可以通过手动强制执行另一个构建来解决错误。这真的很痛苦;我自然而然地希望自动化它。 :^)但是我在弄清楚部分过程时遇到了麻烦。我知道我需要使用条件任务块。我想做的伪代码如下:

if statusCondition == Failure
  if failure is caused by HRESULT = '8000000A'    <-- this is the part I can't figure out
    Use devenv to rebuild vdproj file
  endif
endif

如何使用CC.Net确定故障原因真的是8000000A?我在CC.Net的集成属性或任务条件块中没有看到任何与我需要的内容相同的内容。

谢谢。

1 个答案:

答案 0 :(得分:0)

好的,使用CruiseControl.NET的API我终于能够解决这个问题了。活泉!

首先,我创建了一个C#控制台应用程序来获取失败项目的列表。检查每个失败项目的日志文件,如果项目因错误8000000A而失败,则会强制在该项目上进行构建。

//Due to a race condition in Visual Studio 2010, CCNet builds often fail with error 8000000A.
//See http://stackoverflow.com/questions/8648428/an-error-occurred-while-validating-hresult-8000000a
//
//The build failure can almost always be fixed by manually forcing another build on the failed project.
//
//This program, along with a companion CCNet project, will automate the process of forcing the builds on the failed projects.
//  1. For each CCNet project whose IntegrationStatus == Failure
//  2. Search the most recent log file for the string "8000000A"
//  3. If string found in log file, force a build on the project

using System;
using ThoughtWorks.CruiseControl.Remote;

namespace ForceBuildForError8000000A
{
    class Program
    {
        static void Main(string[] args)
        {
            CruiseServerRemotingClient ccnetClient = new CruiseServerRemotingClient("tcp://localhost:21234/CruiseManager.rem");
            ProjectStatus[] prjStatusList = ccnetClient.GetProjectStatus();
            foreach (ProjectStatus prjStatus in prjStatusList)
            {
                if (prjStatus.BuildStatus == IntegrationStatus.Failure)
                {
                    string latestBuildName = ccnetClient.GetLatestBuildName(prjStatus.Name);
                    string log = ccnetClient.GetLog(prjStatus.Name, latestBuildName);
                    if (log.Contains("ERROR: An error occurred while validating.  HRESULT = '8000000A'"))
                    {
                        Console.WriteLine("Forcing build for " + prjStatus.Name);
                        ccnetClient.ForceBuild(prjStatus.Name);
                    }
                }
            }
        }
    }
}

接下来,我在ccnet.config文件中创建了另一个项目。此项目使用多触发器来监视可能因8000000A错误而失败的所有其他项目。当任何触发器项目出现故障时,将运行C#程序以强制构建因8000000A而失败的任何项目。

<cb:scope ProjectName="$(ForceBuildForError8000000A.Run_ProjectName)">
    <project name="$(ProjectName)" >
        <cb:ProjectHeaderMacro projectName="$(ProjectName)" />
        <cb:AssemblyVersionLabellerMacro Major="1" Minor="0" Build="0" />
        <triggers>
            <multiTrigger>
                <triggers>
                    <projectTrigger project="$(ProjectName1)" triggerStatus="Failure" />
                    <projectTrigger project="$(ProjectName2)" triggerStatus="Failure" />
                    <projectTrigger project="$(ProjectName3)" triggerStatus="Failure" />
                    <projectTrigger project="$(ProjectName4)" triggerStatus="Failure" />
                    <projectTrigger project="$(ProjectName5)" triggerStatus="Failure" />
                    <projectTrigger project="$(ProjectName6)" triggerStatus="Failure" />
                </triggers>
            </multiTrigger>
        </triggers>
        <tasks>
            <exec>
                <executable>$(ForceBuildForError8000000A.exe)</executable>
                <baseDirectory>$(MyWorkingTrunk)</baseDirectory>
                <buildTimeoutSeconds>120</buildTimeoutSeconds>          
            </exec>
        </tasks>
    </project>
</cb:scope>

注意我最终没有像我原先认为的那样使用条件任务块,而是使用条件触发器。

使用NANT而不是C#可能有办法做到这一点,但我永远无法弄清楚如何。