Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I get a "sometimes portable" class library project to load in Visual Studio Express?

For Noda Time version 1.1, the main goal is to build a Portable Class Library flavour, primarily to support Windows Phone and Windows Store apps. This means losing some functionality, so we build a desktop configuration and a PCL configuration (for each of debug, release, and "signed release").

To avoid having to work with umpteen project files, all of the 6 configurations exist in the same project file. The project file is customized to generate a property called "Portability", which is set to either "PCL" or "Desktop", like this:

<!-- 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> 

We then have separate property groups for portable vs desktop, based on the above property. This is what defines the project type as "class library" or "portable class library" (along with the OutputType of Library, which is shared):

<!-- 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> 

This generally works very well - I have the different solution configurations, so I can build and test everything at a moment's notice, and I only need to add each new .cs file to a single project file. So under Visual Studio 2012 Professional (which is what I use) I'm perfectly happy.

The problem comes when I try to load the solution in Visual Studio Express (either VS2010 or VS2012). While the solution is loading, it fails with an error to say that some projects can't be loaded, and the two projects which build PCL versions then have build output like this:

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. 

(Reformatted for clarity.) The two projects refuse to load, so you can't even browse the source code.

I had really hoped that even if Express users couldn't build the PCL versions, they'd still be able to load up the solution, browse the source, and build non-PCL versions. MSBuild works from the command line, but that's not as friendly.

I've tried removing the solution configurations which refer to the PCL project configurations, and that doesn't help. Weirdly enough, even commenting out the XML element, like this:

<!--      <ProjectTypeGuids>(Guids as before)</ProjectTypeGuids>  --> 

doesn't help - although deleting the line does. It's as if Visual Studio isn't actually loading it as a real XML file. (I haven't tried loading the version with the commented out element into VS Pro.)

I could go down the route of generating separate PCL project files if I need to, but I'd really like to avoid it if possible - it would make normal development more painful. Likewise I could generate Express-only PCL and solution files, but again I'd rather not - it just feels wrong.

While ideally I'd like to support VS Express both 2010 and 2012, if there's a solution which only works for 2012, that would be a good start.

So, is there any way of persuading Visual Studio Express that it really can load a project despite a conditional property group (whose condition isn't met) referring to a project type it doesn't know about?

like image 306
Jon Skeet Avatar asked Jan 27 '13 20:01

Jon Skeet


People also ask

How do I add a class library to Visual Studio project?

Right-click on the solution in Solution Explorer and select Add > New Project. On the Add a new project page, enter library in the search box. Choose C# or Visual Basic from the Language list, and then choose All platforms from the Platform list. Choose the Class Library template, and then choose Next.

What is portable class library in C#?

The Portable Class Library project enables you to write and build managed assemblies that work on more than one . NET Framework platform. You can create classes that contain code you wish to share across many projects, such as shared business logic, and then reference those classes from different types of projects.

How do I add a class library in Visual Studio 2015?

Open your Visual Studio 2015 preview, go to the file menu, go to the new, go with the project, from the template field select C#, select Class Library then name it as you want. Save it at an appropriate place.

What is class library in Visual Studio?

A class library is a collection of class definitions contained in a . dll or .exe file. In order to use the class library, you must first add a reference to the library (see "How to add references to your Visual Studio Project").


2 Answers

David Kean's comment here gave me the answer I'm using for the moment:

or remove the <ProjectTypeGuid> element entirely - this will opt you of "portable" enhancements, such as a UI for changing the target framework, etc

I've tried that, and it works like a dream. On machines which have everything appropriately installed, you can then even build the PCL version under Express! I've verified that the resulting binary really is a PCL, and it seems fine.

I wouldn't be surprised to find that I ran into some problems later on, but for the moment this works fine for me. I can easily live without the enhancements in Visual Studio - it was already confused by my project having very different build configurations, so I don't think I was getting much benefit anyway.

like image 88
Jon Skeet Avatar answered Oct 21 '22 10:10

Jon Skeet


As answered here:
Visual Studio 2012 Express with Portable Class Library?
and here:
Share functionality using Portable Class Libraries

Portable Class library projects are not supported in the express SKU...need a higher SKU for the full support. Of course the binary (e.g., using it as a reference) is, just not the project/source support.

I can imagine there is a simple reason for that - there are different types of VS2012 Express editions: for Windows Phone development, for Desktop apps, for Windows 8 apps... I bet the Windows Phone Express edition does not know about the Windows Phone project type and vice versa. This could be the simple reason why PCLs are not supported as well.

Although the idea of Portable Class Libraries is really nice, it's still quite limited in many ways, for instance you cannot use conditional compilation using #if xy as far as I know. If you really have to use Visual Studio Express for development, then it might be better to use projects for each platform with referenced source files and conditional compilation.

like image 24
Martin Suchan Avatar answered Oct 21 '22 12:10

Martin Suchan