2014-04-24 86 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#來做到這一點的方法,但我永遠不知道如何。