我能否在Visual Studio Express中加载一个“有时可移植”的类库项目?

38
对于 Noda Time 版本1.1,主要目标是构建可移植类库版本,主要支持Windows Phone和Windows Store应用程序。这意味着失去了一些功能,因此我们构建了桌面配置和PCL配置(分别为调试、发布和“签名发布”)。
为了避免使用无数个项目文件,所有6个配置都存在于同一个项目文件中。项目文件 被定制为生成一个称为“可移植性”的属性,该属性设置为“PCL”或“桌面”,如下所示:
<!-- Set the custom Portability property based on configuration -->
<PropertyGroup>
  <Portability Condition="'$(Configuration)' == 'Debug Portable'">PCL</Portability>
  <Portability Condition="'$(Configuration)' == 'Release Portable'">PCL</Portability>
  <Portability Condition="'$(Configuration)' == 'Signed Release Portable'">PCL</Portability>
  <!-- Default to desktop if not explicitly set above -->
  <Portability Condition="'$(Portability)' == ''">Desktop</Portability>
</PropertyGroup>

我们基于上述属性为便携式和桌面设备分别创建了不同的属性组。这就是将项目类型定义为 "类库" 或 "可移植类库" 的方法(除此之外,还需要共享的 OutputType 属性值为 Library)。
<!-- Desktop-specific properties -->
<PropertyGroup Condition="'$(Portability)' == 'Desktop'">
  <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
  <TargetFrameworkProfile>Client</TargetFrameworkProfile>
</PropertyGroup>

<!-- PCL-specific properties -->
<PropertyGroup Condition="'$(Portability)' == 'PCL'">
  <MinimumVisualStudioVersion>10.0</MinimumVisualStudioVersion>
  <ProjectGuid>{c78f6992-28d7-45c9-a4c1-6eaa649f3247}</ProjectGuid>
  <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
  <TargetFrameworkProfile>Profile2</TargetFrameworkProfile>
  <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
</PropertyGroup>

这通常非常有效 - 我有不同的解决方案配置,所以我可以随时构建和测试所有内容,我只需要将每个新的 .cs 文件添加到一个项目文件中。因此,在Visual Studio 2012 Professional(这是我使用的)下,我非常满意。 问题出现在我尝试在Visual Studio Express(无论是VS2010还是VS2012)中加载解决方案时。当解决方案正在加载时,它会失败并显示错误,说某些项目无法加载,并且构建PCL版本的两个项目则具有以下构建输出:
C:\Path\To\NodaTime.csproj : error  :
     The project file 'C:\Path\To\NodaTime.csproj' cannot be opened.

There is a missing project subtype.
     Subtype: '{786C830F-07A1-408B-BD7F-6EE04809D6DB}'
     is unsupported by this installation.

(为了更清晰地排版,重新格式化。) 这两个项目无法加载,因此您甚至无法浏览源代码。
我曾经真的希望即使 Express 用户无法构建 PCL 版本,他们仍然能够加载解决方案,浏览源代码并构建非 PCL 版本。MSBuild 可以从命令行工作,但这不太友好。
我尝试删除引用 PCL 项目配置的解决方案配置,但这并没有帮助。奇怪的是,即使注释掉 XML 元素,就像这样:
<!-- 
    <ProjectTypeGuids>(Guids as before)</ProjectTypeGuids>
 -->

删除该行并不能解决问题,似乎Visual Studio没有将其作为真正的XML文件加载。(我还没有尝试将注释掉的元素版本加载到VS Pro中。)

如果必要的话,我可以生成单独的PCL项目文件,但我很想避免这样做——它会使正常开发更加痛苦。同样,我也可以生成仅限于Express的PCL和解决方案文件,但我宁愿不这样做——感觉不太对。

虽然理想情况下我希望支持VS Express 2010和2012,但如果有一种只适用于2012的解决方案,那也是一个好的开始。

那么,有没有办法说服Visual Studio Express,即使条件属性组(其条件未满足)引用了它不知道的项目类型,它仍然可以加载项目?


除了关于VS尝试加载已注释的xml片段的部分外,这确实看起来像Express版的目的:无论当前配置是否使它们处于活动状态,您都无法使用不受支持的项目类型。不确定我理解为什么你觉得这很奇怪。将其与携带工作簿参加考试并发誓不使用它进行比较。因此,首先要防止这种情况发生。 - Simone
这种行为与我在运行于Win7机器上的VS 2012 Premium尝试加载针对WinRT(以及其他平台)的PCL时所经历的类似。Visual Studio无法打开该项目并显示类似的消息,但在Windows 8机器上相同的项目可以正常打开。我觉得这种行为很不稳定,因为即使我不能在Win7下开发WinRT应用程序,但这是一个可移植库,因此应该可以在任何它旨在支持的平台上访问。似乎项目清单中的可移植配置文件会让VS认为它不支持某些内容。 - Vagif Abilov
@VagifAbilov:我在安装了VS专业版的Windows 8电脑上也遇到了相同的问题。 - Jon Skeet
5
<ProjectTypeGuids> 是一个属性,指示 VS 在打开给定项目文件时加载哪个项目系统。显然,读取它的东西如果仍然看到它是注释,就不是真正的 XML 读取器。这里存在一些鸡生蛋的问题;项目系统读取 XML,但 VS 不知道要加载哪个项目系统,直到它自己读取此属性- 这是一个真正的 hack。 - David Kean
2
我认为没有办法做到你想要的 - 你需要将可移植项目分成单独的项目,或完全删除<ProjectTypeGuid>元素 - 这将使你放弃“可移植”增强功能,例如用于更改目标框架的UI等。作为一个完全的侧面说明,我真的建议你不要将可移植视为单独的构建,而是拥有一个可移植的核心,然后为桌面特定功能创建单独的程序集。看看RX扩展在v2中所做的示例,就知道我的意思了。 - David Kean
显示剩余9条评论
2个回答

10

David Kean在这里的评论给了我目前正在使用的答案:

或者完全删除<ProjectTypeGuid>元素-这将使您退出“可移植”增强功能,例如用于更改目标框架的UI等

我已经尝试过这个方法,它像梦想一样工作。在已安装所有必要组件的计算机上,您甚至可以在Express下构建PCL版本!我已验证生成的二进制文件确实是PCL,并且看起来很好。

我不会感到惊讶,如果以后出现了一些问题,但目前这对我来说还不错。我可以轻松地在Visual Studio中没有增强功能 - 因为我的项目已经具有非常不同的构建配置,所以我认为我也没有得到太多的好处。


3

如下所述:
Visual Studio 2012 Express with Portable Class Library?
以及这里:
Share functionality using Portable Class Libraries

Express SKU不支持可移植类库项目...需要更高的SKU来获得完整支持。当然,二进制文件(例如,将其用作引用)是可以的,只是没有项目/源代码支持。

我可以想象出一个简单的原因 - VS2012 Express版本有不同的类型:用于Windows Phone开发、桌面应用程序、Windows 8应用程序......我敢打赌,Windows Phone Express版本不知道Windows Phone项目类型,反之亦然。这可能是PCL也不受支持的简单原因。

虽然可移植类库的想法确实很好,但在许多方面仍然相当有限,例如,据我所知,您不能使用条件编译#if xy。如果您真的必须使用Visual Studio Express进行开发,那么最好使用每个平台的项目,带有引用的源文件和条件编译。


我并不希望Express真正支持PCL,只是加载一个具有构建PCL的某些特性的项目。删除“ProjectTypeGuids”元素似乎可以解决这个问题... 我需要进一步实验。 - Jon Skeet
也许有一种方法可以检测Visual Studio的类型,例如检测WP8的VS Express,并使用项目文件条件将项目类型从PCL更改为WP8? - Martin Suchan
我已经在项目文件中使用了条件部分:即使在没有任何配置使用PCL的解决方案中,你也无法将其加载。仅元素的存在就会引起问题 :( - Jon Skeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接