在Visual Studio中,为什么所有文件都自动成为我的C#项目的一部分?

时间:2019-06-06 14:08:05

标签: c# visual-studio cmake msbuild .net-standard

我使用CMake自动生成Visual Studio解决方案,其结构如下所示:

/src
  CMakeLists.txt
  SomeSource.cs
  /build       << contents of this folder generated by CMake
    GeneratedCode.cs
    MyProject.sln
    MyProjectNET.csharp
    <other files by CMake>

问题是,当我在Visual Studio中打开解决方案时,C#项目在/build文件夹中包含所有内容,包括输出目录等。我检查了.csproj文件,看看CMake是否生成了该项目,以便所有这些文件都明确包含在内,但事实并非如此。

现在这只会带来不便。但是,如您所见,我在GeneratedCode.cs目录中有/build。此代码由CMake生成。由于CMake知道它是项目的一部分,因此在生成MyProjectNET.csharp时会显式添加引用。我现在观察到的行为是,在Visual Studio中打开GeneratedCode.cs时,编辑器几乎用红色强调所有内容,表示它是“歧义引用”,并列出了位于GeneratedCode.cs中的同一类,是可能来源的两倍。 。这样基本上就不可能发现代码中的实际错误。

有趣的是,编译代码有效。我只得到一个警告,提示编译器两次将相同文件作为输入。尽管如此,我还是希望摆脱这种行为,以便更高效地使用代码。

所以,导致我出现问题的原因是我的项目自动包含/build文件夹中的所有文件,然后显式包含GeneratedCode.cs文件,这使Visual Studio感到困惑。为什么所有文件都在我的项目中?我认为这不是正常行为,因为我看不到C ++项目和CMake不会生成的另一个C#项目发生这种情况。我假设CMake在.csproj文件中生成了一些奇怪的设置,但是在项目文件中找不到与我的问题有任何关系的任何东西。什么设置会导致此行为?

编辑:VS版本是2017,版本15.9.9。希望合适,这是实际的项目文件:

<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk" DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup Label="Globals">
    <ProjectGuid>{0AE1D52A-C2A2-35E1-914D-92101FC2A02F}</ProjectGuid>
    <WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
    <Keyword>Win32Proj</Keyword>
    <Platform>x64</Platform>
    <ProjectName>libheroes.NET</ProjectName>
    <VCProjectUpgraderObjectName>NoUpgrade</VCProjectUpgraderObjectName>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
    <Authors>Felix Krause</Authors>
    <LangVersion>7.2</LangVersion>
    <PackageId>Libheroes.NET</PackageId>
    <RootNamespace>Heroes</RootNamespace>
    <Version>0.1.0</Version>
    <OutputType>Library</OutputType>
    <AppDesignerFolder>Properties</AppDesignerFolder>
  <TargetFramework>netstandard2.0</TargetFramework></PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
    <DebugSymbols>true</DebugSymbols>
    <DefineDebug>true</DefineDebug>
    <OutputPath>D:\Projects\libheroes\bindings\csharp\cmake-vs\Debug\</OutputPath>
    <PlatformToolset>v141</PlatformToolset>
    <AssemblyName>libheroes.NET</AssemblyName>
    <AdditionalOptions>/langversion:7.2</AdditionalOptions>
    <DebugType>full</DebugType>
    <DefineConstants>DEBUG</DefineConstants>
    <ErrorReport>prompt</ErrorReport>
    <Optimize>false</Optimize>
    <WarningLevel>3</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
    <OutputPath>D:\Projects\libheroes\bindings\csharp\cmake-vs\Release\</OutputPath>
    <PlatformToolset>v141</PlatformToolset>
    <AssemblyName>libheroes.NET</AssemblyName>
    <AdditionalOptions>/langversion:7.2</AdditionalOptions>
    <DebugType>none</DebugType>
    <DefineConstants />
    <ErrorReport>queue</ErrorReport>
    <Optimize>true</Optimize>
    <WarningLevel>1</WarningLevel>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|x64'" Label="Configuration">
    <OutputPath>D:\Projects\libheroes\bindings\csharp\cmake-vs\MinSizeRel\</OutputPath>
    <PlatformToolset>v141</PlatformToolset>
    <AssemblyName>libheroes.NET</AssemblyName>
    <AdditionalOptions>/langversion:7.2</AdditionalOptions>
    <DebugType>none</DebugType>
    <DefineConstants />
    <Optimize>true</Optimize>
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'" Label="Configuration">
    <DebugSymbols>true</DebugSymbols>
    <DefineDebug>true</DefineDebug>
    <OutputPath>D:\Projects\libheroes\bindings\csharp\cmake-vs\RelWithDebInfo\</OutputPath>
    <PlatformToolset>v141</PlatformToolset>
    <AssemblyName>libheroes.NET</AssemblyName>
    <AdditionalOptions>/langversion:7.2</AdditionalOptions>
    <DebugType>full</DebugType>
    <DefineConstants />
    <Optimize>false</Optimize>
  </PropertyGroup>
  <ImportGroup Label="ExtensionSettings">
  </ImportGroup>
  <ImportGroup Label="PropertySheets">
    <Import Project="$(UserRootDir)\Microsoft.CSharp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.CSharp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
  </ImportGroup>
  <PropertyGroup Label="UserMacros" />
  <ItemGroup>
    <None Include="D:\Projects\libheroes\bindings\csharp\CMakeLists.txt">
      <Link>CMakeLists.txt</Link>
    </None>
  </ItemGroup>
  <Target Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Name="CustomCommand_Debug_a636c07f1d51cd46229efc4bacc41a89" Inputs="D:/Projects/libheroes/bindings/csharp/CMakeLists.txt;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeCSharpCompiler.cmake.in;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeCSharpInformation.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeCompilerIdDetection.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeDetermineCSharpCompiler.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeDetermineCompiler.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeDetermineCompilerId.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeGenericSystem.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeInitializeConfigs.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeSystemSpecificInformation.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeSystemSpecificInitialize.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeTestCSharpCompiler.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeTestCompilerCommon.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CompilerId\VS-10.csproj.in;C:\Program Files\CMake\share\cmake-3.14\Modules\Platform\Windows.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\Platform\WindowsPaths.cmake;D:\Projects\libheroes\bindings\csharp\CMakeLists.txt;D:\Projects\libheroes\bindings\csharp\LibHeroes.NET.targets;D:\Projects\libheroes\bindings\csharp\cmake-vs\CMakeFiles\3.14.0\CMakeCSharpCompiler.cmake;D:\Projects\libheroes\bindings\csharp\cmake-vs\CMakeFiles\3.14.0\CMakeSystem.cmake;D:\Projects\libheroes\bindings\csharp\CMakeLists.txt" Outputs="D:\Projects\libheroes\bindings\csharp\cmake-vs\CMakeFiles\generate.stamp">
    <Exec Command="echo Building Custom Rule D:/Projects/libheroes/bindings/csharp/CMakeLists.txt" />
    <Exec Command="setlocal&#xA;&quot;C:\Program Files\CMake\bin\cmake.exe&quot; -SD:/Projects/libheroes/bindings/csharp -BD:/Projects/libheroes/bindings/csharp/cmake-vs --check-stamp-file D:/Projects/libheroes/bindings/csharp/cmake-vs/CMakeFiles/generate.stamp&#xA;if %errorlevel% neq 0 goto :cmEnd&#xA;:cmEnd&#xA;endlocal &amp; call :cmErrorLevel %errorlevel% &amp; goto :cmDone&#xA;:cmErrorLevel&#xA;exit /b %1&#xA;:cmDone&#xA;if %errorlevel% neq 0 goto :VCEnd" />
  </Target>
  <Target Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Name="CustomCommand_Release_a636c07f1d51cd46229efc4bacc41a89" Inputs="D:/Projects/libheroes/bindings/csharp/CMakeLists.txt;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeCSharpCompiler.cmake.in;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeCSharpInformation.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeCompilerIdDetection.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeDetermineCSharpCompiler.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeDetermineCompiler.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeDetermineCompilerId.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeGenericSystem.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeInitializeConfigs.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeSystemSpecificInformation.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeSystemSpecificInitialize.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeTestCSharpCompiler.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeTestCompilerCommon.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CompilerId\VS-10.csproj.in;C:\Program Files\CMake\share\cmake-3.14\Modules\Platform\Windows.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\Platform\WindowsPaths.cmake;D:\Projects\libheroes\bindings\csharp\CMakeLists.txt;D:\Projects\libheroes\bindings\csharp\LibHeroes.NET.targets;D:\Projects\libheroes\bindings\csharp\cmake-vs\CMakeFiles\3.14.0\CMakeCSharpCompiler.cmake;D:\Projects\libheroes\bindings\csharp\cmake-vs\CMakeFiles\3.14.0\CMakeSystem.cmake;D:\Projects\libheroes\bindings\csharp\CMakeLists.txt" Outputs="D:\Projects\libheroes\bindings\csharp\cmake-vs\CMakeFiles\generate.stamp">
    <Exec Command="echo Building Custom Rule D:/Projects/libheroes/bindings/csharp/CMakeLists.txt" />
    <Exec Command="setlocal&#xA;&quot;C:\Program Files\CMake\bin\cmake.exe&quot; -SD:/Projects/libheroes/bindings/csharp -BD:/Projects/libheroes/bindings/csharp/cmake-vs --check-stamp-file D:/Projects/libheroes/bindings/csharp/cmake-vs/CMakeFiles/generate.stamp&#xA;if %errorlevel% neq 0 goto :cmEnd&#xA;:cmEnd&#xA;endlocal &amp; call :cmErrorLevel %errorlevel% &amp; goto :cmDone&#xA;:cmErrorLevel&#xA;exit /b %1&#xA;:cmDone&#xA;if %errorlevel% neq 0 goto :VCEnd" />
  </Target>
  <Target Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|x64'" Name="CustomCommand_MinSizeRel_a636c07f1d51cd46229efc4bacc41a89" Inputs="D:/Projects/libheroes/bindings/csharp/CMakeLists.txt;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeCSharpCompiler.cmake.in;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeCSharpInformation.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeCompilerIdDetection.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeDetermineCSharpCompiler.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeDetermineCompiler.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeDetermineCompilerId.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeGenericSystem.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeInitializeConfigs.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeSystemSpecificInformation.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeSystemSpecificInitialize.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeTestCSharpCompiler.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeTestCompilerCommon.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CompilerId\VS-10.csproj.in;C:\Program Files\CMake\share\cmake-3.14\Modules\Platform\Windows.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\Platform\WindowsPaths.cmake;D:\Projects\libheroes\bindings\csharp\CMakeLists.txt;D:\Projects\libheroes\bindings\csharp\LibHeroes.NET.targets;D:\Projects\libheroes\bindings\csharp\cmake-vs\CMakeFiles\3.14.0\CMakeCSharpCompiler.cmake;D:\Projects\libheroes\bindings\csharp\cmake-vs\CMakeFiles\3.14.0\CMakeSystem.cmake;D:\Projects\libheroes\bindings\csharp\CMakeLists.txt" Outputs="D:\Projects\libheroes\bindings\csharp\cmake-vs\CMakeFiles\generate.stamp">
    <Exec Command="echo Building Custom Rule D:/Projects/libheroes/bindings/csharp/CMakeLists.txt" />
    <Exec Command="setlocal&#xA;&quot;C:\Program Files\CMake\bin\cmake.exe&quot; -SD:/Projects/libheroes/bindings/csharp -BD:/Projects/libheroes/bindings/csharp/cmake-vs --check-stamp-file D:/Projects/libheroes/bindings/csharp/cmake-vs/CMakeFiles/generate.stamp&#xA;if %errorlevel% neq 0 goto :cmEnd&#xA;:cmEnd&#xA;endlocal &amp; call :cmErrorLevel %errorlevel% &amp; goto :cmDone&#xA;:cmErrorLevel&#xA;exit /b %1&#xA;:cmDone&#xA;if %errorlevel% neq 0 goto :VCEnd" />
  </Target>
  <Target Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'" Name="CustomCommand_RelWithDebInfo_a636c07f1d51cd46229efc4bacc41a89" Inputs="D:/Projects/libheroes/bindings/csharp/CMakeLists.txt;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeCSharpCompiler.cmake.in;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeCSharpInformation.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeCompilerIdDetection.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeDetermineCSharpCompiler.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeDetermineCompiler.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeDetermineCompilerId.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeGenericSystem.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeInitializeConfigs.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeSystemSpecificInformation.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeSystemSpecificInitialize.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeTestCSharpCompiler.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CMakeTestCompilerCommon.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\CompilerId\VS-10.csproj.in;C:\Program Files\CMake\share\cmake-3.14\Modules\Platform\Windows.cmake;C:\Program Files\CMake\share\cmake-3.14\Modules\Platform\WindowsPaths.cmake;D:\Projects\libheroes\bindings\csharp\CMakeLists.txt;D:\Projects\libheroes\bindings\csharp\LibHeroes.NET.targets;D:\Projects\libheroes\bindings\csharp\cmake-vs\CMakeFiles\3.14.0\CMakeCSharpCompiler.cmake;D:\Projects\libheroes\bindings\csharp\cmake-vs\CMakeFiles\3.14.0\CMakeSystem.cmake;D:\Projects\libheroes\bindings\csharp\CMakeLists.txt" Outputs="D:\Projects\libheroes\bindings\csharp\cmake-vs\CMakeFiles\generate.stamp">
    <Exec Command="echo Building Custom Rule D:/Projects/libheroes/bindings/csharp/CMakeLists.txt" />
    <Exec Command="setlocal&#xA;&quot;C:\Program Files\CMake\bin\cmake.exe&quot; -SD:/Projects/libheroes/bindings/csharp -BD:/Projects/libheroes/bindings/csharp/cmake-vs --check-stamp-file D:/Projects/libheroes/bindings/csharp/cmake-vs/CMakeFiles/generate.stamp&#xA;if %errorlevel% neq 0 goto :cmEnd&#xA;:cmEnd&#xA;endlocal &amp; call :cmErrorLevel %errorlevel% &amp; goto :cmDone&#xA;:cmErrorLevel&#xA;exit /b %1&#xA;:cmDone&#xA;if %errorlevel% neq 0 goto :VCEnd" />
  </Target>
  <ItemGroup>
    <Compile Include="D:\Projects\libheroes\bindings\csharp\cmake-vs\LibHeroes.cs" />
    <Compile Include="D:\Projects\libheroes\bindings\csharp\Marshaling.cs">
      <Link>Marshaling.cs</Link>
    </Compile>
  </ItemGroup>
  <ItemGroup>
    <ProjectReference Include="D:\Projects\libheroes\bindings\csharp\cmake-vs\ZERO_CHECK.vcxproj">
      <Project>{C0C9F6B6-CF04-32B9-BDB5-A1812B10331E}</Project>
      <Name>ZERO_CHECK</Name>
      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
      <CopyToOutputDirectory>Never</CopyToOutputDirectory>
    </ProjectReference>


    <ProjectReference Include="D:\Projects\libheroes\bindings\csharp\cmake-vs\build\libheroes.vcxproj">
      <Project>{E8B13004-193F-393B-90DB-A41070EDBD99}</Project>
      <Name>libheroes</Name>
      <ReferenceOutputAssembly>false</ReferenceOutputAssembly>
      <CopyToOutputDirectory>Never</CopyToOutputDirectory>
    </ProjectReference>
  </ItemGroup>

  <ImportGroup Label="ExtensionTargets">
  </ImportGroup>
  <PropertyGroup Condition="'$(Configuration)' == 'Debug'">
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)' == 'Release'">
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)' == 'MinSizeRel'">
  </PropertyGroup>
  <PropertyGroup Condition="'$(Configuration)' == 'RelWithDebInfo'">
  </PropertyGroup>
  <PropertyGroup>
    <BuildDependsOn>
      CustomCommand_Debug_a636c07f1d51cd46229efc4bacc41a89;
      CustomCommand_MinSizeRel_a636c07f1d51cd46229efc4bacc41a89;
      CustomCommand_RelWithDebInfo_a636c07f1d51cd46229efc4bacc41a89;
      CustomCommand_Release_a636c07f1d51cd46229efc4bacc41a89;
      $(BuildDependsOn)
</BuildDependsOn>
  </PropertyGroup>
<ItemGroup><Content Include="build\Libheroes.NET.targets"><Pack>true</Pack><PackagePath>\build\</PackagePath></Content><Content Include="build\$(Configuration)\yaml.dll"><Pack>true</Pack><PackagePath>\build\</PackagePath></Content><Content Include="build\$(Configuration)\libheroes.dll"><Pack>true</Pack><PackagePath>\build\</PackagePath></Content></ItemGroup></Project>

1 个答案:

答案 0 :(得分:5)

新的.NET Standard(<Project sdk="Microsoft.NET.Sdk">)样式的项目文件会自动从项目文件夹中自动包含具有某些扩展名的文件。此更改已随Visual Studio 2017 / NetStandard / .NET Core引入,使维护项目文件更加容易。基本上,新项目系统假定您要包括以下内容:

<Compile Include="**\*.cs" />
<EmbeddedResource Include="**\*.resx" />
<None Include"**\*" />

As a by-product, it can accidentally include files you didn't want to。此升级博客文章介绍了这些差异。 It helped me understand many of the specifics

默认情况下,排除/bin/obj最好的方法是将输出定向到build,在obj文件夹下生成$(BaseIntermediateOutputPath)\build文件夹。

有一些方法可以禁用“新行为”并排除某些文件和文件夹。

要切换到旧的行为,请将以下内容添加到项目文件的顶部:

<PropertyGroup>
    <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
    <EnableDefaultNoneItems>false</EnableDefaultNoneItems>
    <EnableDefaultContentItems>false</EnableDefaultContentItems>

    <!-- Or all default includes -->
    <EnableDefaultItems>false</EnableDefaultItems>
</PropertyGroup>

我想从解决方案中排除特定文件this should do the trick

<ItemGroup>
    <Compile Remove="build\**\*.cs">
    <EmbeddedResource Remove="build\**\*.resx" />
    <None Remove="build\**\*" />
</ItemGroup>

或将build文件夹添加到$(DefaultItemExcludes)

<PropertyGroup>
     <DefaultItemExcludes>$(DefaultItemExcludes);build\**\*</DefaultItemExcludes>
</PropertyGroup>

或者您可以通过右键单击项目并选择从项目中排除来从Visual Studio解决方案资源管理器中排除项目。

另请参阅: