使用C#进行异地构建

时间:2008-08-28 16:21:04

标签: c# msbuild build-process

我刚刚使用继承的属性表为我们现有的C ++代码设置了一个不合适的构建系统,这个特性似乎是Visual C ++产品特有的。构建不合适需要更改许多项目设置,并且继承的属性表允许我仅通过将属性表附加到项目来更改所有必需的设置。我正在将我们的团队从用于UI的C ++ / MFC迁移到C#和WPF,但我需要提供相同的异地构建功能,希望具有相同的便利性。我似乎无法通过C#项目找到一种方法 - 我首先查看是否可以引用MsBuild目标文件,但找不到这样做的方法。我知道我可以直接使用MsBuild,但这似乎比必要的更复杂。有没有办法可以为目录定义宏并在输出路径中使用它,例如?

3 个答案:

答案 0 :(得分:3)

我不太确定什么是“不合适”的构建系统,但是如果你只需要能够将编译好的文件(或其他资源)复制到其他目录,你可以通过绑定到MSBuild构建目标。

在我们的项目中,我们将已编译的dll移动到lib文件夹中,并在构建完成后将文件放入适当的位置。为此,我们创建了一个自定义构建.target文件,用于创建TargetPropertyItemGroup,然后我们将其用于填充外部输出文件夹

我们的自定义目标文件看起来有点像这样:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <ProjectName>TheProject</ProjectName>
        <ProjectDepthPath>..\..\</ProjectDepthPath>
        <ProjectsLibFolder>..\..\lib\</ProjectsLibFolder>

        <LibFolder>$(ProjectsLibFolder)$(ProjectName)\$(Configuration)\</LibFolder>
    </PropertyGroup>

    <Target Name="DeleteLibFiles">
        <Delete Files="@(LibFiles-> '$(ProjectDepthPath)$(LibFolder)%(filename)%(extension)')" TreatErrorsAsWarnings="true" />
    </Target>
    <Target Name="CopyLibFiles">
        <Copy SourceFiles="@(LibFiles)" DestinationFolder="$(ProjectDepthPath)$(LibFolder)" SkipUnchangedFiles="True" />
    </Target>

    <ItemGroup>
        <LibFiles Include=" ">
            <Visible>false</Visible>
        </LibFiles>
    </ItemGroup>
</Project>

然后,Visual Studio中的.csproj文件与此自定义目标文件集成:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" ... >
    ...
    <Import Project="..\..\..\..\build\OurBuildTargets.targets" />
      <ItemGroup>
        <LibFiles Include="$(OutputPath)$(AssemblyName).dll">
          <Visible>false</Visible>
        </LibFiles>
      </ItemGroup>
    <Target Name="BeforeClean" DependsOnTargets="DeleteLibFiles" />
    <Target Name="AfterBuild" DependsOnTargets="CopyLibFiles" />
</Project>

简而言之,此构建脚本首先告诉MSBuild加载我们的自定义构建脚本,然后将编译后的文件添加到LibFiles ItemGroup,最后绑定我们的自定义构建目标DeleteLibFiles和{{ 1}},进入构建过程。我们在解决方案中为每个项目设置了这个,所以只有更新的文件被删除/复制,每个项目都负责它自己的文件(dll,图像等)。

我希望这会有所帮助。如果我误解了你的异地构建系统的意思,我很抱歉,这对你来说完全没用!

答案 1 :(得分:0)

  

有没有办法可以为目录定义宏并在输出路径中使用它

您是否查看了项目的预构建和后期构建事件?

答案 2 :(得分:0)

实际上,预构建和后构建事件似乎只是添加批处理文件类型命令的地方。不幸的是,这无助于我为我们的项目设置标准构建目录。创建批处理文件这些事件似乎是一种非常适合现代语言的方法,如C#,IMO。

在挖掘了更多内容并进行实验后,我发现您可以添加&lt; Import&gt; .csproj文件中的指令。执行此操作时,IDE会弹出一个警告对话框,指出项目中存在不安全的入口点 - 但您可以忽略它,并且可以通过编辑注册表项来显示它根本不显示。所以这将为我提供一种方法,将包含我需要的目录路径的变量放入.csproj文件中。

现在让输出路径引用它 - 不幸的是,当您在输出路径字段中添加“$(MySpecialPath)/ Debug”之类的字符串并保存项目时,$和()字符将转换为十六进制,并将您的文件放在名为“$(MySpecialPath)”的目录下的Debug目录中。 Arrgghh。如果您在文本编辑器中编辑.csproj文件,则可以正确设置此文件,并且它似乎与&lt; Import&gt;一样长。标签出现在&lt; PropertyGroup&gt;之前包含输出路径。

所以我认为我的解决方案是在标准位置创建一个标准的OurTeam.targets MsBuild文件,添加一个用于更改注册表的安装程序,以便它不会标记警告,然后创建自定义项目模板&lt;进口&GT;此文件,还设置输出路径以使用OurTeam.targets文件中定义的属性。遗憾的是,与C ++中的属性表继承机制相比,这是更多的工作和不太优雅的解决方案。