Sunday 26 April 2009

Targeting x64 Program Files Directory with VS Setup Projects

If you’ve been working in an x64 environment for a while now this will probably be old news to you; if, like us, you’re finally moving across and you’re using Visual Studio setup projects, you may need to tweak some settings to get files going where they’re supposed to go. Especially if you’re installing to the Program Files directory.

One of our solutions employs a setup project to install a bunch of static files (primarily image, JavaScript, CSS, and Flash files) to SharePoint’s 12-hive. We use a separate installer for this because it considerably simplifies the WSS solution file and reduces .wsp/.cab build time.  I’ve just got to remember to update the version number every time we send a build off to IT for deployment ;-) I’ll also mention we point a virtual directory at this location so we could install this content anywhere.

The path to the 12-hive is said to be burned into every SharePoint developer’s brain so of course you know it resides under Program Files by default. In an x86 setup project, you can either drop files into the Program Files Folder—which is hard coded to use the special ProgramFilesFolder property (a variable containing the path to your Program Files directory) or you can configure the DefaultLocation property of the Application Folder to point to any location and use the special folder variables as tokens like this:

[ProgramFilesFolder]Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\

Why not use the Program Files Folder? The install path is built up using the properties configured at the setup project level, such as Manufacturer, and don’t offer much flexibility to install to the 12-hive—even though it does sit under /Program Files.

This all works beautifully in our x86 environment but running the same installer in an x64 environment (Windows Server 2008) resulted in our sites breaking because the installed static resources couldn’t be found. The underlying reason for this was because the Application Folder was configured as described above and the ProgramFilesFolder variable was being replaced at install time by the x86 version of the Program Files path (ie. “c:\Program Files (x86)”). This can be overridden by the administrator but that’s not very friendly. Simply changing the TargetPlatform property on the setup project from x86 to x64 won’t help.

To correct this problem, the DefaultLocation property of the Application Folder was updated from ProgramFilesFolder to ProgramFiles64Folder and the TargetPlatform property of the setup project changed to x64. If you forget to do the latter you’ll receive one of the following errors at build time:

The destination path of folder 'Application Folder' is not compatible with the project's target platform 'x86'

The destination path of folder 'Program Files (64-bit) Folder' is not compatible with the project's target platform 'x86'

 x64 seploy project application folderx64 setup project application folder DefaultLocation x64 setup project TargetPlatform

We’re not using the Program Files (x64) Folder or the Program Files Folder folders so despite what the first images shows, I actually remove them to simplify maintenance.

My own confusion stems from the fact 64-bit Windows can run both x86 and x64 applications but they install to different locations. I think of it this way:

  x86 x64
Setup Project [ProgramFilesFolder] [ProgramFiles64Folder]
Windows x86 Program Files N/A
Windows x64 Program Files (x86) Program Files

In our case, we’re actually in the middle of a transition to x64: prod is running x86 and new prod, which is under construction, is running x64. On top of that our dev VMs are still x86. A setup project can only target a single architecture (sort of) so our solution was to simply add a second setup project. The first project remains untouched and we use it regularly at the moment; the second project targets x64 and we build it only when required (it’s only configured to build in the Release configuration). A VS solution can host multiple setup projects so there’s no problem with this arrangement.

Finally, it should be noted the Platform target of the source project that feeds content files into the setup project is configured as “Any CPU”. Since we’re not installing assemblies this doesn’t seem to matter. By was of a side note, the project containing our web parts and feature receivers is also configured to target Any CPU; MOSS obviously installs the related DLLs to the local IIS bin directories (IIS 7.0) but we’ve so far had no need to specifically configure these projects to output x64 assemblies. The beauty of .NET and the CLR at work? Dunno… but if not why are the options present?

7 comments:

  1. Great tip - thanks for sharing.

    ReplyDelete
  2. Thanks for sharing.

    ReplyDelete
  3. Thanks! I couldn't find the ProgramFiles64Folder variable name anywhere and was trying to guess it.... ProgramFiles-x64, ProgramFilesFolder(x64), etc....

    ReplyDelete
  4. Thank you. IT was very helpful

    ReplyDelete
  5. Thank you Michael, I created an installer for x64 platform first. Later I was trying to duplicate same installer project and tinker it to fit for x86 but this stupid Application Files error showed up.
    Your post was of great help.

    ReplyDelete
  6. Thank You... I was getting frustrated as I was changing the Target Platform of the Project to 64 but was missing the fact that I also needed to change it on the Setup

    ReplyDelete

Spam comments will be deleted

Note: only a member of this blog may post a comment.