Can't use Microsoft.Build.Evaluation in VS2017 - c#

I built a Web Forms website using VS2015 where I user Microsoft.Build.Evaluation
so that I can grammatically go through the files in my project.
When using VS2017 I get this error:
Microsoft.Build.Exceptions.InvalidProjectFileException: 'The imported
project "C:\Program Files
(x86)\MSBuild\Microsoft\VisualStudio\v15.0\WebApplications\Microsoft.WebApplication.targets"
was not found. Confirm that the path in the declaration is
correct, and that the file exists on disk.
C:\Users\MyUser\Source\Workspaces\MyProject
TFVC2\Gemstar\MyProject.csproj'
Here is my code:
using Microsoft.Build.Evaluation;
Project project = new Project();
if (ProjectCollection.GlobalProjectCollection.GetLoadedProjects(mPath + "MyProject.csproj").Count == 0)
{
project = new Project(mPath + "MyProject.csproj");
}
else
{
project = ProjectCollection.GlobalProjectCollection.GetLoadedProjects(mPath + "MyProject.csproj").FirstOrDefault();
}
I want to mention that I installed BuildTools for VS2017 from https://www.visualstudio.com/thank-you-downloading-visual-studio/?sku=BuildTools&rel=15

Mac OS -
I resolved it by installing the latest version of Mono.
Installing Mono on macOS.
Search "omnisharp" in settings (command + ',').
Changed the setting Omnisharp: Use Global Mono to always.
Reload the vscode.

Can't use Microsoft.Build.Evaluation in VS2017
It seems the old value of MSBuildExtensionsPath32 set in the Microsoft.Build.Evaluation.
According to the error info:
The imported project "C:\Program Files(x86)\MSBuild\Microsoft\VisualStudio\v15.0\WebApplications\Microsoft.WebApplication.targets"
was not found.
The import path for Microsoft.WebApplication.targets is not correct.
In the project file .csproj, we notice following import:
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
So the value for MSBuildExtensionsPath32 is C:\Program Files (x86)\MSBuild in the Microsoft.Build.Evaluation, which is not correct for Visual Studio 2017.
The value of MSBuildExtensionsPath32 for Visual Studio 2017 should be:
BuildTool Installed:
C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\Microsoft\VisualStudio\v15.0
Visual Studio Installed:
C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\Microsoft\VisualStudio\v15.0
To resolve this issue, you could verride the value in your project file:
<PropertyGroup>
<MSBuildExtensionsPath32>C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\Microsoft\VisualStudio\v15.0</MSBuildExtensionsPath32>
</PropertyGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
See the similar issue for some more details.
Hope this helps.

Install Wix Toolset Visual Studio 2017 Extension.

Related

Can't use Newtonsoft.Json in my project with Visual Studio Code

I followed several tutorials to add Newtonsoft.Json in my project by doing the following :
dotnet add package Newtonsoft.Json
Here is the terminal log :
info: Added PackageReference for package 'Newtonsoft.Json' in project 'C:\Users\XXX\Documents\Visual Studio Code\[...]'
info: Restoring packages for 'C:\Users\XXX\Documents\Visual Studio Code\[...]'
info: CACHE https://api.nuget.org/v3-flatcontainer/newtonsoft.json/index.json
info: The 'Newtonsoft.Json' package is compatible with all frameworks specified in the 'C:\Users\XXX\Documents\Visual Studio Code\[...].csproj' project.
info: PackageReference for package 'Newtonsoft.Json' version '13.0.1' added to file 'C:\Users\XXX\Documents\Visual Studio Code\[...].csproj'.
info: Validation of the restoration...
info: Writing component file to disk. Path: C:\Users\XXX\Documents\Visual Studio Code\[...]\obj\project.assets.json
log: Restore completed in 277.34 ms for C:\Users\XXX\Documents\Visual Studio Code\[...].csproj.
After executing the command, here is the content of my project .csproj file :
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
</Project>
Then I add:
using Newtonsoft.Json;
The problem is that Visual Studio Code doesn't offer me Newtonsoft.Json when I start writing it with using.
Is there something I need to do on my part?

MSBuild not able to build Nuget package because it's storing binaries in the wrong folder

I have a Visual Studio solution which has several projects. One of them, which is called Extensions is supposed to build a Nuget package. Problem is that if I use MSBuild to build the solution (by executing msbuild from the command prompt), I get the following error for the Nuget package build task:
"C:\git\repo\dirs.proj" (default target) (1:7) ->
"C:\git\repo\sources\dirs.proj" (default target) (2:5) ->
"C:\git\repo\sources\dev\Sdk\CompanyName.ProductName.Extensions.csproj" (default target) (7:6) ->
(GenerateNuspec target) ->
C:\Program Files\dotnet\sdk\5.0.408\Sdks\NuGet.Build.Tasks.Pack\build\NuGet.Build.Tasks.Pack.targets(221,5): error : Could not find a part of the path 'C:\git\ess\target\distrib\Debug\Amd64\CompanyName.ProductName.Extensions'. [C:\git\ess\sources\dev\Sdk\CompanyName.ProductName.Extensions.csproj]
Here is the CSPROJ file I have for this project:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AssemblyName>CompanyName.ProductName.Extensions</AssemblyName>
<RootNamespace>CompanyName.ProductName.Extensions</RootNamespace>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);IncludeCoreAssets</TargetsForTfmSpecificBuildOutput>
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
<NuspecFile>CompanyName.ProductName.Extensions.nuspec</NuspecFile>
<PackageOutputPath>$(DistribRoot)\$(Configuration)\$(Platform)\$(MSBuildProjectName)</PackageOutputPath>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<SkipAssemblyComVisible>true</SkipAssemblyComVisible>
<IncludeBuildOutput>false</IncludeBuildOutput>
<OutputPath>$(DistribRoot)\$(Configuration)\$(Platform)\$(MSBuildProjectName)</OutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<NuspecBasePath>$(OutputPath)</NuspecBasePath>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Core\CompanyName.ProductName.Core.csproj" PrivateAssets="All" />
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<Target DependsOnTargets="ResolveReferences" Name="IncludeCoreAssets">
<ItemGroup>
<BuildOutputInPackage Include="#(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference'))" />
</ItemGroup>
</Target>
</Project>
I personally think the issue is that for some reason when MSbuild is trying to create the Nuget package, it's trying to find the Extensions project DLLs in this path: \target\distrib\Debug\Amd64\CompanyName.ProductName.Extensions\, even though it actually built and stored the said binaries in this path earlier: \target\distrib\CompanyName.ProductName.Extensions\. <--- This is something I checked manually myself by examining the 'target' folder after running msbuild.
Visual Studio however doesn't have this issue. When I build this solution within Visual Studio, it stores the binaries for this Extensions project in \target\distrib\Debug\AnyCPU\CompanyName.ProductName.Extensions\ folder, which I think matches the pattern defined in the CSPROJ file:
<OutputPath>$(DistribRoot)\$(Configuration)\$(Platform)\$(MSBuildProjectName)</OutputPath>
Visual Studio also stored the Nuget package in this folder, which is also correct as per the <PackageOutputPath> spec mentioned in the CSPROJ file.
So can someone suggest why MSbuild is storing the built DLLs of this project in \target\distrib\CompanyName.ProductName.Extensions\, but is trying to find them in \target\distrib\Debug\Amd64\CompanyName.ProductName.Extensions\ ?
I think the issue is that for some reason, MSbuild isn't adhering to the <OutputPath> spec mentioned above when it's storing the built DLLs for this project.

Project gets unloaded when opening with Visual Studio 2019

I am trying to open a solution using Visual studio 2019 and visual studio 2017. All the projects in the solution are loading except for one. When trying to load the unloaded project i get an error in the output window as
TakstMVC.csproj : error : The imported project
"....build\MSBuild.Community.Tasks.targets" was not found. Confirm
that the expression in the Import declaration
"TakstMVC\.....build\MSBuild.Community.Tasks.targets" is correct,
and that the file exists on disk. TakstMVC\FluentMigrator.targets
When i tried to open using VS 2017 i saw a migration report which said
TakstMVC.csproj: The application which this project type is based on
was not found. Please try this link for further information:
http://go.microsoft.com/fwlink/?LinkID=299083&projecttype=E3E379DF-F4C6-4180-9B81-6769533ABE47
Part of the .csproj of the project is as below:
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>
</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{A4354F5C-ECF5-4621-AA9E-B91FE543F096}</ProjectGuid>
<ProjectTypeGuids>{E3E379DF-F4C6-4180-9B81-6769533ABE47};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>TakstMVC</RootNamespace>
<AssemblyName>TakstMVC</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<MvcBuildViews>false</MvcBuildViews>
<UseIISExpress>true</UseIISExpress>
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>4.0</OldToolsVersion>
<IISExpressSSLPort />
<IISExpressAnonymousAuthentication />
<IISExpressWindowsAuthentication />
<IISExpressUseClassicPipelineMode />
<MvcProjectUpgradeChecked>true</MvcProjectUpgradeChecked>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
I have the following installed in my computer
Microsoft .NET Framework 4.7.1 SDK
Microsoft .NET Framework 4.7.1 SDK Targeting Pack (ENU)
Microsoft .NET Core 3.1.1 - Windowsserver hosting
Microsoft .NET Core SDK 3.1.101 (x64)
Microsoft .NET Core SDK 2.2.207 (x64)
Microsoft .NET Core Runtime - 3.1.1
Microsoft .NET Core Runtime - 2.2.8
I tried to install dotnetfx35.exe but it doesnt even run when executed (not even a message or error).
The windows feature are as below:
How can I identify the target framework of the project and load it in visual studio successfully ? appreciate some advise on this.
The error is clear that you did not import the MSBuild.Community.Tasks.targets correctly on your local area. The reason is that you did not install MSBuild.Community.Tasks.targets on your PC or the import path from csproj file is incorrect.
You should check this document to install the right target.
First, remove xml node under csproj file like these:
<Import Project="..\build\MSBuild.Community.Tasks.targets" Condition="Exists('..\build\MSBuild.Community.Tasks.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\build\MSBuild.Community.Tasks.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\build\MSBuild.Community.Tasks.targets'))" />
</Target>
Second, install the msi file.
then, add these under the csproj file:
<Import Project="C:\Program Files (x86)\MSBuild\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
Besides, you could also use nuget function. First, uninstall the nuget package if you have a old version on the project. Then, use the first suggestion to remove any previous import projects="xxx\MSBuildTasks.targets". After that, install the MSBuildTasks nuget package. That is the same.
Update
Try to You should change ..\..\ to ..\. Use the right path.
Or use this command under Tools-->Nuget Package Manager-->Package Manager Console
update-package -reinstall
Answer from the Customer
embarrassingly enough the whole issue was with the solution path where my solution was located in my local computer. I had a long path including a folder having two words as well. After trying everything else I moved the solution folder to C:\temp folder and the issue was no longer there. The error showed in VS was quite misleading. What a waist of time. Thank you for your efforts !

MSBuild targets for nuget project called from another project

I am a beginner with MSBuild. I have a project (A) that depends on another project (B) and it consumes it either from a NuGet server either from a local workspace (I use NuGetReferenceSwitcher for this purpose).
Shortly, here are my requirements:
When consumed from NuGet server, project B has to support both Debug and Release builds. In this way, if we switch to Debug in Visual Studio we would be able to debug also project B when called from A. Right now, the NuGet also gives the Release version.
When switching to local workspace, it should still build properly.
Here is how my local files are located:
\workspace\projectA\projectA.sln
\workspace\projectB\projectB.csproj
The solution I tried is the following:
Inside projectB I created a targets file (located in build\projectB.targets) with the following contents:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
<Reference Include="lib1">
<HintPath>"$(MSBuildProjectDirectory)\bin\$platform$\Debug\lib1.dll"</HintPath>
</Reference>
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' == 'Release'">
<Reference Include="lib1">
<HintPath>"$(MSBuildProjectDirectory)\bin\$platform$\Release\lib1.dll"</HintPath>
</Reference>
</ItemGroup>
</Project>
projectB.csproj contains this:
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="packages\some_package" Condition="Exists('packages\some_package)" />
projectB.nuspec contains:
<file src="build\**" target="build\net462" />
projectA.csproj (that depends on projectB) contains:
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\projectB.*\build\projectB.targets" Condition="Exists('..\packages\projectB.*\build\projectB.targets')" />
<Import Project="..\..\..\..\projectB\projectB.csproj" Condition="!Exists('..\packages\projectB.*\build\projectB.targets')" />
Here are my questions:
With this configuration, when using local workspace for projectB, the compilation of projectA fails because of the relative path of "some_package" which is not find from projectA (that also uses relative path for projectB as you see in point 4). How else could I do reference projectB from projectA so it doesn't fail the compiling?
Why is this code not working to switch from release to debug when using nuget?
Thank you,
Why is this code not working to switch from release to debug when using nuget?
Quite simply, NuGet doesn't have a concept of "Debug" or "Release".
However, there is a way to create debug symbols for NuGet packages and then configure Visual Studio to step through the code of the installed packages.

MSBUILD target outputs element is applied strangly [duplicate]

I have customised an MSBuild project so that the default target is a new target named similarly to 'BuildWithExternalReference'. This new target calls two other targets; the first is a custom target called something like 'BuildExternalReference' which builds a DLL using an external tool. The DLL that is built is a reference for the main project, which is built using the normal 'Build' target. I have setup the Inputs and Outputs attributes for the 'BuildExternalReference' target so the Inputs reference the source files and the outputs reference the resulting DLL.
In both Visual Studio 2012 and Visual Studio 2010 the build works correctly the first time it is invoked. However, on subsequent builds if I change the external source files (referenced by the 'BuildExternalReference' target Inputs attribute) then Visual Studio 2012 simply reports 'Build: 0 succeeded, 0 failed, 1 up-to-date, 0 skipped'. Visual Studio 2010 continues to work perfectly. In addition, building from the command line with MSBuild.exe works perfectly.
I'm aware that the build system in Visual Studio 2012 has changed, but I can't find information about changes to the way incremental builds are performed.
Has anything changed in Visual Studio 2012 to cause incremental builds to change?
Here's a cut down version of the csproj file I'm using:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="BuildWithExternalTool" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ExternalSourceFiles Include="..\ExternalSourceFiles\\*\*.cs" />
<ExternalDll Include="..\ExternalSource\External.dll" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Target Name="BuildExternalTool" Inputs="#(ExternalSourceFiles);" Outputs="#(ExternalDll)">
<Exec Command="C:\External\Path\To\Tool.exe" />
</Target>
<Target Name="BuildWithExternalTool">
<CallTarget Targets="BuildExternalTool" />
<CallTarget Targets="Build" />
</Target>
</Project>
Update 1st of November 2012
Here's a complete self contained example which reproduces the issue:
https://skydrive.live.com/redir?resid=EA1DD6ACA92F9EFF!155&authkey=!ANhuqF_rrCgxpLE
This is a solution with one project. The MSBuildIssueExample\MSBuildIssueExample.csproj file has been customised so there is a custom default target. This default target calls a custom target (called 'ExternalTool') and then the default Build target.
The custom ExternalTool target writes out some messages to make sure it's working, and also copies the contents of the MSBuildIssueExample\ExternalTool\Input.txt file over the MSBuildIssueExample\ExternalTool\Output.txt file.
The Input.txt file is a input of the ExternalTool target, and Output.txt is an output.
To recreate the issue follow these steps:
1) Open the solution in the designated version of Visual Studio
2) Build the solution once to make sure the outputs are up to date with respect to the inputs
3) Modify MSBuildIssueExample\ExternalTool\Input.txt so its content does not match Output.txt
4) Build again
When you go through this process in Visual Studio 2010 the ExternalTool target will be invoked again, and the Input.txt file will be copied over Output.txt.
When you go through this process in Visual Studio 2012 the ExternalTool target will not be invoked, even though the inputs are newer than the outputs, and as a result the contents of Input.txt will not be written to Output.txt.
However, if you do Rebuild (rather than just Build) then both versions of Visual Studio work as expected.
This feedback from Microsoft answers the question:
This is due to a change in VS 2012 where C#/VB projects now do a "fast up-to-date check" that allows them to skip the build, rather than forcing the build all the time. One downside, however, is that fast up-to-date check does not take into account custom targets, which is why your incremental change was not detected. If you wish to disable the "fast up-to-date check" please set "DISABLEFASTUPTODATECHECK" to true either as an MSBuild property in the project file or as an environment variable in the environment you launch VS from.
So basically this is a breaking change in Visual Studio 2012 that unfortunately does not seem to be documented very well.
This is an old issue, but still relevant. Thank you very much for raising it here.
I would like to provide the results of my research.
The example you share shows the abnormal behavior both when built inside the Visual Studio GUI and by the devenv command line (devenv .\MSBuildIssueExample.sln /build)
However, if you replace your csproj file with the following:
MSBuildIssueExample.csproj
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{4EA8847D-262C-4937-8536-E526E9BAB1C7}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MSBuildIssueExample</RootNamespace>
<AssemblyName>MSBuildIssueExample</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Class1.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="Custom.Targets" />
</Project>
Custom.Targets
<?xml version="1.0" encoding="utf-8" ?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CompileDependsOn>ExternalTool;$(CompileDependsOn)</CompileDependsOn>
<CleanDependsOn>CleanOutput;$(CleanDependsOn)</CleanDependsOn>
</PropertyGroup>
<ItemGroup>
<ExternalToolInputs Include="ExternalTool\Input.txt">
<InProject>false</InProject>
</ExternalToolInputs>
<ExternalToolOutputs Include="ExternalTool\Output.txt">
<InProject>false</InProject>
</ExternalToolOutputs>
</ItemGroup>
<Target Name="ExternalTool" Inputs="#(ExternalToolInputs)" Outputs="#(ExternalToolOutputs)">
<Message Text="ExternalTool target start, copying input file over output..." />
<Copy SourceFiles="#(ExternalToolInputs)" DestinationFiles="#(ExternalToolOutputs)" />
<Message Text="ExternalTool target end, copy successful" />
</Target>
<Target Name="CleanOutput">
<Delete Files="#(ExternalToolOutputs)" ContinueOnError="true" />
</Target>
</Project>
Then the behavior is different !
Visual Studio GUI continues to misbehave, however, the command line build with devenv does recognize the change in the input!
Also note, that running msbuild on the command line instead of devenv works correctly in both versions. Although msbuild has other problems ...
EDIT
There is a solution for the GUI build, which is only applicable when the amount of external files is small. You add them to the project as links and make sure the Build Action is None. Then it works fine in the GUI.
Although, I have only checked with the Custom.Targets, but I am pretty sure it is going to work with the original version as well.
To expand on mark's Edit, and since None-items didn't work for me, here's an example of a custom targets file that I can import in other projects, that reads a text file into a property (which I can then use in the DefineConstants property), and that will mark the text file as input for the CoreCompile target:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<CommonDefines>$([System.IO.File]::ReadAllText('$(SolutionDir)\_meta\definesFlags.txt'));$(CommonDefines)</CommonDefines>
</PropertyGroup>
<ItemGroup>
<CustomAdditionalCompileInputs Include="$(SolutionDir)\_meta\definesFlags.txt" />
</ItemGroup>
</Project>
CustomAdditionalCompileInputs-items is taken as an input by Microsoft.Csharp.Core.targets.

Categories