2014-04-24 59 views
0

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

该错误几乎总是可以通过手动强制执行另一个生成来解决。这是一个真正的痛苦;自然我想自动化它。 :^)但是我很难搞清楚这个过程的一部分。我知道我需要使用一个条件任务块。什么我想要做的伪代码看起来像:

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的集成属性或任务条件块中看不到任何东西,看起来像我需要的东西。

谢谢。

回答

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#来做到这一点的方法,但我永远不知道如何。