如何根据所选配置将项目构建为可移植或普通 class 库?
How can a project be built as a portable or a normal class library depending on the selected configuration?
上下文: 我们有一个名为 'THEPROJECT' 的公共库项目,它与 visual studio 中的 Xamarin 移动解决方案和 Web 项目共享。由于 Xamarin 中的限制,此共享库是 PCL Profile259。在我们的 Web 应用程序解决方案中,我们希望使用适当的属性标记数据模型,以便 DataContext 正常工作(因为我们希望使用 LinqToSql)。
尝试的解决方案: 我们决定调查 'THEPROJECT' 的项目并以允许它以可移植库状态存在的方式更改 msbuild / 普通 class 库取决于在 visual studio.
中选择的配置
我们已经查看了 this post 中的解决方案,但这只是解决方案的一部分。我们可以让项目作为一个或另一个存在,但是它需要手动更改项目文件。现在我们在加载以下项目时遇到错误。可移植项目的 必须是“.NETPortable”。
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">DebugDesktop</Configuration>
<Platform Condition="'$(Platform)' == ''">AnyCPU</Platform>
<ProjectGuid>{426E7BD8-9DA8-4E15-9512-72E7C632B037}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>THEPROJECT</RootNamespace>
<AssemblyName>THEPROJECT</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<MinimumVisualStudioVersion>10.0</MinimumVisualStudioVersion>
<BuildMode>Desktop</BuildMode>
</PropertyGroup>
<!-- Define the Build Configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugDesktop|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Desktop\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<BuildMode>Desktop</BuildMode>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseDesktop|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Desktop\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<BuildMode>Desktop</BuildMode>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugPCL|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\PCL\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<BuildMode>Portable</BuildMode>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleasePCL|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\PCL\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<BuildMode>Portable</BuildMode>
</PropertyGroup>
<!-- Determine the correct properties for PCL/Desktop -->
<Choose>
<When Condition=" '$(BuildMode)' == 'Portable' ">
<PropertyGroup>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TargetFrameworkProfile>Profile259</TargetFrameworkProfile>
<TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
<DynamicImportPath>$(MSBuildExtensionsPath32)\Microsoft\Portable$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets</DynamicImportPath>
</PropertyGroup>
</When>
<When Condition=" '$(BuildMode)' == 'Desktop' ">
<PropertyGroup>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
<DynamicImportPath>$(MSBuildToolsPath)\Microsoft.CSharp.targets</DynamicImportPath>
</PropertyGroup>
<ItemGroup>
<Reference Include="System.Data.Linq" />
</ItemGroup>
</When>
</Choose>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\mobileapplication\packages\Newtonsoft.Json.8.0.2\lib\portable-net40+sl5+wp80+win8+wpa81\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\sqlite-net-extensions\SQLiteNetExtensions\SQLiteNetExtensions-PCL.csproj">
<Project>{f723017d-ede5-49cc-a84f-881c067c6004}</Project>
<Name>SQLiteNetExtensions-PCL</Name>
</ProjectReference>
<ProjectReference Include="..\..\sqlitenetpcl\src\SQLite.Net\SQLite.Net.csproj">
<Project>{4971d437-0694-4297-a8cc-146ce08c3bd9}</Project>
<Name>SQLite.Net</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(DynamicImportPath)" />
<!-- Source/Resx etc... -->
</Project>
创建便携式 Class 库时,您需要将库创建为 Windows 8.1 便携式库,您不能为此使用通用库,这听起来像是Xamarin 的约束。 Windows 8.1 可移植库是一种混合库,它允许 classic .net 与新的轻量级 .net 版本进行通信。
便携式 Class 库的问题是它无法通过项目引用引用 Classic Class 库,您只能通过 DLL 引用来引用它。如果您对编辑该文件感到不自在,则无需弄乱 XML,只需找到已编译的 DLL 并手动添加引用即可。如果您选择这样做,您将需要手动更新构建依赖项,否则您可能会破坏引用。
问题似乎不完全在您的 .csproj 中,但也在您的 project.json 中。我注意到 visual studio 没有生成正确的 project.json 文件。我必须修改 UI 中的目标才能使其正确生成。一旦我得到初始 project.json 生成,我就没有其他问题。
在做任何事情之前,我们需要连接我们的便携式 Class 库来处理 Classic Class 库。第一步是将目标框架从属性更新为目标 .net 4.5 或您喜欢的任何版本。
执行此操作后确认 project.json 文件如下所示:
{
"supports": {},
"dependencies": {},
"frameworks": {
".NETPortable,Version=v4.5,Profile=Profile259": {}
}
}
一旦您的便携式 Class 库以正确的版本为目标,您就可以将 DLL 引用添加到已编译的 .net 4.5 程序集。我没有对可移植 class 库的 csproj 文件进行任何其他更改,但这是该文件的源代码,因此您可以查看。
注意如何引用 ClassLibrary1:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.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>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7C4EB968-4C17-438C-B981-97EDC865F312}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PortableLibrary</RootNamespace>
<AssemblyName>PortableLibrary</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TargetFrameworkProfile>Profile259</TargetFrameworkProfile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</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>
<Compile Include="Class1.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="ClassLibrary1">
<HintPath>..\ClassLibrary1\bin\Debug\ClassLibrary1.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<None Include="project.json" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
假设您的 Web 项目是 ASP.NET Core 1.0,这应该可以消除问题。如果您是 运行 Classic ASP.NET 应用程序,您可能仍然需要创建构建规则。
TLDR:
您的 project.json 文件似乎有问题,请确保它已正确生成并且您不能通过项目引用直接引用 .net 4.5,您必须引用 DLL。
要根据配置回答关于使项目成为 "Portable" 或 "Normal" 的问题,当弹出的错误是关于 <TargetFrameworkIdentifier>
必须是 .NETPortable
:
从配置中删除所有 <ProjectTypeGuids>
。
那些项目类型的 GUID 给 Visual Studio 一些只与可移植项目有关的 GUI 东西,所以当配置不可移植时,它会导致你得到的错误。但是由于您可以轻松地编辑 XML,所以您显然不需要那些东西。另外,您可以继续使用 GUI 编辑项目属性,删除项目类型 GUID。
至少截至 Visual Studio 2015 年。
上下文: 我们有一个名为 'THEPROJECT' 的公共库项目,它与 visual studio 中的 Xamarin 移动解决方案和 Web 项目共享。由于 Xamarin 中的限制,此共享库是 PCL Profile259。在我们的 Web 应用程序解决方案中,我们希望使用适当的属性标记数据模型,以便 DataContext 正常工作(因为我们希望使用 LinqToSql)。
尝试的解决方案: 我们决定调查 'THEPROJECT' 的项目并以允许它以可移植库状态存在的方式更改 msbuild / 普通 class 库取决于在 visual studio.
中选择的配置我们已经查看了 this post 中的解决方案,但这只是解决方案的一部分。我们可以让项目作为一个或另一个存在,但是它需要手动更改项目文件。现在我们在加载以下项目时遇到错误。可移植项目的 必须是“.NETPortable”。
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">DebugDesktop</Configuration>
<Platform Condition="'$(Platform)' == ''">AnyCPU</Platform>
<ProjectGuid>{426E7BD8-9DA8-4E15-9512-72E7C632B037}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>THEPROJECT</RootNamespace>
<AssemblyName>THEPROJECT</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<MinimumVisualStudioVersion>10.0</MinimumVisualStudioVersion>
<BuildMode>Desktop</BuildMode>
</PropertyGroup>
<!-- Define the Build Configurations -->
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugDesktop|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Desktop\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<BuildMode>Desktop</BuildMode>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseDesktop|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Desktop\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<BuildMode>Desktop</BuildMode>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'DebugPCL|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\PCL\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
<BuildMode>Portable</BuildMode>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleasePCL|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\PCL\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<BuildMode>Portable</BuildMode>
</PropertyGroup>
<!-- Determine the correct properties for PCL/Desktop -->
<Choose>
<When Condition=" '$(BuildMode)' == 'Portable' ">
<PropertyGroup>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TargetFrameworkProfile>Profile259</TargetFrameworkProfile>
<TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
<DynamicImportPath>$(MSBuildExtensionsPath32)\Microsoft\Portable$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets</DynamicImportPath>
</PropertyGroup>
</When>
<When Condition=" '$(BuildMode)' == 'Desktop' ">
<PropertyGroup>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
<DynamicImportPath>$(MSBuildToolsPath)\Microsoft.CSharp.targets</DynamicImportPath>
</PropertyGroup>
<ItemGroup>
<Reference Include="System.Data.Linq" />
</ItemGroup>
</When>
</Choose>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=8.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\mobileapplication\packages\Newtonsoft.Json.8.0.2\lib\portable-net40+sl5+wp80+win8+wpa81\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\sqlite-net-extensions\SQLiteNetExtensions\SQLiteNetExtensions-PCL.csproj">
<Project>{f723017d-ede5-49cc-a84f-881c067c6004}</Project>
<Name>SQLiteNetExtensions-PCL</Name>
</ProjectReference>
<ProjectReference Include="..\..\sqlitenetpcl\src\SQLite.Net\SQLite.Net.csproj">
<Project>{4971d437-0694-4297-a8cc-146ce08c3bd9}</Project>
<Name>SQLite.Net</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(DynamicImportPath)" />
<!-- Source/Resx etc... -->
</Project>
创建便携式 Class 库时,您需要将库创建为 Windows 8.1 便携式库,您不能为此使用通用库,这听起来像是Xamarin 的约束。 Windows 8.1 可移植库是一种混合库,它允许 classic .net 与新的轻量级 .net 版本进行通信。
便携式 Class 库的问题是它无法通过项目引用引用 Classic Class 库,您只能通过 DLL 引用来引用它。如果您对编辑该文件感到不自在,则无需弄乱 XML,只需找到已编译的 DLL 并手动添加引用即可。如果您选择这样做,您将需要手动更新构建依赖项,否则您可能会破坏引用。
问题似乎不完全在您的 .csproj 中,但也在您的 project.json 中。我注意到 visual studio 没有生成正确的 project.json 文件。我必须修改 UI 中的目标才能使其正确生成。一旦我得到初始 project.json 生成,我就没有其他问题。
在做任何事情之前,我们需要连接我们的便携式 Class 库来处理 Classic Class 库。第一步是将目标框架从属性更新为目标 .net 4.5 或您喜欢的任何版本。
执行此操作后确认 project.json 文件如下所示:
{
"supports": {},
"dependencies": {},
"frameworks": {
".NETPortable,Version=v4.5,Profile=Profile259": {}
}
}
一旦您的便携式 Class 库以正确的版本为目标,您就可以将 DLL 引用添加到已编译的 .net 4.5 程序集。我没有对可移植 class 库的 csproj 文件进行任何其他更改,但这是该文件的源代码,因此您可以查看。
注意如何引用 ClassLibrary1:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.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>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7C4EB968-4C17-438C-B981-97EDC865F312}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>PortableLibrary</RootNamespace>
<AssemblyName>PortableLibrary</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<TargetFrameworkProfile>Profile259</TargetFrameworkProfile>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
</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>
<Compile Include="Class1.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="ClassLibrary1">
<HintPath>..\ClassLibrary1\bin\Debug\ClassLibrary1.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<None Include="project.json" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
假设您的 Web 项目是 ASP.NET Core 1.0,这应该可以消除问题。如果您是 运行 Classic ASP.NET 应用程序,您可能仍然需要创建构建规则。
TLDR:
您的 project.json 文件似乎有问题,请确保它已正确生成并且您不能通过项目引用直接引用 .net 4.5,您必须引用 DLL。
要根据配置回答关于使项目成为 "Portable" 或 "Normal" 的问题,当弹出的错误是关于 <TargetFrameworkIdentifier>
必须是 .NETPortable
:
从配置中删除所有 <ProjectTypeGuids>
。
那些项目类型的 GUID 给 Visual Studio 一些只与可移植项目有关的 GUI 东西,所以当配置不可移植时,它会导致你得到的错误。但是由于您可以轻松地编辑 XML,所以您显然不需要那些东西。另外,您可以继续使用 GUI 编辑项目属性,删除项目类型 GUID。
至少截至 Visual Studio 2015 年。