Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.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
C# 动态引用项目的生成配置_C#_Visual Studio_Visual Studio 2015_Msbuild - Fatal编程技术网

C# 动态引用项目的生成配置

C# 动态引用项目的生成配置,c#,visual-studio,visual-studio-2015,msbuild,C#,Visual Studio,Visual Studio 2015,Msbuild,我有一个ASP.NET项目,它包含在多个解决方案中。在每个解决方案中,我希望ASP.NET项目的生成输出中包含不同的未引用项目。解决方案如下所示: Foo.sln WebApp.csproj Foo.csproj Bar.sln WebApp.csproj Bar.csproj 理想情况下,即使在使用F5进行调试时,这也会起作用。我尝试使用构建配置来实现这一点,但在VisualStudio中使用时,偏离典型的“调试”和“发布”似乎很脆弱。有没有一种典型的方法可以做到这一点?我不知道是

我有一个ASP.NET项目,它包含在多个解决方案中。在每个解决方案中,我希望ASP.NET项目的生成输出中包含不同的未引用项目。解决方案如下所示:

  • Foo.sln

    • WebApp.csproj
    • Foo.csproj
  • Bar.sln

    • WebApp.csproj
    • Bar.csproj

理想情况下,即使在使用F5进行调试时,这也会起作用。我尝试使用构建配置来实现这一点,但在VisualStudio中使用时,偏离典型的“调试”和“发布”似乎很脆弱。有没有一种典型的方法可以做到这一点?

我不知道是否有一种典型的方法可以满足您的要求(从IDE),但您可以通过编辑*.proj文件手动完成这一点

每个项目将发出输出(*.dll、*.exe、app.config等),并将其复制到$(OutputPath)属性中指定的文件夹(内部将使用OutDir属性)。如果要构建解决方案,您将拥有$(SolutionDir)属性以及$(SolutionName)。因此,您可以定义新的msbuild项目,该项目将被其他项目引用,并且您可以设置属性$(OutputPath),以便每个输出都将进入一个文件夹(称之为Common.props):


$(MSBuildThisFileDirectory)
默认名称
调试
$(SolutionDir)$(SolutionName)\bin\$(配置)
之后,您应该通过其他项目导入该项目-*.*proj(您应该指定项目的正确路径):



使用common$(OutputPath)属性将把您所有的二进制文件放在一个文件夹中-这将有助于解决您的任务。

我不知道是否有一种典型的方法来实现您的要求(从IDE),但您可以通过编辑*.proj文件手动完成这一任务

每个项目将发出输出(*.dll、*.exe、app.config等),并将其复制到$(OutputPath)属性中指定的文件夹(内部将使用OutDir属性)。如果要构建解决方案,您将拥有$(SolutionDir)属性以及$(SolutionName)。因此,您可以定义新的msbuild项目,该项目将被其他项目引用,并且您可以设置属性$(OutputPath),以便每个输出都将进入一个文件夹(称之为Common.props):


$(MSBuildThisFileDirectory)
默认名称
调试
$(SolutionDir)$(SolutionName)\bin\$(配置)
之后,您应该通过其他项目导入该项目-*.*proj(您应该指定项目的正确路径):



使用common$(OutputPath)属性将把所有二进制文件放在一个文件夹中-这将有助于解决您的任务。

免责声明:我认为这不是一个很好的主意,但似乎可以做到。

为了测试这个解决方案,我创建了两个项目。控制台应用程序1和类库1。ConsoleApplication1没有对ClassLibrary1的引用(在Visual Studio中可见),但从Visual Studio生成ConsoleApplication1时,它将生成ClassLibrary1.dll,然后将其复制到ConsoleApplication1的bin文件夹中

要导入目标文件,请继续并将此行添加到要生成未引用项目的项目中。此路径将相对于当前项目,因此在我的情况下,目标文件位于解决方案的根目录下。请确保在
行后添加此项,因为
未引用。target
依赖于在
Microsoft.CSharp.targets
中设置的目标

<Import Project="..\unreferenced.target" />

然后,您将继续创建一个文件名unreferenced.target,并将下面的内容添加到该文件中

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 <!-- Start another msbuild task to build your unreferenced project -->
 <Target Name="BuildBeforeResolveReferences" BeforeTargets="BeforeResolveReferences">
    <MSBuild
      BuildInParallel="False"
      Projects="$(SolutionDir)ClassLibrary1\ClassLibrary1.csproj"
      RunEachTargetSeparately="True"
      StopOnFirstFailure="False"
      UnloadProjectsOnCompletion="False">
    </MSBuild>
  </Target>

  <Target Name="CopyUnreferencedProjectOutput" AfterTargets="Build">
    <!-- This item group is here because we do not want it evaluated by msbuild until the ClassLibrary1.csproj has been compiled and its output is in its output directory -->
    <ItemGroup>
      <!-- Gets a list of all files at the OutputPath that end in .dll if you need the pdbs remove the .dll -->
      <!-- To maintain folder structure in the bin folder use <SourceFiles Include="..\ClassLibary1\@(OutputPath)**\*.dll" /> the double ** is a recursive wild card and will look through all directorys -->
      <SourceFiles Include="$(MSBuildProjectDirectory)\..\ClassLibrary1\$(OutputPath)*.dll" />
    </ItemGroup>

    <!-- To make sure the copy maintains folder structure switch it to this copy -->
    <!-- <Copy SourceFiles="@(SourceFiles)" DestinationFiles="@(SourceFiles -> '$(MSBuildProjectDirectory)$(OutputPath)%(RecursiveDir)%(Filename)%(Extension)')" /> -->
    <Copy SourceFiles="@(SourceFiles)" DestinationFolder="$(MSBuildProjectDirectory)\$(OutputPath)" />
  </Target>

  <!-- Cleans up all the files when clean is called -->
  <Target Name="CleanUnreferenceProjectOutput" BeforeTargets="Clean">
    <ItemGroup>
    <!-- Removed the .dll from the end of this to clean up the pdbs  as well -->
      <SourceFiles Include="$(SolutionDir)\ClassLibrary1\$(OutputPath)*" />
      <SourceFiles Include="$(SolutionDir)\ConsoleApplication1\$(OutputPath)*.dll" />
    </ItemGroup>

    <Delete Files="@(SourceFiles)" />
  </Target>
</Project>

我认为这是最好的办法。您可以将其扩展为有一个未被引用但您想要构建的项目列表,但对于这个示例,我只保留了一个

编辑2:在获得当前解决方案之前,我做了大量研究,在解决程序集之前将引用注入ProjectReference项目组。可以这样做,但您必须将属性
BuildInVisualStudio
设置为false,否则在
Microsoft.Common.Current.targets
中的
ResolveProjectReferences
目标中计算msbuild条件时,您将选择仅运行
GetManifest
目标的msbuild任务。我能够得到要构建的解决方案,但由于我不知道将
BuildInVisualStudio
设置为false需要什么,我选择了上面的解决方案。此外,我还添加了一个清理移动到bin文件夹中的文件的任务,因为clean只清理项目的obj文件夹中的
{ProjectName}{ProjectExtension}FileListAbsoluteText.txt


编辑:在对下面的解决方案进行更多的研究之后,它将只在命令行中工作。我目前正在调查为什么会发生这种情况。

免责声明:我认为这不是一个好主意,但似乎可以做到。

为了测试这个解决方案,我创建了两个项目。控制台应用程序1和类库1。ConsoleApplication1没有对ClassLibrary1的引用(在Visual Studio中可见),但从Visual Studio生成ConsoleApplication1时,它将生成ClassLibrary1.dll,然后将其复制到ConsoleApplication1的bin文件夹中

要导入目标文件,请继续并将此行添加到要生成未引用项目的项目中。此路径将与当前项目相关,因此在我的示例中,targe
<Import Project="..\unreferenced.target" />
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 <!-- Start another msbuild task to build your unreferenced project -->
 <Target Name="BuildBeforeResolveReferences" BeforeTargets="BeforeResolveReferences">
    <MSBuild
      BuildInParallel="False"
      Projects="$(SolutionDir)ClassLibrary1\ClassLibrary1.csproj"
      RunEachTargetSeparately="True"
      StopOnFirstFailure="False"
      UnloadProjectsOnCompletion="False">
    </MSBuild>
  </Target>

  <Target Name="CopyUnreferencedProjectOutput" AfterTargets="Build">
    <!-- This item group is here because we do not want it evaluated by msbuild until the ClassLibrary1.csproj has been compiled and its output is in its output directory -->
    <ItemGroup>
      <!-- Gets a list of all files at the OutputPath that end in .dll if you need the pdbs remove the .dll -->
      <!-- To maintain folder structure in the bin folder use <SourceFiles Include="..\ClassLibary1\@(OutputPath)**\*.dll" /> the double ** is a recursive wild card and will look through all directorys -->
      <SourceFiles Include="$(MSBuildProjectDirectory)\..\ClassLibrary1\$(OutputPath)*.dll" />
    </ItemGroup>

    <!-- To make sure the copy maintains folder structure switch it to this copy -->
    <!-- <Copy SourceFiles="@(SourceFiles)" DestinationFiles="@(SourceFiles -> '$(MSBuildProjectDirectory)$(OutputPath)%(RecursiveDir)%(Filename)%(Extension)')" /> -->
    <Copy SourceFiles="@(SourceFiles)" DestinationFolder="$(MSBuildProjectDirectory)\$(OutputPath)" />
  </Target>

  <!-- Cleans up all the files when clean is called -->
  <Target Name="CleanUnreferenceProjectOutput" BeforeTargets="Clean">
    <ItemGroup>
    <!-- Removed the .dll from the end of this to clean up the pdbs  as well -->
      <SourceFiles Include="$(SolutionDir)\ClassLibrary1\$(OutputPath)*" />
      <SourceFiles Include="$(SolutionDir)\ConsoleApplication1\$(OutputPath)*.dll" />
    </ItemGroup>

    <Delete Files="@(SourceFiles)" />
  </Target>
</Project>