Если в моем файле проекта нет целей, и у меня есть файл Directory.Build.targets (с соответствующими целями) в соответствующем каталоге, Visual Studio не может построить проект. Версия VS - 2019RC, но я не думаю, что это проблема конкретной версии.
Это ожидаемое поведение и почему?
ОБНОВЛЕНИЕ - полная структура проекта. В общем, это модифицированный проект из шаблона "Проект коннектора данных" из "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>
Привет, я проверил ваше обновление и боюсь, что этот тип проекта не поддерживает вашу ситуацию. Этот тип проекта является расширением от третьей стороны, а не от команды разработчиков VS. И после того, как я протестировал это расширение, у него есть специальный процесс проверки, который сильно отличается от проектов VS. (C# C++...) Например: Создайте новый проект, удалите две цели в своем файле проекта. Перезагрузитесь, и вы обнаружите, что опция сборки исчезла!!!
И для ошибки: E_INVALIDARG. Add PropertyGroup Condition = " '$(Configuration)' == 'Debug' "> <DebugSymbols>false</DebugSymbols> <!--Должно быть true, исправьте это, когда отладчик будет реализован --> <OutputPath>bin\Debug \</OutputPath> </PropertyGroup> в файл proj может помочь загрузить. Не знаю почему, процесс проверки довольно странный.





Is that expected behavior, and why?
Это зависит.
1. Во-первых, согласно этот документ, Directory.Build.targets работает только после того, как Microsoft.Common.props вызывает его.
Поэтому, если вы не импортировали Microsoft.Common.props (или .targets) в файл проекта, сборка завершится ошибкой.
В этой ситуации ожидаемое поведение состоит в том, что мы не можем построить проект без целей в файле проекта.
2. Как вы упомянули «У меня есть файл Directory.Build.targets (с соответствующими целями)», убедитесь, что в вашем файле проекта есть <Import Project = "$(MSBuildToolsPath)\Microsoft.CSharp.targets" />. Без него сборка не может работать в вашей ситуации (без настраиваемых целей в файле проекта).
Убедитесь, что вы импортировали Microsoft.CSharp.targets в файл проекта. А для ваших целей в Directory.Build.targets добавьте атрибут <Target BeforeTargets = "..."> или <Target AfterTargets = "...">, чтобы он работал.
Пример для моего 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, или цель, импортированная с другими файлами целей.
Поскольку в вашем файле проекта нет целей, и цели в ваших импортированных целях не будут запущены, 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, сборка может завершиться успешно и запустить цель «Сегодня», чтобы вывести «JustForTest». И если я закомментирую импорт Microsoft.Common.Props, сборка завершится ошибкой с MSB4040. Потому что в .NET Directory.build.propsне может быть импортирован неявно без Microsoft.Common.Props.
Обновление3
Я проверил содержимое microsoft.common.props и microsoft.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, если я прокомментирую, что import Microsoft.Common.props, то сборка упадет, поскольку цели не импортируются в файл proj. Я скоро добавлю некоторые детали в свое обновление, вы можете проверить это.
Кроме того: если Directory.build.props не может быть неявно импортирован в файл вашего проекта, где нет целей, вы не сможете построить проект, если не импортируете его явно с помощью <Import Project = "..\Directory.Build.props " />
"Я скоро добавлю некоторые детали в свое обновление, вы можете проверить его" - не могли бы вы сказать, где я могу проверить обновление? Спасибо. По поводу ошибки - я даже не могу "загрузить" проект, когда я открываю такой проект (проект без какой-либо цели, но в Directory.Build.targets), я вижу проект в состоянии "выгрузки", и если я пытаюсь загрузить это, я получаю сообщение об ошибке. Поэтому я не вижу, какие файлы Microsoft.Common* используются для сборки такого проекта.
Привет, какой тип проекта в визуальной студии? Может быть, я могу создать тип проекта, который вы используете, а затем я могу исследовать его структуру. Кроме того, даже если у нас нет целей в файле проекта и в обоих файлах Directory.Build.targets, сборка завершится ошибкой, а перезагрузка может быть успешной. Не могли бы вы поделиться сообщением об ошибке при попытке загрузки, я предполагаю, что могут быть некоторые синтаксические ошибки. (И посмотрите update2, я пытаюсь описать, что я имею в виду, когда Directory.build.targets вызывается другим проектом импорта)
Ошибка E_INVALIDARG. Кстати, я просмотрел свой файл mporj и понял, что там есть импорт Microsoft.CSharp.targets для встроенной задачи. И я подозреваю, что все штучки Directory.Build* у меня работают только потому, что есть этот импорт. Это правильно? Таким образом, без импорта Microsoft.CSharp.targets или Microsoft.VisualBasic.targets вся эта магия Directory.Build.* исчезает.
Хорошо, я размещу всю структуру проекта в обновлении для своего поста. Большое спасибо за ваше терпение.
Хорошо, я проверю это после вашего обновления. Любой вопрос, пожалуйста, не стесняйтесь связаться со мной :)
Давайте продолжить обсуждение в чате.
Если возможно, не могли бы вы поделиться простым образцом файла вашего проекта и файла Directory.Build.targets. В ходе этого процесса на результат сборки может повлиять множество факторов. Поэтому трудно сказать, является ли это ожидаемым поведением без этих двух файлов.