2010-07-06 36 views
3

我想在TeamCity服務器上使用MSBUILD在我的web.config中更改connectionString。以前我有使用屬性在目標調用此:更改帶有msbuild的connectionstrings

<PropertyGroup> 
<UpdateWebConfigCode> 
<![CDATA[ 
    public static void ScriptMain() 
    { 
    XmlDocument wcXml = new XmlDocument(); 
    wcXml.Load(@"TCM.MVC.UI\Web.config"); 

    XmlElement root = wcXml.DocumentElement; 
    XmlNodeList connList = root.SelectNodes("//connectionStrings/add"); 
    XmlElement elem; 

    foreach (XmlNode node in connList) 
    { 
    elem = (XmlElement)node; 

    switch (elem.GetAttribute("name")) 
    { 
    case "TCMBaseConnectionString": 
     elem.SetAttribute("connectionString", "Data Source=server-name;Initial Catalog=TCMCentral;User ID=user;Password=something"); 
     break; 

    } 
    } 

    wcXml.Save(@"TCM.MVC.UI\Web.config");   

    } 
]]> 
</UpdateWebConfigCode> 

然後,我會叫它目標:

<Target Name="UpdateWebConfig">   
    <Script Language="C#" Code="$(UpdateWebConfigCode)" Imports="System.Xml" /> 
</Target> 

但這種不斷拋出一個錯誤。我意識到這可能是有點過時,但無法找到任何東西來取代它....任何建議?

回答

3

我這樣做有一個自定義的任務,它不一樣一樣的代碼,但MSBuidl變爲:

<UpdateConnectionString ConfigFile ="path\to\web.config" 
     ConnectionStringName="MyConnectionStringName" 
     ConnectionString="connection-string-here"/> 

這種任務的代碼是

public class UpdateConnectionString : Task 
    { 
     [Required] 
     public string ConfigFile { get; set; } 
     [Required] 
     public string ConnectionStringName { get; set; } 
     [Required] 
     public string ConnectionString { get; set; } 

     public override bool Execute() 
     { 
      try 
      { 
       var fi = new FileInfo(ConfigFile); 
       if(!fi.Exists) 
       { 
        Log.LogError("File {0} does not exist"); 
        return false; 
       } 
       fi.IsReadOnly = false; 
       XDocument doc = XDocument.Load(ConfigFile); 
       var confignode = doc.Descendants("configuration").Single(); 
       var connectionStrings = confignode.Descendants("connectionStrings").SingleOrDefault(); 
       if(connectionStrings == null) 
       { 
        connectionStrings = new XElement("connectionStrings"); 
        confignode.Add(connectionStrings); 
       } 
       var connectionElement = connectionStrings.Descendants("add").SingleOrDefault(
        e => e.Attribute("name") != null && 
         string.Compare(e.Attribute("name").Value, ConnectionStringName, 
             StringComparison.OrdinalIgnoreCase) == 0); 
       if (connectionElement == null) 
       { 
        connectionElement = new XElement("add", new XAttribute("name", ConnectionStringName)); 
        connectionStrings.Add(connectionElement); 
       } 

       connectionElement.SetAttributeValue("connectionString", ConnectionString); 
       doc.Save(ConfigFile); 
      } 
      catch (Exception ex) 
      { 
       Log.LogErrorFromException(ex, true); 
       return false; 
      } 
      return true; 
     } 
    } 

注意,這如果代碼不存在,代碼也會添加一個連接字符串,這可能比您現在需要的更復雜。

+0

傑米,感謝您的幫助。我最終在MSBuildCommunityTasks中使用了XmlUpdate屬性。請參閱下面的答案。再次感謝。 Andrew – abarr 2010-07-06 13:26:32

5

我結束了使用MSBuildCommunityTasks XmlUpdate屬性。以下是我的目標:

<Target Name="UpdateWebConfig">   
    <XmlUpdate XmlFileName="C:\TCM.NET\Current\TCM.MVC.UI\web.config" XPath="configuration/connectionStrings/add[@name='TCMBaseConnectionString']/@connectionString" Value="Data Source=server-name;Initial Catalog=TCMCentral;User ID=user;Password=something" /> 
</Target> 

這對我很好。

+0

不錯的選擇,我也開始更改爲更通用的「UpdateXml」類型任務,儘管我自己創作的是MSBuildCommunity之一。 – Jamiec 2010-07-06 14:07:27