Simon Green's Developer Blog
Developing .NET in the cold white north ...

Running .NET Apps in 32-bit mode on 64-bit Windows

Monday, 17 December 2007 12:37 by Simon

The normal behavior for .NET 2.0 applications compiled with the default 'Any CPU' platform is to run as 32-bit on x86 (32-bit) Windows and as 64-bit on x64 (64-bit) Windows.

Occasionally, some apps won't run correctly - I've recently run into this with CCNetConfig (a CruiseControl.NET Configuration tool) and have seen it before with other tools. Another obscure scenario where it shows up is if you try to use the JET OleDB driver which will fail in 64-bit mode because there isn't one! (it has to be 32-bit).

Rather than have to recompile the app or even worse, run a 32-bit Virtual Machine, there is an easy way to force .NET to run an app in 32-bit mode using the 'CorFlags.exe' tool.

Depending on your system this may be installed in different places. I've seen it in different places on XP64 and Vista X64:

  • C:\Program Files\Microsoft SDKs\Windows\v6.0\Bin\x64\CorFlags.exe
  • C:\Program Files (x86)\Microsoft Visual Studio 8\SDK\v2.0\Bin\CorFlags.exe

Running this from the command line with the path / filename of the app you want to change and the switch /32BIT+ to turn on 32-bit mode, e.g.:

   CoreFlags.exe TheApp.exe /32BIT+ 

If that fixes the problem then you know that it is a 64-bit issue. You can re-enable 64-bit operation for the app by turning off the 32-bit switch with the parameter /32BIT-, e.g.:

   CoreFlags.exe TheApp.exe /32BIT- 

Voila ... control over 32-bit and 64-bit execution without doing a recompile! I'm not 100% certain but I think that this switch sets the same flag that the 'x86' and 'Any CPU' targets set in Visual Studio.


Tags:   , ,
Categories:   .NET
Actions:   E-mail | del.icio.us | Permalink | Comments (6) | Comment RSSRSS comment feed

Bootstrap your build - good practice for CruiseControl.NET

Sunday, 16 December 2007 03:43 by Simon

If you are reading this (a developers blog) then chances are you are already in the 20% of developers who know there is more to development than 'developing' (code). So, you are probably using version control such as Subversion, SourceGear Vault or heck, even SourceSafe (for all people knock it, it is infinitely better than nothing at all!) and maybe have a continuous integration system such as CruiseControl.NET or Draco.NET setup to automatically do a build when the source-code changes.

What many people leave out though is making sure that the build scripts themselves and the whole source control configuration is itself protected by version control so that in an emergency a new build machine can be setup quickly and easily without having to develop everything from scratch or remember all the triggers, rules and targets that were in the original system.

Here is a technique that I've found useful and also helps to keep the build configuration for each project with the project that it belongs to (i.e. in it's repository) rather than off somewhere else. It also enables you to make all changes to your build system via the normal Subversion working-copy / commit process.

For this example, lets assume that we have 3 subversion repositories:

The build repository would contain the default CruiseControl.NET files including the ccnet.config file in the server folder which is where the configuration for each project normally resides. We're going to move pieces of that file into each separate project repository.

The CruiseControl.NET wiki describes how to Configure CruiseControl.Net to Automatically Update its Config File which is the bootstrap part of the process - this allows us to make changes to the build config file from another machine without having to get onto the build server and also ensures that all the configuration is stored in a repository.

My ccnt.config file is slightly different to the one shown in the wiki to enable the individual project configurations to be stored in their own repositories so each project has it's own folder:


<!DOCTYPE cruisecontrol [

  &lt;!ENTITY accelerator SYSTEM "file:accelerator\ccnet.config">

  <!ENTITY redirector SYSTEM "file:redirector\ccnet.config">

]>

<cruisecontrol>

  <project name="ccnet">

    <sourcecontrol type="svn">

      <trunkUrl>http://buildserver/svn/build/trunk/CruiseControl.NET/server/config</trunkUrl>

      <workingDirectory>C:\Program Files (x86)\CruiseControl.NET\server\config</workingDirectory>

      <executable>C:\Program Files (x86)\VisualSVN Server\bin\svn.exe</executable>

    </sourcecontrol>

    <triggers>

      <intervalTrigger name="ci" seconds="60" buildCondition="IfModificationExists" />

    </triggers>

  </project>

  &accelerator;

  &redirector;

</cruisecontrol>

 

Remember that the ccservice.exe.config and / or ccnet.exe.config file will need to be changed to tell CruiseControl.NET where to look for the ccnet.config file now that it isn't in the original place:


 <appSettings>

  <!-- Without this appSetting ccservice will look for ccnet.config in its own directory. -->

  <add key="ccnet.config" value=".\config\ccnet.config"/>

  <add key="service.name" value="CCService"/>

  <add key="remoting" value="on"/>

  <add key="ServerLogFilePath" value="ccnet.log"/>

  <!-- Used by the WebDashboard ServerLog plugin to locate the log file produced by the LogFileTraceListener (above) -->

  <add key="ServerLogFileLines" value="100"/>

  <!-- Used by the WebDashboard ServerLog plugin to determine how many lines from the log file should be read -->

  <add key="WatchConfigFile" value="true"/>

  <!-- Turns on or off the file watcher used to monitor the ccnet.config file -->

 </appSettings>

 

The next step is to supply the ccnet.config files for each project which will come from the repositories for those projects.

I've created a 'build' folder in each ...

... and inside that is the ccnet.config project snippet for that project:


  <project name="redirector">

    <workingDirectory>E:\ccnet\redirector</workingDirectory>

    <sourcecontrol type="svn">

      <trunkUrl>http://buildserver/svn/redirector/trunk</trunkUrl>

      <executable>C:\Program Files (x86)\VisualSVN Server\bin\svn.exe</executable>

    </sourcecontrol>

  </project>

 

(the real-life project contains a lot more - labellers, targets etc...)

The final piece to tie everything together is to make these project-specific files part of the config folder that the build ccnet.config file is in above and for this we use the svn:externals facility.

I used TortoiseSVN to add the property to a checked-out copy of the config folder:

NOTE: The screeshot above only shows the first entry. An additional entry would be made for the accelerator project.

After committing all these files the build server will automatically update it's own ccnet.config and get the separate snippet of the file for each project from the separate project repositories because of the svn:externals. The folder structure will then appear as below:

Everything is stored in source control which makes moving to a new build machine easier and the configuration for each project is stored in the same repository as the project itself.

Adding or removing projects from the continuous integration / build system is simply a case of editing the root ccnet.config file and setting the appropriate svn:externals property on the config folder which can be done on a working copy of the build repository. An additional advantage is that all changes can now be done via subversion itself without needing direct access to the build machine so normal repository security can be used.

Incidentally, in case you are wondering what happens if a non-working configuration is committed don't worry - CruiseControl.NET is smart enough to avoid using something that won't load and keeps the previous version in memory so all you need to do is correct it and commit a new working version and it will then pick that up and carry on.