tags:

views:

176

answers:

4

Hello all,

I would like to be able to use .NET 3.5 types in an application based on .NET 2.0. Basically we don't have deployed .NET 3.5 libraries in desktops but we need to use some classes from there. Any ideas how this is possible ?

Thanks, Marios

+1  A: 

Not at all. You will need .NET Runtime 3.5 on a machine if you want to run .NET 3.5 code. You will need to create projects that do not rely on 3.5 if you deploy to machine with 2.0.

Here is some info on how to create projects targeting .NET 2.0 with VS2008.

http://weblogs.asp.net/scottgu/archive/2007/06/20/vs-2008-multi-targeting-support.aspx

Igor Zevaka
I heard about a way to extract the IL from 3.5 classes, and regenerate C# code. Not sure if this is true.
koumides
That sounds way harder than to work around the missing functionality on .NET 2.0. Is it LINQ that you want by any chance? In that case you are screwed. Still though, it'd be easier to replace it with something else than to hack the IL (if that's even possible).
Igor Zevaka
Linq can be used when deploying to .NET 2.0 (SP1) targets. There are several possibilities to do so, you can e.g. use LinqBridge (http://www.albahari.com/nutshell/linqbridge.aspx) or the approach described in http://linqinaction.net/blogs/main/archive/2007/09/05/linq-support-on-net-2.0.aspx
0xA3
I stand corrected on that, thanks for the info divo.
Igor Zevaka
+2  A: 

What types do you want to use? It might theoretically be possible to use certain types because .NET 3.5 assemblies are compiled for the .NET 2.0 runtime. However, be aware that normally .NET 3.5 assemblies will require the .NET 3.5 Framework to be installed as there is more in .NET 3.5 than just the assemblies (e.g. services for WPF etc).

If you don't want to deploy the .NET 3.5 Framework with your application, I suggest you to have a look at the .NET 3.5 Client profile, a reduced variant that will be sufficient for most desktop applications.

0xA3
+1  A: 

There's nothing really special about .NET 3.5, it is just a bunch of added assemblies (like Linq). Same for .NET 3.0 (like WPF). .NET frameworks 2.0 through 3.5 SP1 still use the same version of the CLR, version 2.0.

So it is a very conscious decision to make your program depend on .NET 3.5, it requires Project + Add Reference and selecting an assembly that has a 3.5.0.0 version number. Once you do that, your client needs to have that same assembly installed on her machine. Which requires the .NET 3.5 version of the framework to be installed on her machine.

Most clients already have it, it got distributed by Windows Update.

Hans Passant
"It is just a bunch of assemblies": Surely there are plenty of new assemblies (and the runtime is the same), but don't forget that there might be additional registry keys, COM or native dependencies or services like PresentationFontCache that need to be set up.
0xA3
+1  A: 

This question got me wondering, so I dug into it a bit.

The answer to your question depends on how many dependencies you have on the new frameworks, and how much hacking you are willing to do.

The real best answer is to bite the bullet and install the necessary framework. However, if you need to just distribute a single assembly from .net 3.0 it may be possible. I'm pretty sure, requiring an assembly from 3.5 will require installing 3.0. At that point, you have nothing to gain by not installing 3.5.

Here's the hacking I did to make an assembly from 3.0 work from 2.0:

Hack # 1 Add the reference to the required 3.0. Visual Studio should complain. Unload the project and edit the project file. Remove this line from the xml and reload the project.

<RequiredTargetFramework>3.0</RequiredTargetFramework>

Visual Studio will happily compile and run with this assembly now.

Hack # 2 Change the copy local property in the assembly references list to true.

Hack # 3 (Ugliest hack) Modify the machine config to add the config section for the required assembly. This may or may not be required, depending on the assembly you are pulling in. In my test, I referenced the System.Runtime.Serialization assembly and needed to copy this section from the machine.config on my 3.5 machine to my 2.0 machine.

<sectionGroup name="system.runtime.serialization" type="System.Runtime.Serialization.Configuration.SerializationSectionGroup, System.Runtime.Serialization, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
    <section name="dataContractSerializer" type="System.Runtime.Serialization.Configuration.DataContractSerializerSection, System.Runtime.Serialization, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

Once I did that, the following code ran just fine on my .net 2.0 box.

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        try
        {
            Console.WriteLine("Testing serialization");

            DataContractSerializer formatter = new DataContractSerializer(typeof(Junk));
            MemoryStream stream = new MemoryStream();

            Junk junk = new Junk();
            junk.Name = "Junk";
            junk.Value = 15;

            formatter.WriteObject(stream, junk);
            Console.WriteLine("Wrote object to stream");

            stream.Seek(0, SeekOrigin.Begin);

            Junk savedJunk = formatter.ReadObject(stream) as Junk;

            Console.WriteLine("Deserialized name = {0}", savedJunk.Name);
            Console.WriteLine("Deserialized value = {0}", savedJunk.Value);

            Console.WriteLine("Testing complete");
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            Console.WriteLine(ex.StackTrace);
        }
    }
}

[DataContract]
class Junk
{
    [DataMember]
    public string Name = "";
    [DataMember]
    public int Value = 0;
}

...again, I'm not recommending this. But, it may be possible to bend the rules if you are really desperate.

Scott P