Web Deployment Projects targeting x64

I am working on an ASP.NET web application which has mixed-mode C++/CLI dependencies that call out to pure unmanaged DLLs. A new requirement is a 64-bit version of the application (it runs fine on Win64 in a IIS 32-bit app pool, but since 32-bit mode is an all-or-nothing proposition, it was decided we need a true 64 bit app.)

I ran into a problem getting the Visual Studio Web Deployment Project to compile my app. It seems that aspnet_compiler.exe loads all of the dependencies during compilation, and the 32 bit compiler cannot load the 64 bit images (you get a "bad image format" error.) This is true even on Win64 build machines that have the .NET Framework64 (and therefore the 64-bit aspnet_compiler.exe)

After a bit of spelunking through the .wdproj, I found that a relatively simple change to the MSBUILD file shipped with the WD project will allow this to work out. It simply forces MSBUILD to use the 64 bit compiler if the $(Platform) variable is set to "x64"

Here is how to do it:
  1. Find the install directory for the Web Deployment Project MSBUILD scripts. On my system, this is:
    c:\Program Files (x86)\MSBuild\Microsoft\WebDeployment\v9.0
  2. Edit (or better yet, edit a copy) of Microsoft.WebDeployment.targets.

    Change this section of the file (around line 524 of the source in the version I have):

    <PropertyGroup>
    <PrecompDependsOn>
    _PrepareForBuild;
    </PrecompDependsOn>
    <AspNetToolPath Condition=" '$(Platform)' == 'x64'">$(windir)\Microsoft.NET\Framework64\$(FrameworkVersion)</AspNetToolPath></PropertyGroup>

    <Target Name="AspNetCompiler" DependsOnTargets="$(PrecompDependsOn)">
    <AspNetCompiler
    PhysicalPath="$(_AspNetCompilerSourceWebPath)"
    TargetPath="$(TempBuildDir)"
    VirtualPath="$(_AspNetCompilerVirtualPath)"
    Force="$(_Force)"
    Debug="$(DebugSymbols)"
    Updateable="$(EnableUpdateable)"
    KeyFile="$(_FullKeyFile)"
    KeyContainer="$(_AspNetCompilerKeyContainer)"
    DelaySign="$(DelaySign)"
    AllowPartiallyTrustedCallers="$(AllowPartiallyTrustedCallers)"
    FixedNames="$(_AspNetCompilerFixedNames)"
    Clean="$(Clean)"
    MetabasePath="$(_AspNetCompilerMetabasePath)"
    ToolPath="$(AspNetToolPath)"/>

    I added the definition of the AspNetToolPath property, which points to the .NET Framework64 directory. I also added the ToolPath attribute to the AspNetCompiler element, and set its value to be the value of my AspNetToolPath property. Note that ToolPath will be blank if $(Platform) is something other than x64, which will result in the default 32 bit compiler being used.

Comments

Steve said…
I ran into similar issues as this, but was able to compile on a 64-bit OS by explicitly using a 64-bit compiler command prompt when doing the build. Changes were not required to the msbuild files.
Unknown said…
Hi,The Msdeploy.exe command-line executable file with Web Design Cochin that implements Web Deploy functionality contains many powerful features. A Web Deploy verb specifies the action to be taken, such as synchronization Thanks.......
Farinha said…
This seems to kind of work for me, except the $(FrameworkVersion) bit. It seems to not resolve to anything. I know I could just put in the value, but I don't want to be hard-coding it. Any idea what could be causing it to be missing?
jlew said…
@Farinha I wouldn't be surprised if the landscape had changed somewhat since this was written in 2009, but I don't have any better answer, sorry.
Gaz said…
The following worked well for me.

$([Microsoft.Build.Utilities.ToolLocationHelper]::GetPathToDotNetFramework('TargetDotNetFrameworkVersion.VersionLatest', 'DotNetFrameworkArchitecture.Bitness64'))

Popular posts from this blog

ElasticSearch Head-Only Plugins

WCF has its own web server!