【问题标题】:Directory.Build.targets for project files without targets in Visual StudioVisual Studio 中没有目标的项目文件的 Directory.Build.targets
【发布时间】:2019-03-17 16:03:42
【问题描述】:

如果我的项目文件没有任何目标,并且我在适当的目录中有 Directory.Build.targets 文件(具有适当的目标),则 Visual Studio 无法构建项目。 VS的版本是2019RC,但我不认为这是特定版本的问题

这是预期的行为,为什么?

UPDATE - 项目的完整结构。一般来说,这是从“Power Query SDK”的“数据连接器项目”模板修改的项目 - https://marketplace.visualstudio.com/items?itemName=Dakahn.PowerQuerySDK

项目名称为 PQExtensionTest。它具有典型的文件夹结构 - PQExtensionTest 解决方案目录,在 PQExtensionTest.sln 文件和 PQExtensionTest 项目目录中包含 PQExtensionTest.mroj 和 Directory.build.targets 文件。

PQExtensionTest.sln 文件:

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28010.2046
MinimumVisualStudioVersion = 10.0.40219.1
Project("{4DF76451-A46A-4C0B-BE03-459FAAFA07E6}") = "PQExtensionTest", "PQExtensionTest\PQExtensionTest.mproj", "{6DEC2A2E-C380-4701-AA12-5052284223E4}"
EndProject
Global
    GlobalSection(SolutionConfigurationPlatforms) = preSolution
        Debug|x86 = Debug|x86
        Release|x86 = Release|x86
    EndGlobalSection
    GlobalSection(ProjectConfigurationPlatforms) = postSolution
        {6DEC2A2E-C380-4701-AA12-5052284223E4}.Debug|x86.ActiveCfg = Debug|x86
        {6DEC2A2E-C380-4701-AA12-5052284223E4}.Debug|x86.Build.0 = Debug|x86
        {6DEC2A2E-C380-4701-AA12-5052284223E4}.Release|x86.ActiveCfg = Release|x86
        {6DEC2A2E-C380-4701-AA12-5052284223E4}.Release|x86.Build.0 = Release|x86
    EndGlobalSection
    GlobalSection(SolutionProperties) = preSolution
        HideSolutionNode = FALSE
    EndGlobalSection
    GlobalSection(ExtensibilityGlobals) = postSolution
        SolutionGuid = {50EB6857-946A-4D05-B65C-B99E4D39BEDD}
    EndGlobalSection
EndGlobal

PQExtensionTest.mroj 文件:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <ProjectGuid>{6dec2a2e-c380-4701-aa12-5052284223e4}</ProjectGuid>
  </PropertyGroup>
  <ItemGroup>
    <Compile Include="PQExtensionTest.pq">
      <SubType>Code</SubType>
    </Compile>
    <Content Include="PQExtensionTest.query.pq">
      <SubType>Code</SubType>
    </Content>
  </ItemGroup>
</Project>

Directory.Build.targets 文件:

<Project DefaultTargets="BuildExtension" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <SchemaVersion>2.0</SchemaVersion>
    <ProjectGuid>{a9cd1ca9-92e5-493d-8065-377910605c30}</ProjectGuid>
    <OutputType>Exe</OutputType>
    <RootNamespace>MyRootNamespace</RootNamespace>
    <AssemblyName>MyAssemblyName</AssemblyName>
    <EnableUnmanagedDebugging>False</EnableUnmanagedDebugging>
    <AllowNativeQuery>False</AllowNativeQuery>
    <AsAction>False</AsAction>
    <FastCombine>False</FastCombine>
    <ClearLog>False</ClearLog>
    <ShowEngineTraces>False</ShowEngineTraces>
    <ShowUserTraces>False</ShowUserTraces>
    <LegacyRedirects>False</LegacyRedirects>
    <SuppressRowErrors>False</SuppressRowErrors>
    <SuppressCellErrors>False</SuppressCellErrors>
    <MaxRows>1000</MaxRows>
    <ExtensionProject>Yes</ExtensionProject>
    <Name>PQExtensionTest</Name>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
    <DebugSymbols>false</DebugSymbols>
    <!--Should be true, fix this when the debugger is implemented -->
    <OutputPath>bin\Debug\</OutputPath>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
    <DebugSymbols>false</DebugSymbols>
    <OutputPath>bin\Release\</OutputPath>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="mscorlib" />
    <Reference Include="System" />
    <Reference Include="System.Data" />
    <Reference Include="System.Xml" />
  </ItemGroup>
 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
  <UsingTask TaskName="BuildExtension" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll">
    <ParameterGroup>
      <InputDirectory ParameterType="System.String" Required="true" />
      <OutputFile ParameterType="System.String" Required="true" />
    </ParameterGroup>
    <Task>
      <Reference Include="System.IO.Compression" />
      <Reference Include="System.IO.Compression.FileSystem" />
      <Using Namespace="System.Globalization" />
      <Using Namespace="System.IO.Compression " />
      <Code Type="Fragment" Language="cs"><![CDATA[    
    using(FileStream fileStream = File.Create(OutputFile))
    using(ZipArchive archiveOut = new ZipArchive(fileStream, ZipArchiveMode.Create, false))
    {
        foreach(string fullPath in Directory.EnumerateFiles(InputDirectory))
        {
            string filename = Path.GetFileName(fullPath);

            archiveOut.CreateEntryFromFile(fullPath, filename, CompressionLevel.Optimal);
        }
    }
]]></Code>
    </Task>
  </UsingTask>
  <Target Name="BuildExtension" DependsOnTargets="ExtensionClean">
    <ItemGroup>
      <PQFiles Include="@(Compile)" Condition="'%(Extension)' == '.pq'" />
    </ItemGroup>
    <ItemGroup>
      <NonPQFiles Include="@(Compile)" Condition="'%(Extension)' != '.pq'" />
    </ItemGroup>
    <MakeDir Directories="$(IntermediateOutputPath)" />
    <MakeDir Directories="$(OutputPath)" />
    <Copy SourceFiles="@(NonPQFiles)" DestinationFolder="$(IntermediateOutputPath)" />
    <Copy SourceFiles="@(PQFiles)" DestinationFiles="@(PQFiles->'$(IntermediateOutputPath)%(RecursiveDir)%(FileName).m')" />
    <BuildExtension InputDirectory="$(IntermediateOutputPath)" OutputFile="$(OutputPath)\$(ProjectName).mez" />
  </Target>
  <Target Name="ExtensionClean">
    <!-- Remove obj folder -->
    <RemoveDir Directories="$(BaseIntermediateOutputPath)" />
    <!-- Remove bin folder -->
    <RemoveDir Directories="$(OutputPath)" />
<Message Text="MyM: $(aProperty)" />
   </Target>

【问题讨论】:

  • 如果可能的话,请您分享您的项目文件和 Directory.Build.targets 文件的简单示例。在此过程中,构建的结果可能会受到许多因素的影响。因此,如果没有这两个文件,很难说这是否是预期的行为。
  • 您好,我检查了您的更新,恐怕这个项目类型似乎不支持您的情况。此项目类型是来自第三方的扩展,不是来自 VS 开发团队。经过我的测试,此扩展具有特殊的检查过程,与 VS 项目有很大不同。(C# C++ ...)例如:创建一个新项目,删除其 proj 文件中的两个目标。重新加载,你会发现构建选项消失了!!!
  • 对于错误:E_INVALIDARG。添加PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> falsebin\Debug \ 到 proj 文件可以帮助加载。不知道为什么,检查过程很奇怪。

标签: visual-studio msbuild


【解决方案1】:

这是预期的行为,为什么?

视情况而定。

1。首先,根据this docDirectory.Build.targets只有在Microsoft.Common.props调用后才有效。

因此,如果您没有在项目文件中导入Microsoft.Common.props(或.targets),构建将失败。

在这种情况下,我们无法在项目文件中没有目标的情况下构建项目。

2。正如您提到的“我有 Directory.Build.targets 文件(带有适当的目标)”,请确保您的项目文件中有 &lt;Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /&gt;。没有它,构建将无法满足您的情况(项目文件中没有自定义目标)。

确保您已在项目文件中导入 Microsoft.CSharp.targets。对于Directory.Build.targets 中的目标,添加属性&lt;Target BeforeTargets="..."&gt;&lt;Target AfterTargets="..."&gt; 使其工作。

以我的Directory.Build.targets 为例:

<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
...
  </PropertyGroup>
  <Target Name="Test" AfterTargets="build">
    <Message Text="..."/>
  </Target>
</Project>

只有满足了这几点,你才能在你的情况下成功构建。所以请检查一下。

更新:

对于自定义 .proj 文件。我们必须在.proj 文件中直接定义一个目标,或者将一个目标与其他目标文件一起导入。

由于您的 proj 文件中没有目标,并且您导入的目标中没有目标将运行,MSBuild 将抛出错误MSB4040(项目中没有目标)。因为如果没有目标运行,那么它对 MSBuild 过程没有意义。这是设计的功能。

更新2

test.sln 中,我在解决方案目录中有一个Directory.build.props

<Project  xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="Today">
    <Message Text="JustForTest"/>
  </Target>
</Project>

在项目目录中还有一个非常简单的 .csproj 文件:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
</Project>

如果我构建 test.csproj,构建可以成功并运行 Today Target 以输出“JustForTest”。如果我注释掉 Import Microsoft.Common.Props,构建将失败并显示 MSB4040。因为在 .NET 中,Directory.build.props 不能在没有 Microsoft.Common.Props 的情况下隐式导入

更新3

我检查了microsoft.common.propsmicrosoft.Csharp.targets 的内容。 在 M.C.P 文件中,有关于 Directory.build.props 的定义和调用。在 M.C.T 文件中,它定义了 C# 的标准构建过程。所以我同意你的项目文件中必须有一些东西调用 Directory.build.props,但不能是 microsoft.Csharp.targets 或 microsoft.VB.targets。

【讨论】:

  • 1.我在 Directory.Build.targets 中有目标。但仅在该文件中。所以它是不神圣的? 2.“Directory.Build.targets 仅在 Microsoft.Common.props 调用它之后才起作用” - 你的意思是 Directory.Build.targets 将在 Microsoft.Common.props 导入之后被导入,或者 如果 Microsoft.Common.props 导入了,还是别的什么?
  • For1,正如我上面提到的,在我们只有 Directory.Build.targets 中的目标的情况下,并且只有在那个文件中,我们是否可以构建项目取决于我们是否有“Microsoft.Common.props”来调用它,或者类似“Microsoft.Common.props”的东西。
  • For2,是的,我刚刚又查了一遍。在 C# 项目中,它使用 Microsoft.Common.props 隐式导入 Directory.Build.targets,如果我评论导入 Microsoft.Common.props,则构建将失败,因为没有将目标导入 proj 文件。我很快会在我的更新中添加一些细节,你可以检查一下。
  • 另外:如果 Directory.build.props 不能被隐式导入到没有目标的项目文件中,则除非通过
  • “我很快会在我的更新中添加一些细节,你可以查看它” - 请你说我在哪里可以查看更新?谢谢。关于错误 - 我什至无法“加载”项目,当我打开这样一个项目(没有任何目标但在 Directory.Build.targets 中的项目)时,我看到项目处于“卸载”状态,如果我尝试加载它,我得到一个错误。所以我看不到哪些 Microsoft.Common* 文件用于构建这样的项目。
猜你喜欢
  • 1970-01-01
  • 2014-08-05
  • 1970-01-01
  • 2017-10-15
  • 2011-11-09
  • 1970-01-01
  • 1970-01-01
  • 2019-02-09
  • 1970-01-01
相关资源
最近更新 更多