Class Libraries do not work in Windows Azure using Visual Studio 2010

If you create a class library and add a reference to it from an Azure Web Role or Azure Worker Role you get an error. Here’s how to get around it.

The problem is that the class library template for Visual Studio 2010 creates a .csproj file with too few configuration settings. In Visual Studio 2008 the default target platform is AnyCPU. In Visual Studio 2010 it’s x86 and the configuration for AnyCPU is not included. It seems to me this is an error in Visual Studio 2010 Beta 1.

This is what a standard .csproj file excerpt looks like in a class library created in Visual Studio 2008:

  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
As you can clearly see it indicates AnyCPU.

This is what a standard .csproj file excerpt looks like in a class library created in Visual Studio 2010:

  <PropertyGroup>
    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>

This class library will target a x86 platform by default: (Open project Properties –> Build.)

platformtargetx86

Note: Here is a good resource to Platform Targets: Visual Studio .NET Platform Target Explained from Visual Studio Hacks. “The Platform Target setting is meant to communicate the platform that the developer intends to be compatible with.”

The issue then is that when you add a reference to this class library from a standard Windows Azure project you will not be able to run it. The error appears different if you add the reference to the Web Role or the Worker Role.

Let’s reproduce the error! (Start up your Visual Studio 2010)

Create a new Windows Azure Service project (SampleService) with both Web and Worker Role:

standardazureprojectlayout

Create a new Class Library (SampleLib) targeting the .NET Framework 3.5. (Azure does not run on the beta .NET Framework 4.0.)

Build and run your cloud app to make sure you can run before you start adding references.

Add a reference from your Web Role to SampleLib and compile.

This should produce the error: “The OutputPath property is not set for this project.  Please check to make sure that you have specified a valid Configuration/Platform combination.  Configuration='Debug'  Platform='AnyCPU'    C:\Windows\Microsoft.NET\Framework\v4.0.20506\Microsoft.Common.targets    582    10    SampleService”

webroleerror

Remove the reference and compile. (Make sure it compiles again.)

Add a reference from your Worker Role to SampleLib and compile. This appears to work! No error.

Run the application. Still no error.

Now add the following code to the top of your worker role:

public class WorkerRole : RoleEntryPoint
{
    public override void Start()
    {
        new SampleLib.Class1();

Now run the application! Error: “Could not load file or assembly 'SampleLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. An attempt was made to load a program with an incorrect format.”

You can add reference all you want but if you don’t use the code in the library it will not get loaded.

In conclusion you cannot add this Class Library to any of the roles.

Now let’s make it work!

Open your SampleLib.csproj in your editor of choise. For me it is notepad2 for smaller fixes of text based files.

This is likely what the PropertyGroup in your file will look like: (I cut out the <PropertyGroup> element for brevity.)

<PropertyGroup>
  <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
  <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
  <ProductVersion>10.0.20506</ProductVersion>
  <SchemaVersion>2.0</SchemaVersion>
  <ProjectGuid>8fcc762b-a44a-43bc-bea9-0d89f22fbb40</ProjectGuid>
  <OutputType>Library</OutputType>
  <AppDesignerFolder>Properties</AppDesignerFolder>
  <RootNamespace>SampleLib</RootNamespace>
  <AssemblyName>SampleLib</AssemblyName>
  <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
  <FileAlignment>512</FileAlignment>
  <PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
  <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|x86' ">
  <DebugType>pdbonly</DebugType>
  <Optimize>true</Optimize>
  <OutputPath>bin\Release\</OutputPath>
  <DefineConstants>TRACE</DefineConstants>
  <ErrorReport>prompt</ErrorReport>
  <WarningLevel>4</WarningLevel>
</PropertyGroup>

What we have to do is dump the x86 references and replace them with “AnyCPU”. Also we kan just go ahead and kill the <PlatformTarget>x86</PlatformTarget> altogether.

Here is the resulting xml: (Again only the <PropertyGroup> element for brevity.)

<PropertyGroup>
  <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
  <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
  <ProductVersion>10.0.20506</ProductVersion>
  <SchemaVersion>2.0</SchemaVersion>
  <ProjectGuid>8fcc762b-a44a-43bc-bea9-0d89f22fbb40</ProjectGuid>
  <OutputType>Library</OutputType>
  <AppDesignerFolder>Properties</AppDesignerFolder>
  <RootNamespace>SampleLib</RootNamespace>
  <AssemblyName>SampleLib</AssemblyName>
  <TargetFrameworkVersion>v3.5</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>
Make sure you replace three instances of “x86” with “AnyCPU” and remove the tag PlatformTarget. Save and close the file.
Visual Studio will now ask you to reload the project:
filemodificationdetected 
Click “Reload”.
That’s it!
Now your Class Library will have a property page that looks like this under Properties –> Build:
platformtargetAnyCPU 
Now to verify: Add a reference from your Web Role and another reference from your Worker Role to SampleLib.
Compile. Works!
Run. Works!
Now you can fill your Class Library with all that goodness that you want to share between projects!
HTH – Cheers,

M.

This work is licensed under a Creative Commons license.

posted @ Wednesday, June 24, 2009 2:01 PM

Print

Comments on this entry:

# Class Libraries do not work in Windows Azure using Visual Studio 2010 - Magnus M&#229;rtensson

Left by DotNetShoutout at 7/5/2009 1:33 PM
Gravatar
Thank you for submitting this cool story - Trackback from DotNetShoutout

# Windows Azure and Cloud Computing Posts for 7/6/2009

Left by LINQ in Action roller at 7/7/2009 1:32 AM
Gravatar
Windows Azure, Azure Data Services, SQL Data Services and related cloud computing topics now appear in

# re: Class Libraries do not work in Windows Azure using Visual Studio 2010

Left by Erwyn van der Meer at 7/7/2009 8:37 AM
Gravatar
I also ran into a similar issue, check out bloggingabout.net/.../...es-on-64-bit-windows.aspx. I read and heard from Microsoft that this a VS2010 beta 1 issue only (check out the links in my blog post). For later versions the default for class libraries will be AnyCPU again.

# re: Class Libraries do not work in Windows Azure using Visual Studio 2010

Left by Ronald Widha at 10/5/2009 5:59 AM
Gravatar
good spot! thanks

# re: Class Libraries do not work in Windows Azure using Visual Studio 2010

Left by Matt Honeycutt at 7/25/2011 3:32 AM
Gravatar
This is an old post, but it still just saved me a ton of hair pulling. Thanks!

Your comment:



 (will not be displayed)


 
 
 
Please add 8 and 1 and type the answer here:
 

Live Comment Preview: