Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Visual studio 2010 TFS生成未按预期转换web.config_Visual Studio 2010_Msbuild_Web Config_Tfsbuild - Fatal编程技术网

Visual studio 2010 TFS生成未按预期转换web.config

Visual studio 2010 TFS生成未按预期转换web.config,visual-studio-2010,msbuild,web-config,tfsbuild,Visual Studio 2010,Msbuild,Web Config,Tfsbuild,目标是让TFS构建和部署2+种不同的配置,并让web.config转换文件在其输出中包含预期的内容。这是在ASP.NET MVC项目中实现的 Web.Debug.Config-。 Web.Release.Config- 两个转换后的配置文件的构建操作设置为None。由于部署中包含所有3个web.*.config文件,因此对其进行了修改 TFS已正确配置以生成和部署这两种配置。它按预期部署到2个放置位置。生成定义中未指定MSBuild参数 问题:构建和部署的两个网站具有相同的web.confi

目标是让TFS构建和部署2+种不同的配置,并让web.config转换文件在其输出中包含预期的内容。这是在ASP.NET MVC项目中实现的

Web.Debug.Config-。
Web.Release.Config-

两个转换后的配置文件的构建操作设置为None。由于部署中包含所有3个web.*.config文件,因此对其进行了修改

TFS已正确配置以生成和部署这两种配置。它按预期部署到2个放置位置。生成定义中未指定MSBuild参数

问题:构建和部署的两个网站具有相同的web.config文件。基本上,转换后的文件似乎不存在

预期的:指定的更改(
xdt:Transform=“Replace”
xdt:Transform=“Remove”
)将出现在web.config文件中

如何配置项目或TFS以确保web.config转换得到处理,并将其输出部署到正确的部署位置?我还可以检查/修改什么

  • 已经确认转换是好的——输出正确的转换
  • 尚未对.csproj进行任何后期生成或部署修改
  • 是否有任何
    xdt
    属性被误用或丢失
  • 生成定义中未指定MSBuild参数
  • web.config生成操作设置是否正确
  • 我们没有使用web部署包或任何东西。只是希望在以后将这些输出复制到它们的各种Web服务器位置

如果我遗漏了任何重要信息,请留下评论,我将包括更多相关信息

这是我一直在用的东西。当前TransformXml任务有一个错误,它会使文件处于打开状态。阅读更多

您可以调用此任务并为正在使用的每个配置进行部署

<Target Name="TransformWebConfig">

    <PropertyGroup>
        <_tempSourceFile>$([System.IO.Path]::GetTempFileName())</_tempSourceFile>
        <_tempTransformFile>$([System.IO.Path]::GetTempFileName())</_tempTransformFile>
    </PropertyGroup>

    <Copy SourceFiles="$(_websiteDirectory)\Web.config" DestinationFiles="$(_tempSourceFile)"/>
    <Copy SourceFiles="$(_websiteDirectory)\Web.$(_transformConfiguration).config" DestinationFiles="$(_tempTransformFile)"/>

    <MSBuild.Community.Tasks.Attrib Files="$(_websiteDirectory)\Web.config" ReadOnly="false" />

    <TransformXml Source="$(_tempSourceFile)"
                  Transform="$(_tempTransformFile)"
                  Destination="$(_websiteDirectory)\Web.config"
                  StackTrace="false" />
</Target>

$([System.IO.Path]::GetTempFileName())
$([System.IO.Path]::GetTempFileName())

TFS Team Build 2010不会自动转换您的Web.configs。您需要将自定义工作流活动添加到生成过程模板以完成此操作

Edwald Hofman有一个很好的博客,解释了如何修改TFS 2010构建过程模板,所以我在这里不深入讨论

在您了解如何将自定义活动添加到构建过程模板后,请将以下活动添加到您的工作流中,我在“将文件放置到放置位置”之后添加了该活动。它利用Microsoft.Web.Publishing.Tasks程序集(位于C:\Program Files(x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web)执行转换:

/// <summary>
/// Transforms configuration files using TransformXml
/// </summary>
[BuildActivity(HostEnvironmentOption.All)]
public sealed class WebConfigTransform : CodeActivity
{
    #region Public Properties

    /// <summary>
    /// The binaries folder
    /// </summary>
    [RequiredArgument]
    public InArgument<string> BinariesLocation { get; set; }

    #endregion

    #region Overrides of CodeActivity

    /// <summary>
    /// When implemented in a derived class, performs the execution of the activity.
    /// </summary>
    /// <param name="context">The execution context under which the activity executes.</param>
    protected override void Execute(CodeActivityContext context)
    {
        var binariesFolder = context.GetValue(BinariesLocation);

        foreach (var sourceFolder in Directory.GetDirectories(Path.Combine(binariesFolder, "_PublishedWebsites")))
        {
            var sourceFile = Path.Combine(sourceFolder, "Web.config");
            if (File.Exists(sourceFile))
            {
                var filesToTransform = Directory.GetFiles(sourceFolder, "Web.*.config");


                foreach (var fileToTransform in filesToTransform)
                {

                    var tempSourceFile = Path.GetTempFileName();
                    var tempTransformFile = Path.GetTempFileName();

                    File.Copy(sourceFile, tempSourceFile, true);
                    File.Copy(fileToTransform, tempTransformFile, true);

                    var transformation = new TransformXml
                    {
                        BuildEngine = new BuildEngineStub(),
                        Source = tempSourceFile,
                        Transform = tempTransformFile,
                        Destination = fileToTransform
                    };

                    transformation.Execute();
                }
            }
        }
    }

    #endregion
}

水滴实际上不会进行任何转换。您需要的是向MSBuild参数添加
/p:DeployOnBuild=True

这将创建一个包,该包可用于通过命令行或使用IIS导入应用程序向导安装网站


如果您想要的是直接发布多个配置,那完全是另一回事,这就是我偶然发现这篇文章的原因。

尽量不要设置构建平台-基本上删除ItemToBuild中的“Any CPU”,并选择MSBuild Platform作为“Auto”

以前我做过类似于其他答案的事情。然而,我刚刚找到了解决这个问题的更好办法。只需将“/p:UseWPP\u CopyWebApplication=true/p:PipelineDependsOnBuild=false”添加到MSBuild参数中。我只是在我的一个TFS构建上尝试了这个,它工作得很好


我在这里找到了一个很好的建议:。

谢谢。我在这个阶段有点困惑;这段XML放在哪里?是否对TFS生成定义进行了任何其他修改以适应?您对MSBuild的熟悉程度如何?您可以将此目标放在构建定义中,并可能从“BeforeDropBuild”target.True调用它。虽然我认为当我发布我的答案时,情况并非如此。谁知道呢,我会重新发布2010年TFS的正确答案。其他选项是更好的选择,而且更容易产生分歧。我更愿意对我的构建过程模板进行一次更改(供所有解决方案使用),而不是编辑我创建的每个.proj文件或构建定义。Hrm,很好的一点,从来没有想过。。。诚然,我不熟悉通过TFS和构建模板进行构建,但这一切似乎都非常令人沮丧。似乎我们不得不特意开发/维护脚本来实现msbuild中已经存在的功能。当我们第一次从TFS 2008切换到2010时,我太沮丧了。但是,一旦你掌握了修改构建过程模板的方法,我想你会喜欢它的增强。我正在尝试实现它,但我没有在上下文中获得WriteBuildMessage方法,这是我缺少的扩展方法吗?更简单的解决方案!工作完美,即使设置TFS build来构建多个配置(调试和发布都转换得很好),这正是我所需要的!谢谢你的提示。
public class BuildEngineStub : IBuildEngine
{
        #region IBuildEngine Members

        public bool BuildProjectFile(string projectFileName, string[] targetNames,
                                     IDictionary globalProperties,
                                     IDictionary targetOutputs)
        {
            throw new NotImplementedException();
        }

        public int ColumnNumberOfTaskNode
        {
            get { return 0; }
        }

        public bool ContinueOnError
        {
            get { return false; }
        }

        public int LineNumberOfTaskNode
        {
            get { return 0; }
        }

        public string ProjectFileOfTaskNode
        {
            get { return ""; }
        }

        public void LogCustomEvent(CustomBuildEventArgs e)
        {
            Console.WriteLine("Custom: {0}", e.Message);
        }

        public void LogErrorEvent(BuildErrorEventArgs e)
        {
            Console.WriteLine("Error: {0}", e.Message);
        }

        public void LogMessageEvent(BuildMessageEventArgs e)
        {
            Console.WriteLine("Message: {0}", e.Message);
        }

        public void LogWarningEvent(BuildWarningEventArgs e)
        {
            Console.WriteLine("Warning: {0}", e.Message);
        }

        #endregion
    }