views:

507

answers:

5

I have a c# .net winforms solution and I want to create two different builds: one that supports IE6 and one that supports IE7. A few of the files in one of my projects are different for the IE6 build versus the IE7 build, so I want to include the IE6 files when I build for IE6 and the IE7 files when I build for IE7. What's the best way of structuring my solution for this situation?

Due to other constraints I do not want to create a separate assembly that contains the shared items; I want the project to compile to a single assembly 'foo.dll' regardless of which build I'm making.

I thought I could just create two separate projects that compile to 'foo.dll', then create two Release Configurations and only include the relevant project in the relevant configuration. However I'd need to include the files that are the same for IE6 and IE7 in both projects, and I can't see how to use a single copy of a file in two projects (when I Add Existing Item it creates a copy in the project directory). I'm using SVN for source control so could perhaps use that to do the 'sharing' between folders, but doubt that's the best way..

NB: Different builds are needed due to API differences in IE, details of which aren't relevant to the question - just believe me that there are two builds required.

A: 

Why not use conditional CSS statements instead of building separate projects for different versions of a browser?

<!--[if lte IE6]> <style type="text/css">@import "IE6-override.css";</style> <![endif]-->
<!--[if gte IE 7]> <style type="text/css">@import "IE7-override.css";</style> <![endif]-->
Chris Ballance
It really depends on what is different between the IE6 and IE7 versions.
Andy
I think he's talking about compiling with different source for each version, not just using different css files.
Kevin Tighe
Windows forms uses CSS? thats a new one.
StingyJack
If you're using a browser, you can use CSS
Chris Ballance
A: 

I'm not sure how to do what you're asking, but couldn't you just include both versions of your API wrapper in the dll and determine which one to call at runtime? For example, what if a user installs the IE6 version of your app then upgrades to IE7? They'll need to reinstall, right?

It seems to me like this would be a much simpler solution, but maybe I'm missing something...

Kevin Tighe
Since I'm hooking into an API provided by IE that is different in different versions there are various issues that come up with referencing the APIs, as well as having different interop assemblies and so forth... It's just simpler to compile two versions with slightly different code.
Rory
Oh, too bad :(. Looks like Coincoin's answer will do what you want though.
Kevin Tighe
+3  A: 

In MSBuild, you can specify conditions to item groups. You can then bind those conditions to the target device.

Example:

<!-- Declare the condition property at the beggining of the build file -->
<PropertyGroup Condition="$(Platform) == 'IE7'">
  <UseNewLibrary>true</UseNewLibrary>
</PropertyGroup>

<PropertyGroup Condition="$(Platform) == 'IE6'">
  <UseNewLibrary>false</UseNewLibrary>
</PropertyGroup>


<!-- Then those the property to select the right file -->
<ItemGroup Condition="$(UseNewLibrary)==true">
  <Compile Include="Class1.cs"/>
  <Compile Include="Class2.cs"/>
  <Compile Include="Class3.cs"/>
  <Compile Include="Class4.cs"/>
</ItemGroup>

<ItemGroup Condition="$(UseNewLibrary)==false">
   <Compile Include="Class1Old.cs"/>
   <Compile Include="Class2Old.cs"/>
   <Compile Include="Class3Old.cs"/>
   <Compile Include="Class4Old.cs"/>
</ItemGroup>

<!-- And now references -->
<ItemGroup Condition="$(UseNewLibrary)==true">
  <Reference Include="MyAssembly, Version=1.1.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</ItemGroup>

<ItemGroup Condition="$(UseNewLibrary)==false">
  <Reference Include="MyAssembly, Version=1.0.6.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</ItemGroup>

Note that all files will appear in the IDE, but at compile time everything should align correctly.

Then, all you need to do is create your platforms (IE6 and IE7) in the configuration management.

You can also directly use the platform property instead of creating an intermediate property.

Coincoin
How do I create my platforms in the configuration management? Visual Studio 2005 doesn't let me add new Project Platforms, it only gives me the x86 and x64 and AnyCPU options.
Rory
I have 2008 so it might be a ltitle different but you go in configuration manager, then in the Platform dropdown a <new> options is there. It will pop a window with a combo box that can be edited by hand.
Coincoin
Yeah, I can add Platforms for the Solution, but for each Project I'm limited to the options they have. I guess that makes sense if it's actually passed to the compiler with the /platform option. I'll just use different Configurations instead.
Rory
You might have to add the possible configuration in the solution file. It's a pain since a lot of combination of configuration|platform might exist.What you can also do if you don't really care about have the config in the IDE is just change them by hand and when you release you build both.
Coincoin
This can be done using msbuild /p:name=value
Coincoin
+1  A: 

In order to add the same file in two or more projects you can

Right click on the project and choose Add >> Existing Item
Choose the file in the filepicker
Click the little triangle on the right side of the Add button in the file picker
Choose Add As Link

This will add the file to the project without making a copy of it.

I don't know all the details of your situation, but you're solution sounds awkward. Two versions of the same dll is likely to lead to configuration problems on client computers eventurally. I encourage you to consider Kevin's idea of a single dll with all capabilities, and calling the appropriate code as needed.

ScottS
+1  A: 

Assuming you are using VS2005 or above you can use the Condition property in the project file.

You'll need to edit the csproj file directly

  1. Unload project
  2. Edit

then on the files you want to conditionally include

<Compile Include="IE6.cs" Condition=" '$(Platform)' == 'IE6' " />
<Compile Include="IE7.cs" Condition=" '$(Platform)' == 'IE7' " />
<Compile Include="IE.cs"  />
Scott Weinstein