I have a little dilemma on how to set up my visual studio builds for multi-targeting.
Background: c# .NET v2.0 with p/invoking into 3rd party 32 bit DLL's, SQL compact v3.5 SP1, with a Setup project. Right now, the platform target is set to x86 so it can be run on Windows x64.
The 3rd party company has just released 64 bit versions of their DLL's and I want to build a dedicated 64bit program.
This raises some questions which I haven't got the answers to yet. I want to have the exact same code base. I must build with references to either the 32bit set of DLL's or 64bit DLL's. (Both 3rd party and SQL Server Compact)
Can this be solved with 2 new sets of configurations (Debug64 and Release64) ?
Must I create 2 separate setup projects(std. visual studio projects, no Wix or any other utility), or can this be solved within the same .msi?
Any ideas and/or recommendations would be welcomed.
If you use Custom Actions written in .NET as part of your MSI installer then you have another problem.
The 'shim' that runs these custom actions is always 32bit then your custom action will run 32bit as well, despite what target you specify.
More info & some ninja moves to get around (basically change the MSI to use the 64 bit version of this shim)
Building an MSI in Visual Studio 2005/2008 to work on a SharePoint 64
64-bit Managed Custom Actions with Visual Studio
Regarding your last question. Most likely you cant solve this inside a single MSI. If you are using registry/system folders or anything related, the MSI itself must be aware of this and you must prepare a 64bit MSI to properly install on 32 bit machine.
There is a possibility that you can make you product installed as a 32 it application and still be able to make it run as 64 bit one, but i think that may be somewhat hard to achieve.
that being said i think you should be able to keep a single code base for everything. In my current work place we have managed to do so. (but it did took some juggling to make everything play together)
Hope this helps. Heres a link to some info related to 32/64 bit issues: http://blog.typemock.com/2008/07/registry-on-windows-64-bit-double-your.html
You can generate two solutions differently and merge them afterwards! I did this for VS 2010. and it works. I had 2 different solutions generated by CMake and I merged them
Let's say you have the DLLs build for both platforms, and they are in the following location:
You simply need to edit your .csproj file from this:
To this:
You should then be able to build your project targeting both platforms, and MSBuild will look in the correct directory for the chosen platform.
You can use a condition to an ItemGroup for the dll references in the project file.
This will cause visual studio to recheck the condition and references whenever you change the active configuration.
Just add a condition for each configuration.
Example:
Yes, you can target both x86 and x64 with the same code base in the same project. In general, things will Just Work if you create the right solution configurations in VS.NET (although P/Invoke to entirely unmanaged DLLs will most likely require some conditional code): the items that I found to require special attention are:
The assembly reference issue can't be solved entirely within VS.NET, as it will only allow you to add a reference with a given name to a project once. To work around this, edit your project file manually (in VS, right-click your project file in the Solution Explorer, select Unload Project, then right-click again and select Edit). After adding a reference to, say, the x86 version of an assembly, your project file will contain something like:
Wrap that Reference tag inside an ItemGroup tag indicating the solution configuration it applies to, e.g:
Then, copy and paste the entire ItemGroup tag, and edit it to contain the details of your 64-bit DLL, e.g.:
After reloading your project in VS.NET, the Assembly Reference dialog will be a bit confused by these changes, and you may encounter some warnings about assemblies with the wrong target processor, but all your builds will work just fine.
Solving the MSI issue is up next, and unfortunately this will require a non-VS.NET tool: I prefer Caphyon's Advanced Installer for that purpose, as it pulls off the basic trick involved (create a common MSI, as well as 32-bit and 64-bit specific MSIs, and use an .EXE setup launcher to extract the right version and do the required fixups at runtime) very, very well.
You can probably achieve the same results using other tools or the Windows Installer XML (WiX) toolset, but Advanced Installer makes things so easy (and is quite affordable at that) that I've never really looked at alternatives.
One thing you may still require WiX for though, even when using Advanced Installer, is for your .NET Installer Class custom actions. Although it's trivial to specify certain actions that should only run on certain platforms (using the VersionNT64 and NOT VersionNT64 execution conditions, respectively), the built-in AI custom actions will be executed using the 32-bit Framework, even on 64-bit machines.
This may be fixed in a future release, but for now (or when using a different tool to create your MSIs that has the same issue), you can use WiX 3.0's managed custom action support to create action DLLs with the proper bitness that will be executed using the corresponding Framework.
Edit: as of version 8.1.2, Advanced Installer correctly supports 64-bit custom actions. Since my original answer, its price has increased quite a bit, unfortunately, even though it's still extremely good value when compared to InstallShield and its ilk...
Edit: If your DLLs are registered in the GAC, you can also use the standard reference tags this way (SQLite as an example):
The condition is also reduced down to all build types, release or debug, and just specifies the processor architecture.