MSBuild: Как я могу получить доступ к встроенным свойствам при определении своих собственных свойств? - PullRequest
1 голос
/ 12 февраля 2020

У меня есть файл с именем Common.targets, определенный следующим образом:

<Project>
  <PropertyGroup>
    <TlbExpPath>"c:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\x64\tlbexp"</TlbExpPath>
    <TlbOutPath>"$(OutDir)..\TLB\$(TargetName).tlb"</TlbOutPath>
  </PropertyGroup>

  <Target Name="TlbExp" AfterTargets="CopyFilesToOutputDirectory" Inputs="$(TargetPath)" Outputs="$(TlbOutPath)">
    <Exec Command='$(TlbExpPath) "$(TargetPath)" /nologo /win64 /out:$(TlbOutPath) /verbose' />
  </Target>
</Project>

Когда я проверяю вывод свойства TlbOutPath, он выглядит следующим образом:

"..\TLB\.tlb"

Видимо $(OutDir) и $(TargetName) ничего не производят при использовании внутри PropertyGroup. Я не уверен почему. Как я могу сделать эти пути / значения многократно используемыми, сохраняя при этом доступ к встроенным свойствам, когда они определены?

Я использую MSBuild, который поставляется в комплекте с Visual Studio 2019. Я добавляю элемент Import в мои настоящие .csproj проекты включают эту цель там, где она мне нужна. csproj проекты используют формат SDK для проектов, например <Project Sdk="Microsoft.NET.Sdk">.

Вот пример того, как выглядит импорт:

<Project Sdk="Microsoft.NET.Sdk">

  <!-- etc -->

  <ItemGroup>
    <Reference Include="Microsoft.CSharp" />
    <!-- etc -->
  </ItemGroup>

  <Import Project="$(RepositoryRoot)\Common.targets" />

</Project>

1 Ответ

0 голосов
/ 13 февраля 2020

MSBuild: Как я могу получить доступ к встроенным свойствам при определении своих собственных свойств?

Это довольно проблема в новом проекте формата SDK. Я проверил это и получил ту же проблему, как вы сказали, что очень беспокоит меня. Например, $(OutDir), $(TargetName), $(OutputPath), $(TargetPath) и некоторые другие общие системные свойства нельзя использовать в новом свойстве, в то время как $(Configuration) и $(AssemblyName) работают хорошо.

И не только у нас но также кто-то другой также сталкивается с той же проблемой по этому поводу. См. этот поток .

Для традиционного старого проекта формата csproj не было проблем с использованием этих свойств таким образом, но в В новом проекте формата SDK невозможно присвоить некоторые общие свойства, такие как $(OutDir), $(TargetName) и $(TargetPath), новому свойству. Как мы знаем, большинство общих свойств определены в файле Microsoft.Common.props (старый формат csproj), который сильно отличается от нового проекта формата SDK, в котором такого файла нет.

на получите ответ, я сообщил об этой проблеме на D C Forum . См. this . Вы можете ввести эту ссылку и добавить любые подробные комментарии для описания этой проблемы. И любой, кто интересуется этим вопросом, также проголосует за него, чтобы привлечь больше внимания сотрудников Microsoft. Все эти усилия ускорятся и получат окончательный ответ.

Этот процесс может занять некоторое время, или вы можете попробовать мое предложение.

Предложение

1) Вы можете настроить это свойство $(OutDir) в Common.targets файле и использовать $(TargetFramework) вместо $(TargetName), поскольку в файле xxxx.csproj определено $(TargetFramework).

<Project>
  <PropertyGroup>
 <OutDir>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName)\</OutDir>
 <TlbExpPath>"c:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\x64\tlbexp"</TlbExpPath>
 <TlbOutPath>"$(OutDir)..\TLB\$(TargetName).tlb"</TlbOutPath>
 <TargetPath>xxxx\xxxx.dll(exe)</TargetPath>--------the absolute path of the output file
  </PropertyGroup>

  <Target Name="TlbExp" AfterTargets="CopyFilesToOutputDirectory" Inputs="$(TargetPath)" Outputs="$(TlbOutPath)">
    <Exec Command='$(TlbExpPath) "$(TargetPath)" /nologo /win64 /out:$(TlbOutPath) /verbose' />
  </Target>
</Project>

2) используйте Directory.Build.targets файл вместо файла пользовательских целей.

A) Вы должны добавить файл с именем Directory.Build.targets (он должен иметь это имя и иметь свое собственное правило для импорта в xxx.csproj) в папке проекта.

B) добавить содержимое Common.targets в него без каких-либо изменений, а затем построить свой проект напрямую. Directory.Build.targets будет импортирован в ваш проект автоматически при сборке.

Эта функция работает хорошо и не теряет никаких свойств. Тем не менее, я все еще беспокоюсь о том, почему это работает.

Заключение

Я думаю, что # 2 более подходит и проще для достижения вашей цели.

...