Using .NET 3.5 features without installing .NET 3.5

by AaronPowell 23. February 2010 03:48

I recently worked on a project for a client which the deployment environment was only to have .NET 2.0 installed. This is a rarity these days, after all .NET 3.5 was released in November 2007 (http://en.wikipedia.org/wiki/.NET_Framework#.NET_Framework_3.5), so having chosen to not install it is a bit of an effort.

works-on-my-machine-starburst

But fine, what ever floats your boat I guess, but there is a problem, pretty much all the libraries which we’ve developed at The FARM are .NET 3.5 libraries, generally because they use features like LINQ or Extension Methods.
Damn, that’s going to be a pain in the ass, I’d either have to forgo our libraries, or make custom versions of them.

Or, I could be a bit ninja-esq and make a .NET 2.0 website, which has .NET 3.5 assemblies in it, now that sounds like fun.

But let’s step back a bit, what is .NET 3.5 in relation to .NET 2.0?
Well really .NET 3.5 is a super-set of the .NET 2.0 framework (well, technically a super-set of .NET 3.0, which itself was a super-set of .NET 2.0, but you get the idea). But why is that? Well .NET 3.5 is built on top of the same CLR (Common Language Runtime) which powers .NET 2.0.

Since most people associate .NET 3.5 with Visual Studio 2008 so I’ll talk about them in a combined manner.

In addition to the .NET 3.5 release we also received the C# 3 compiler. This nifty little bugger brought along the translation of => to being either a Func, Action or Predicate, and it also introduced the var keyword.
But the fun thing is that because C# 3 is targeted at the 2.0 CLR all the compiled IL is perfectly valid for .NET 2.0! This is actually how (and why) multi-targeting in Visual Studio 2008 works (well, how and why at a very high level :P) and why you can use var, lambda, etc in a .NET 2.0 project provided it’s made in Visual Studio 2008.

But back to our original topic, how do I use .NET 3.5 without installing it on the server? (Note – you’ll still need it installed on the dev environment)

Putting the pieces together

So we’ll create a new ASP.NET web application, still choosing .NET 3.5 as the framework version and do everything as per normal. The tricky part is when we come to wanting to deploy the site onto our target environment, which doesn’t have .NET 3.5 installed.
Before we can do this there is one last thing we need to change within Visual Studio, you need to change the way the Visual Studio handles the referenced assemblies. Framework assemblies (well, any assembly which is in the Global Assembly Cache (GAC)) are set to Copy Local=False, you need to change this to True, so right-click the assembly and go to Properties:

properties

Now what will happen is that when the compile is done the assembly/ assemblies will be copied into the /bin folder of your site, meaning now they are loaded into memory, but not loaded there from the GAC!

You can then take all the files and deploy them to the target environment, with the .NET 3.5 assemblies in the /bin folder, but not installed.

Really a great trick with Shared Hosting ;)

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

.Net | Hosting | Umbraco

Freeing up space on your server

by AnthonyDang 3. February 2010 06:24

Yesterday we went to install service pack 2 on a Windows  Server 2008 machine. It turns out you need at least 5GB free on C: which we didnt have. After deleting everything we possibly could, including running CCleaner and making the Page File non-existant we were still 400MB off the mark.

 

 Then I noticed a system file c:\hiberfil.sys which was 3GB.

 

Well it turns out that Windows Server 2008 still allocates space for a hibernate file. Who would want to hibernate their Live server?

 

Anyway, this is how to gain an exta 3GB...

 

C:\Users\Administrator>powercfg.exe /hibernate off

 

That's it!

 

 

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Hosting

Wildcard mapping in IIS 7 classic pipeline = web.config!

by Shannon Deminick 8. December 2009 08:34

After foolishly pulling out my hair trying to find out why my wildcard mapping was disappearing in IIS 7 using classic pipeline mode, i realized it was my own fault!! I followed the instructions on this site: http://learn.iis.net/page.aspx/508/wildcard-script-mapping-and-iis-7-integrated-pipeline/ and unfortunately just skipped over the message about how this modifies your web.config… oops! So basically, every time I deployed my handler mapping would be removed… Doh!

Unfortunately, the method to add a wildcard mapping in this article will actually remove the inheritance of standard handlers from the root of IIS and your machine.config and just make copies of them. This might not be the best approach, but i suppose sometimes it’s necessary. We only need the wildcard mapping for URL Rewriting so i decided to see if i could just simply add the isapi wildcard mapping only, have the rest of the handlers inherit from the root and see if it works… turns out it does!

So instead of having to modify IIS itself, i just needed to add this to my web.config:

<handlers>
	<remove name="ASP.Net-ISAPI-Wildcard" />
	<add name="ASP.Net-ISAPI-Wildcard" path="*"
	verb="*" type="" modules="IsapiModule"
	scriptProcessor="C:\Windows\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll"
	resourceType="Unspecified"
	requireAccess="None"
	allowPathInfo="false"
	preCondition="classicMode,runtimeVersionv2.0,bitness64"
	responseBufferLimit="4194304" />
</handlers>

Too easy! No fussing around with IIS and now at least i won’t override my changes accidentally.

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , , ,

.Net | Hosting

2 Click ASP.NET Web Application Deployment with MSBuild

by AaronPowell 2. October 2009 06:12

A couple of months ago Shannon wrote a post on how we do 2 Click Deployments at The Farm (if you haven’t read this post I suggest you read it first as I make the assumption it’s been read and skip over a few sections that it covers). I’ve been working with him to try and improve our process of deployment, and one of those tasks has been moving away from using NAnt as the build runner to using MSBuild.

Why the shift? Well MSBuild has actually come a long way recently and despite common belief it’s not just for building .NET applications. In fact it can be used the same way that NAnt can be used, to execute arbitrary operations.
As mentioned in the original post we’ve used an internal tool for modifying the web.config (and other configuration files) but it had a bit a limitation as it meant that the files were always full of settings for all environments. It also wasn’t designed to update a single property of an XML node, you’d need to replicate the whole XML structure, even if it was just 1 attribute changing.

So I suggested that we migrate to a XSLT based config management, which is what I’d used previously. A former colleague of mine has a good post on how to set that up, it can be found here.

Moving to MSBuild also brought in another advantage, it would simplify our deployment process. Currently we’re using CruiseControl.NET to execute a NAnt script which in turn executed MSBuild.

Another goal was to allow us to deploy from the branch in source control, rather than from the trunk, this way you can deploy different branches if you want to test different functionality based on a branch without overriding the trunk. So we’ve updated our source control structure to look like this:

  • trunk
  • branch
    • v1.1
  • build

The new addition is the build folder, this folder will generally only hold a single file, and that’s the master build information, which we’ll call cc.build. This build file is the one that CruiseControl.NET will look for and check out. It then contains the instructions to which branch to check out, and then handle the rest of the execution of the build. A sample looks like this:

<Project ToolsVersion="3.5" DefaultTargets="CheckoutAndBuild" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>

  <PropertyGroup>
    <BranchVersion>v1.1_net</BranchVersion>
    <BuildType>_net</BuildType>
    <BranchFolder>$(BaseFolder)\$(BuildType)</BranchFolder>
    <RepoPath>file:///\svn/Client/branches/$(BranchVersion)</RepoPath>
  </PropertyGroup>

  <Target Name="CheckoutAndBuild">
    <RemoveDir Directories="$(BranchFolder)" />

    <SvnCheckout RepositoryPath="$(RepoPath)"
					LocalPath="$(BranchFolder)"
					ToolPath="C:\Program Files\CollabNet Subversion">
      <Output TaskParameter="Revision" PropertyName="Revision" />
    </SvnCheckout>

    <Message Text="Revision: $(Revision)"/>

    <Time Format="yyyyMMddtt">
      <Output TaskParameter="FormattedTime" PropertyName="buildDate" />
    </Time>

    <MSBuild Projects="$(BranchFolder)\cc.msbuild"
             Properties="CCNetWorkingDirectory=$(BaseFolder);BuildDate=$(BuildDate);DeployType=Dev;DeployLocation=$(BaseFolder)..\Deployment\Dev;BuildConfiguration=Debug;ShowMessages=True;IncludeSymbols=True" />
  </Target>

</Project>

So lets have a look at the break down of this file. First off, we’re using the MSBuild Community Tasks for tasks such as the SVN checkout, and a few other aspects which we’ll cover later.

When we call this MSBuild file from CruiseControl.NET and pass in a parameter, BaseFolder, which is the Working folder (see the Folder Structure section of the original post).
There’s some parameters combined so we get a path to where we’ll be checking out the branch, etc.

First thing is to remove any existing checkout folder, and then have SVN checkout the latest copy of the branch.
As Shannon mentioned in the original post we timestamp each sip package, so for this we’re using the Community Task date formatter to generate our timestamp.

Then it gets a bit tricky, because this file is a dumb file and doesn’t know what’s going to be done by the branch deployment file so we need to have a way in which we can actually do a build. This is done by using the MSBuild task which allows you to execute any specified MSBuild file(s). This is done by passing the file to execute into the Projects attribute. Since we’re going to execute the one within the branch we tell it to look there.
Then it’s just a matter of passing any properties you require into the MSBuild file, here we’ve got a bunch of different parameters which the target file can consume.

The MSBuild task is then replicated as many times for each different environment/ location which you want to build for.

 

Each branch maintains its own msbuild file, which is also called cc.msbuild so that we can keep the naming consistent across all locations. This file is the one which is responsible for:

  • Compiling the project
  • Modifying the config files
  • Zipping the release

But this can easily be expanded upon, depending how the branch needs to be handled, there’s nothing that says it couldn’t also do the copying to the appropriate server, etc. Lets take a look inside this file.

<Project ToolsVersion="3.5" DefaultTargets="ZipFiles" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>

  <PropertyGroup>
    <LocationWorkingWeb>$(CCNetWorkingDirectory)\_net\Client.Web</LocationWorkingWeb>
    <ProjectWeb>$(LocationWorkingWeb)\Client.Web.csproj</ProjectWeb>
    <BuildFolder>$(DeployLocation)\$(BuildDate)\</BuildFolder>
  </PropertyGroup>

  <Target Name="ZipFiles" DependsOnTargets="FormatFiles">
    <ItemGroup>
      <ZipFiles Include="$(BuildFolder)**\*.*" Condition="$(IncludeSymbols) == 'True'" />
      <ZipFiles Include="$(BuildFolder)**\*.*" Exclude="$(BuildFolder)**\*.pdb" Condition="$(IncludeSymbols) == 'False'" />
    </ItemGroup>

    <Zip Files="@(ZipFiles)"
         ZipFileName="$(DeployLocation)\$(BuildDate).zip"
         WorkingDirectory="$(BuildFolder)"/>

    <RemoveDir Directories="$(BuildFolder)" />
  </Target>

  <Target Name="FormatFiles" DependsOnTargets="BuildWebProject">
    <MSBuild Projects="transformers.msbuild"
             Properties="XslFile=$(CCNetWorkingDirectory)\_net\CruiseControl\Web.config.xslt;OutputFile=$(BuildFolder)Web.config;InputFile=$(LocationWorkingWeb)\Web.config;Environment=$(DeployType)" />
  </Target>

  <Target Name="BuildWebProject">
    <MSBuild Projects="$(ProjectWeb)"
             Properties="Configuration=$(BuildConfiguration);OutDir=$(BuildFolder)bin\;WebProjectOutputDir=$(BuildFolder)"
             Targets="Clean;Build;ResolveReferences;_CopyWebApplication"/>
  </Target>
</Project>

This file, again uses the MSBuild Community Tasks, but its also a whole lot smarter about what’s happening for this particular build. I’ve specified that the DefaultTargets of the file is the ZipFiles which is really the final task which I want to execute.
One really nice thing about MSBuild is that you can specify a DependsOnTargets attribute for a target, which states that the particular target(s) must have executed before the called one will execute. So by looking at how the dependency is configured the project will have been compiled and the files formatted will both have been done. Makes it so much simpler to execute something, rather than having a ‘runner’ target which is just responsible for calling a bunch of targets in order we can just have them done in order of dependency.

So we’ve got a BuildWebProject target which will again call an external MSBuild file, in this case our csproj file, passing in some of the information which was given to us from the ‘master’ file, in a manner in which Visual Studio itself would have done.

Next we format the files. This goes off to an external MSBuild file, so we can use the same operations for every single file we want to format. The contents of transformers.msbuild is as follows:

<!-- ROBOTS IN DISGUISE -->
<Project ToolsVersion="3.5" DefaultTargets="Xslt" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/>
  <ItemGroup>
    <XslFileWithParams Include="$(XslFile)">
      <environment>$(Environment)</environment>
    </XslFileWithParams>
  </ItemGroup>
  <Target Name="Xslt">
    <Xslt RootTag="" Inputs="$(InputFile)" Output="$(OutputFile)" Xsl="@(XslFileWithParams)" />
  </Target>
</Project>

This is a basic task file which adds a parameter (named envrionments) to our XSLT and then uses the MSBuild Community Tasks to do the transformation.
Note – this is a slight deviation from Alistair’s blog post, we don’t have a different XSLT per machine, we have a single XSLT which we use the parameter to determine what to do. This makes it easier to see all the options we want to change per environment.

Lastly the dependencies hierarchy throws us back to the ZipFiles target, where we gather all the files together that we want (and there’s an option to exclude the pdb files, after all PDB != Product Deployable Bits ;) ), call the Zip task (make sure you specify a working folder otherwise you’ll end up with a crazy hierarchy in the Zip!) and then we delete the folder which we built to.

 

Conclusion

MSBuild is a good tool which can be used for doing operations other than just compiling a .NET project, as you can see here we’re using it to pull files down out of SVN or transform a file via XSLT. This doesn’t have anything to do with compilation, or .NET for that matter.

It make take a bit of work to get set up, there was quit a bit of frustration vented during this process but now that it’s working there’s no looking back.

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , , , , , ,

.Net | Hosting | Umbraco

The FARM adds a nail to the coffin of IE 6

by Shannon Deminick 20. July 2009 10:19

Days until TheFARM drops support for IE6



We are happy to announce that we will cease to support IE 6 development from Oct 31 2009. We will continue to support our clients’ existing websites but any new development will target Firefox 2+, IE 7+, and Web kit browsers (e.g. Safari, Chrome).

IE 6 was released in Aug 2001, it is 8 years old and 2 more browsers have since been released from Microsoft… it’s about time people stop using this horrible, horrible browser. Other larger players including YouTube have also stated that support for IE 6 will stop. We’re hoping that more agencies will adopt this idea and push for clients to finally make the upgrade or switch to a new browser… it’s 8 years old!

Comments are always welcome!

Currently rated 5.0 by 6 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , ,

Hosting | Internet Technology | JavaScript

2 Click ASP.Net Web Application Deployment

by Shannon Deminick 10. July 2009 13:17

At CodeGarden09 I had mentioned during one of the open space sessions that we had developed a 2 click deployment strategy for some of our projects and someone asked if I could share the solution, so here it goes!

The tools we use to do this are:

Get Zip File here: TheFARMDeployUtilities.zip (513.89 kb)

We generally have 3 different environments for our websites: Development, Staging, Live (Production). For 2 click deployments to work, we then need to have CruiseControl.Net server installed on each server environment. Your development machine or the machine that is performing the 2 click deploy should have access to all of the CruiseControl.Net servers so that each project can be added to your CCTray application. We lock down our CruiseControl.Net servers via firewall and running them on non-standard ports to only allowing traffic to them from our office environment.

This strategy is 2 steps because:

  • Gives you the control over when the project is built
  • Gives you control over when the built files are deployed live
  • Though it could be done in 1 step, I feel that it’s safer to ensure that the project is built properly before it goes live

This deployment process also takes into account:

  • A rollback process which ensures any build that is deployed can be rolled back to a previous build very quickly
  • The problem of multiple application restarts (or long application restarts) when uploading files via FTP since each DLL is essentially copied up one at a time, this process ensures that all built files are deployed to the environment without delay.

Basic Workflow

In order to understand the next steps its best to get a brief overview of what steps are involved when the deployment occurs:

  1. All code is committed to the repository (to a branch, or wherever the stable code should be) that you wish to deploy

Click 1

  1. A CruiseControl ‘Force Build’ is initiated for the project (normally via CCTray)
  2. CruiseControl checks out the latest version from Subversion and puts it in it’s working folder for the project
  3. CruiseControl runs a NANT task which:
    1. Creates a build date time stamp (i.e. 20090710AM)
    2. Runs an MSBuild process for each deployment environment (dev/stage/live) to build and deploy the web application. Depending on the environment, it will build in Release vs. Debug mode.
    3. Formats configuration files to include only the relevant settings for each environment
    4. Zips the builds for each deployment environment named with the build date time stamp
    5. FTPs the Zip file to a deploy folder on the deployment servers (stage/live)

Click 2

  1. A CruiseControl ‘ForceBuild’ is initiated on the environment’s server you wish to deploy to (normally via CCTray)
  2. CruiseControl runs a NANT task which:
    1. Unzips the latest build files into the staging/live folders for IIS.

CruiseControl Server Setup

The CruiseControl (build) server requires a few bits of software installed and configured:

The CruiseControl servers on staging/live environments only require that CruiseControl & NANT is installed.

Folder Structure

On the CruiseControl build server, we create this folder structure for each project:

  • Artifact
    • Debug
      • buildlogs (stores the CruiseControl build logs for the project)
  • Deployment
    • Dev (the folder for the Dev environment builds)
    • Live (the folder for the Live environment builds)
    • Staging (the folder for the Staging environment builds)
  • Working (where all of the source control files are checked out to)

On the staging/live servers we have a folder in the root of the website labelled: “_DEPLOY” which is where the deployment zip files get FTP’d to. We ensure that this folder doesn’t have read access so public people can’t go downloading your build files! In this _DEPLOY folder we have a deploy.build NANT task (see below).

Configuration File Formatting

Everyone seems to have their own way of managing different configuration settings for different environments and so do we! I like to be able to see all of the configuration settings for each environment in one file so that i know what’s being defined without looking through different files. To do this, our configuration settings look something like this:

<!--<DEV>-->
<add key="mySetting" value="DevEnvironmentSettingValue" />
<!--</DEV>-->
<!--<STAGING>
<add key="mySetting" value="StagingEnvironmentSettingValue" />
</STAGING>-->
<!--<LIVE>
<add key="mySetting" value="LiveEnvironmentSettingValue" />
</LIVE>-->

 

With the above design, development settings are always active when developing. When CruiseControl runs it’s build one of the NANT tasks that are run is The FARM’s configuration settings parser plugin which removes any configuration settings in config files that are not required for the current build environment.

We’ve also developed a handy little Visual Studio plugin to make formatting these configuration settings very easy. All that is required is highlighting a configuration element, clicking Tools –> The Farm Config –> Format for Dev (or staging/live)

CruiseControl.Net Setup

Deployment/Build Server

I’ve put documentation about each item directly in the XML:

<project name="MYPROJECT" category="WEB" queue="MYPROJECT" queuePriority="1" >
<!-- The working folder, this is where our repository files will be checked out to -->
<workingDirectory>D:\CruiseControl\Projects\MYPROJECT\Working</workingDirectory>
<!-- This is where our log files, and debug info will be saved -->
<artifactDirectory>D:\CruiseControl\Projects\MYPROJECT\Artifact\Debug</artifactDirectory>
<sourcecontrol type="svn">
<!-- We use a file based Subversion repository... here's an example of the location -->
<trunkUrl>file:///\myserver.mydomain.local/MYPROJECT/DEV_Repository/trunk/</trunkUrl>
<!-- Our Subversion install is here -->
<executable>C:\Program Files\CollabNet Subversion\svn.exe</executable>
<autoGetSource>True</autoGetSource>
</sourcecontrol>
<!-- We always do Force Builds, instead of automatic builds based on source control so our
server doesn't die when people commit multiple times for different projects, therefore
triggers is set to nothing -->
<triggers/>
<tasks>
<nant>
<!-- We use NANT to do all of our build. NANT in turn runs MSBuild and other
methods that we require such as FTP, etc... -->
<executable>C:\Program Files\Nant\bin\nant.exe</executable>
<baseDirectory>D:\CruiseControl\Projects\MYPROJECT\Working</baseDirectory>
<!-- This is the location of the NANT build file... it is in our working folder
which means that it is committed into the repository so that our devs are free
to modify it to suit their needs -->
<buildFile>D:\CruiseControl\Projects\MYPROJECT\Working\cc.build</buildFile>
<buildTimeoutSeconds>3600</buildTimeoutSeconds>
</nant>
</tasks>
<publishers>
<xmllogger />
<!-- This ensures that our log files don't build up too big -->
<artifactcleanup cleanUpMethod="KeepLastXBuilds" cleanUpValue="50" />
</publishers>
</project>

Staging/Live Servers

For each site, just define another project which simply runs a NANT script which basically just unzips the zip build file into the working IIS site folder (see below)

<project name="_STAGING_MYSITE">
<workingDirectory>E:\Inetpub\MYSITE</workingDirectory>
<artifactDirectory>E:\Inetpub\MYSITE\_DEPLOY\Debug</artifactDirectory>
<tasks>
<nant>
<executable>C:\Nant\bin\nant.exe</executable>
<baseDirectory>E:\Inetpub\MYSITE</baseDirectory>
<buildFile>E:\Inetpub\MYSITE\_DEPLOY\deploy.build</buildFile>
</nant>
</tasks>
<publishers>
<xmllogger />
<artifactcleanup cleanUpMethod="KeepLastXBuilds" cleanUpValue="50" />
</publishers>
</project>

NANT Build File

Deployment/Build Server

I’ve put documentation about each item directly in the XML:

<!-- Ensure NO namespace is declared as FTPTask for NANT 
has a bug when namespaces are declared -->
<project name="Site" default="DeployAll">

<!-- ** PROPERTY DEFINITIONS, These are the only things you should need to change -->

<!-- define the folder containing the web application project -->
<property name="location.working.web" value="${CCNetWorkingDirectory}\_net\MySite.Web"/>

<!-- define the web applicatoin project project file -->
<property name="project.web" value="${location.working.web}\MySite.Web.csproj"/>

<!-- define the deployment folders for each environment -->
<property name="location.deploy.dev" value="${CCNetWorkingDirectory}\..\Deployment\Dev"/>
<property name="location.deploy.staging" value="${CCNetWorkingDirectory}\..\Deployment\Staging"/>
<property name="location.deploy.live" value="${CCNetWorkingDirectory}\..\Deployment\Live"/>

<!-- define the MSBuild executable -->
<property name="exe.msconfig" value="C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe"/>

<!-- define the ftp property connections for the stage/live environments -->
<property name="ftp.staging.server" value="123.123.123.123"/>
<property name="ftp.staging.user" value="admin"/>
<property name="ftp.staging.password" value="hello"/>
<property name="ftp.staging.path" value="MYSITE/FILES/_DEPLOY"/>
<property name="ftp.live.server" value="321.321.321.321"/>
<property name="ftp.live.user" value="admin"/>
<property name="ftp.live.password" value="hello"/>
<property name="ftp.live.path" value="MYSITE/FILES/_DEPLOY"/>

<!-- ** END PROPERTY DEFINITIONS -->

<!-- the primary build target which does the entire build -->
<target name="DeployAll" depends="SetBuildDate,Init,DevSite,StagingSite,LiveSite,CopyStaticFiles" />

<!-- sets some GLOBAL properties for use on all builds -->
<target name="Init" description="Sets the global working and project properties">
<property name="GLOBAL.location.working" value="${location.working.web}"/>
<property name="GLOBAL.project" value="${project.web}"/>
</target>

<!-- set a build date property to today's date with am/pm stored in ${build.date}-->
<target name="SetBuildDate" description="Creates a build date property for use in our deployment scripts">
<tstamp property="build.date" pattern="yyyyMMddtt" verbose="true" />
<echo message="Current build label: ${build.date}" level="Debug" />
</target>

<!-- Deploy Dev with Debug, this doesn't time stamp or zip the output
since it's a dev environment, the location should be set to your
IIS folder -->
<target name="DevSite" description="Compile Dev Web MySite.">
<property name="GLOBAL.location.deploy" value="${location.deploy.dev}"/>
<!-- build project in Debug mode -->
<property name="GLOBAL.project.config" value="Debug"/>
<property name="GLOBAL.deploy.type" value="DEV"/>

<!-- build the web application (see below) -->
<call target="BuildWebProject" />
</target>

<!-- Deploy Staging with Debug -->
<target name="StagingSite" description="Compile Staging Web MySite.">
<!-- build the project to the time stamped folder -->
<property name="GLOBAL.location.deploy" value="${location.deploy.staging}\${build.date}"/>
<!-- build project in Debug mode -->
<property name="GLOBAL.project.config" value="Debug"/>
<!-- define that the STAGING settings should be active on deploy -->
<property name="GLOBAL.deploy.type" value="STAGING"/>

<!-- build the web application (see below) -->
<call target="BuildWebProject" />
<!-- format the configuration files for the project to have the correct
environments settings active -->
<call target="FormatFileForDeploy" />
<!-- zip the build -->
<call target="ZipDeployFiles" />

<!-- transfer the build to the staging environment's deploy folder -->
<connection id="myconn" server="${ftp.staging.server}" username="${ftp.staging.user}" password="${ftp.staging.password}" />
<ftp connection="myconn" verbose="true" showdironconnect="true" remotedir="${ftp.staging.path}">
<put localdir="${location.deploy.staging}" type="bin">
<include name="${build.date}.zip" />
</put>
</ftp>

</target>

<!-- Deploy Live with Release -->
<target name="LiveSite" description="Compile Live Web MySite.">
<!-- build the project to the time stamped folder -->
<property name="GLOBAL.location.deploy" value="${location.deploy.live}\${build.date}"/>
<!-- build project in RELEASE mode -->
<property name="GLOBAL.project.config" value="Release"/>
<!-- define that the LIVE settings should be active on deploy -->
<property name="GLOBAL.deploy.type" value="LIVE"/>

<!-- build the web application (see below) -->
<call target="BuildWebProject" />
<!-- format the configuration files for the project to have the correct
environments settings active -->
<call target="FormatFileForDeploy" />
<!-- zip the build -->
<call target="ZipDeployFiles" />

<!-- transfer the build to the live environment's deploy folder -->
<connection id="myconn" server="${ftp.live.server}" username="${ftp.live.user}" password="${ftp.live.password}" />
<ftp connection="myconn" verbose="true" showdironconnect="true" remotedir="${ftp.live.path}">
<put localdir="${location.deploy.live}" type="bin">
<include name="${build.date}.zip" />
</put>
</ftp>
</target>

<!-- ** BUILD METHODS-->

<!-- Global method to build web applicatio projects using MSBuild -->
<target name="BuildWebProject">
<exec basedir="${GLOBAL.location.working}" program="${exe.msconfig}" workingdir="." failonerror="true">
<arg value="${GLOBAL.project}" />
<arg value="/nologo" />
<arg value="/t:Clean;Build" />
<arg value="/t:ResolveReferences;_CopyWebApplication"/>
<arg value="/p:OutDir=${GLOBAL.location.deploy}\bin\;Configuration=${GLOBAL.project.config}"/>
<arg value="/p:WebProjectOutputDir=${GLOBAL.location.deploy}"/>
</exec>
</target>

<!-- This formats any files that are included in our include property -->
<!-- to be in the correct format for dev,staging,live -->
<target name="FormatFileForDeploy">
<thefarm-process-config configtype="${GLOBAL.deploy.type}">
<fileset basedir="${GLOBAL.location.deploy}">
<include name="**/Regions.xml" />
<include name="**/EmailFormDefinitions.xml" />
<include name="**/*.config" />
</fileset>
</thefarm-process-config>
</target>

<!-- Zips all files in the current deployment folder -->
<target name="ZipDeployFiles">
<zip zipfile="${GLOBAL.location.deploy}.zip">
<fileset basedir="${GLOBAL.location.deploy}">
<include name="**/*" />
</fileset>
</zip>
<delete dir="${GLOBAL.location.deploy}" />
</target>

<!-- ** END BUILD METHODS-->

</project>

Staging/Live Servers

<project name="MyStagingSite" default="DoDeploy">

<target name="DoDeploy" depends="SetBuildDate,UnzipDeployFiles" />

<!-- set a build date property to today's date with am/pm-->
<target name="SetBuildDate">
<tstamp property="build.date" pattern="yyyyMMddtt" verbose="true" />
<echo message="Current build label: ${build.date}" level="Debug" />
</target>

<!-- unzip the build file into the IIS working folder -->
<target name="UnzipDeployFiles">
<unzip zipfile="${CCNetWorkingDirectory}\_DEPLOY\${build.date}.zip" todir="${CCNetWorkingDirectory}" />
</target>

</project>

Rollback

Since each build is contained in a date/time stamped ZIP file it is obviously fairly easy to rollback your site to a previous build, you would just have to know what date/time the last stable build was.

Conclusion

Though the above seems like a lot of work, it really isn’t since all the work is already done for you! All you really need to do once you have your CruiseControl servers setup is create your projects, modify the NANT build script properties for each project and that’s it.

This makes deployment extremely easy and safe since there’s no room for human error. All of the files will go exactly where they need to go. Developers can’t upload the wrong configuration files to the wrong servers or the wrong files to the wrong places. Another great benefit is that when the server unzips the build, the .Net application restarts quickly because it has all of the files to start compiling instantly.

Obviously to do this, you would need access to your staging and development servers, but even if you didn’t you could still get the first step done (which is the major step). The NANT scripts above are quite basic, we use them to build Sandcastle .Net documentation and all sorts of other things.

Always great to know how everyone else is doing the things described in this doc, so please let me know!

Currently rated 4.5 by 2 people

  • Currently 4.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , , , , , ,

.Net | Hosting | Umbraco

Guide to installing Cold Fusion 8 on Windows Server 2008 (IIS 7) 64 bit

by Shannon Deminick 7. May 2009 07:27

After a lot of trial and error i finally figured out how to get CF 8 running in on Windows Server 2008 x64 in IIS 7. So i figured I’d write a post about it since there’s pretty much no documentation covering this that i could find.

Installation

  • Take a backup of IIS
    • C:\Windows\System32\Inetsrv\AppCmd add backup "backupname"
  • Install CF 8 Enterprise
    • Select Multiserver
    • Keep default paths
    • DO NOT attempt to configure anything for ColdFusion until the update is applied
  • Install CF 8.1 Update
    • Configure for Multiserver

Web Site/Server Configuration

  • Give the IIS users/groups (IUSR, IIS_IUSRS) full control over your JRun install folder (C:\JRun4\lib\wsconfig)
    • After looking at the logs, it seems that the configuration tool is trying to set IIS_WPG permissions on this folder which is for Server 2003, not 2008
  • Create a new application pool called ColdFusion
    • Under advanced settings, enable running in 32 bit mode and make Managed Pipeline mode Classic instead of Integrated
    • CF will not run without 32 bit and Classic enabled (according to my experience so far)
  • Create a new website and ensure it is assigned to the ColdFusion application pool
    • For testing, create a website pointed to your default CFIDE install folder
  • Launch the Web Server Configuration Tool from Start Menu
    • Click Add
    • Select "coldfusion" from the JRun Server drop down list (not "admin")
    • Ensure the Web Server has IIS selected
    • Select the website you just created from the IIS Web Site drop down list (Do not check All, or be prepared to restore IIS if your running other .Net apps!)
    • Check "Configure web server for ColdFusion 8 application"
    • Click Advanced...
      • Check Enable verbose logging for connector if you want details log requests for debugging
    • Save changes and click yes to restart the web server (this will restart IIS!!!)

Testing

  • If you configured a test site to point to your CFIDE folder, go to the website in your browser to the /install.cfm path
    • This should show you a Congratulations screen
  • If you configured your site with your own CF files, test those instead

Debugging

  • After some trial and error, i figured out the above procedure, but there are logs to refer to.
  • the CF web site config tool creates web site configuration structures at this location:
    • \Run4\lib\wsconfig\(some number)
    • Each (some number) corresponds to a different website configured with the tool
    • In each folder is a LogFiles folder that contains logs that you can use to debug the installation
  • There's also a log file at: \Run4\lib\wsconfig\wsconfig.log

Un-configuring a site

  • If a site needs to be un-configured or re-configured, the web configuration tool seem to always fail when trying to remove a site.
  • To remove a site manually:
    • Stop the website in IIS
    • Stop the CF server and CF admin services in the Services administration tools
    • Delete the folder: \Run4\lib\wsconfig\(some number)
      • where (some number) corresponds to the site you want to remove
    • edit the \Run4\lib\wsconfig\wsconfig.properties file and remove the lines referring to the number (some number) of the site folder that you deleted in the previous step
    • Start the CF admin and CF server services
    • Run the web configuration tool and re-add the site you want configured
    • Start the site in IIS

Currently rated 5.0 by 4 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , ,

Hosting

// Website built by The FARM