Posts for category 'Programming'

The effects of x64 on your .Net application

When you run an application created using .Net 2.0 or later on an x64 version of Windows, it will execute as a native 64 bit application. This is generally a good thing; your application gets to use the larger virtual address space and other advantages of x64 without you needing to change anything.

There are however a few consequences of running as a 64 bit process which need to be understood. There are three main differences when your application is running as a 64 bit process:

  1. You cannot use 32 bit DLLs.
  2. File and registry virtualization is always disabled.
  3. DEP is always enabled.

The first issue is relatively well known. A 64 bit process cannot load 32 bit DLLs, and .Net is no exception. This isn’t a problem if you use PInvoke to use native Windows APIs; all the Windows DLLs come in both 32 and 64 bit versions. But if you’re using a third party (or your own) native DLL or COM component, you need to be aware of this. Also some .Net libraries, such as Managed DirectX and XNA, indirectly depend on 32 bit DLLs and will therefore not work in a 64 bit process. If you try to run such an application on Windows x64, it will crash with a BadImageFormatException.

If your application depends on any external native DLLs and you cannot provide a 64 bit version of those DLLs, or if the application is otherwise incompatible with x64, you should change the target CPU of your executable to x86. For C# projects in Visual Studio 2008, you can find this setting on the “Build” tab of the project properties; the “Platform target” setting is the one you want. For Visual Basic projects, look under the “Compile” tab, click the “Advanced Compile Options…” button, and change the “Target CPU” setting. When you change this setting, the compiler adds an attribute to the executable to tell the CLR to always run the program as a 32 bit process. You can also set this setting to x64 or ia64 which means your application will fail to run on systems that don’t support those architectures.

The second issue is less well known, and it applies to Windows Vista and newer only. If you have UAC enabled your application will run with limited rights, and cannot write to many locations such as Program Files or HKEY_LOCAL_MACHINE in the registry. For compatibility, Windows will redirect attempts to write to these locations to a different folder in the user’s profile (in %LocalAppData%\VirtualStore, to be precise). For 32 bit processes, this behaviour is enabled by default (you can manually disable it using a manifest), but for 64 bit processes, it is always disabled (it cannot be enabled at all) so if you attempt to write to these locations, it will fail.

File and registry virtualisation can be disabled for 32 bit processes using a manifest, and to make your application behave consistently on both 32 and 64 bit systems I strongly recommend you do this. Visual Studio 2008 will automatically embed a manifest in your application that disables the virtualisation. If you are using Visual Studio 2005, you can use this method to embed the manifest.

The final issue has to do with Data Execution Prevention. XP and Vista will not apply DEP protection to a 32 bit process unless the executable is marked with the NXCOMPAT flag, but for 64 bit processes, DEP is always enabled. If you interop with native code which might be incompatible with DEP you need to be aware of this. Visual Studio 2008 (and Visual Studio 2005 as well, provided you’re using .Net 2.0 SP1) will mark the application with the NXCOMPAT flag so DEP will be enabled for 32 bit processes as well. If your application is not compatible with DEP, and you cannot fix it for some reason, you must set the platform target to x86 as described above, and remove the NXCOMPAT flag.

Categories: Programming
Posted on: 2009-01-08 12:58 UTC. Show comments (0)

.Net Remoting and IPv6

.Net Remoting is quite an old technology, and has been superseded by Windows Communication Foundation in .Net 3.0. However, that doesn’t mean it’s useless; you may have an old application that already uses it, or you may need to target clients that don’t have .Net 3.0, or maybe you’re even working with Mono, which currently doesn’t support WCF. In all these scenarios, using .Net Remoting is still perfectly valid.

.Net Remoting was introduced in .Net 1.0, and broad support for IPv6 was not introduced until .Net 2.0. For reasons of backwards compatibility, a .Net Remoting server still listens on IPv4 by default, even in .Net 2.0 and higher. Only if your networking configuration supports only IPv6 (IPv4 is disabled completely) will .Net Remoting automatically listen on IPv6.

It seems like that should be fine. After all, if your network supports IPv4, what is the problem with using it? It turns out there is one, and it’s quite subtle. If your network is configured to use both IPv6 and IPv4, and your Remoting clients are using host names to connect to the server, those host names will resolve to both an IPv6 and IPv4 address. Windows will then try to connect using IPv6 first – which fails because the server is listening only on IPv4 – causing a delay of a few seconds on the initial connection.

You can easily reproduce this problem by having a .Net Remoting client connect to a server on the local host on a computer running Vista with the default networking setup which has IPv6 enabled. If you use localhost in the well-known service URL it will attempt IPv6 first, causing a delay. If instead you use it will be much quicker. However, using IP addresses instead of host names may not be practical, and disabling IPv6 is also a bit of a sledgehammer solution. A better idea is to make .Net Remoting listen on IPv6.

Although it can be rather hard to find out how to do this from the documentation, it turns out to be quite simple. If you use the app.config file to configure remoting you can use the bindTo attribute of the channel to listen on IPv6. If you just add that attribute, the server will no longer listen on IPv4 however; if you want both IPv4 and IPv6, you need to define two channels. An example is given below:

      <wellknown mode="Singleton" type="MyApplication.MyServer, MyAssembly" objectUri="MyServer" />
      <channel ref="tcp" name="tcp6" port="9000" bindTo="[::]" />
      <channel ref="tcp" name="tcp4" port="9000" bindTo="" />

As you can see, the IPv6 addresses are enclosed in square brackets. By using [::], the server will listen on all IPv6 addresses; you can of course also specify an explicit IPv6 address to listen on, same as for IPv4. For example, [::1] would cause it to listen on the local host only. This example uses a TCP channel, but the same principle works for HTTP channels as well.

If you configure remoting programmatically, you can use the same approach:

IDictionary properties = new Hashtable();
properties["name"] = "tcp6";
properties["port"] = 9000;
properties["bindTo"] = "[::]";
TcpServerChannel channel = new TcpServerChannel(properties, null);
ChannelServices.RegisterChannel(channel,  false);

Again, if you need it to listen on both IPv6 and IPv4, you need to configure two channels. The client does not need to be changed at all, for both methods of configuration.

A small note for people who are using Mono: on Linux, if you bind to an IPv6 address, it will automatically bind to the equivalent IPv4 address as well. In that case, you don’t need to specify two channels, just create a channel for IPv6 and it will listen on IPv4 too. This behaviour is exclusive to Linux, other flavours of Unix (e.g. FreeBSD) don’t do it.

Categories: Programming
Posted on: 2009-01-03 08:19 UTC. Show comments (1)

Enumerating the lines of a file

If you've done any programming at all, you'll probably have read a file line by line at some point. Fortunately, most libraries provide an easy way of doing that, and .Net is no exception: the TextReader.ReadLine method provides what you need. If you've used this method, you'll have written something like the following C# code.

using( StreamReader reader = File.OpenText("myfile.txt") )
    string line;
    while( (line = reader.ReadLine()) != null )
        // Do something with the line

While it does the job, personally I think it would be nicer and more semantic if we could use the foreach keyword for this. It's possible of course to use File.ReadAllLines for this purpose (we can use foreach to enumerate over the array it returns), but that reads the entire file into memory at once, so it's not a good solution if the file you want to read is big.

Fortunately, we can make it possible to do this with very little code indeed, thanks to extension methods (introduced in .Net 3.5) and the yield keyword (introduced in .Net 2.0).

public static class TextReaderExtensions
    public static IEnumerable<string> EnumerateLines(this TextReader reader)
        if( reader == null )
            throw new ArgumentNullException("reader");

        string line;
        while( (line = reader.ReadLine()) != null )
            yield return line;

Note that the extension is defined on TextReader, so you're not limited to using it with StreamReader; you can also use it with StringReader or anything else that inherits from TextReader.

With these few lines of code, we can now use foreach to enumerate over the lines of a file:

using( StreamReader reader = File.OpenText("myfile.txt") )
    foreach( string line in reader.EnumerateLines() )
        // Do something with the line

While this isn't much shorter than the original, it looks much nicer in my opinion.

Categories: Programming
Posted on: 2008-09-26 07:25 UTC. Show comments (3)

FormatC source code formatting

I am proud to announce a new utility here on FormatC.

FormatC is a utility that allows you to add syntax highlighting to your C#, Visual Basic, C++, XML, HTML, Transact-SQL or PowerShell source code, so you can publish it on a web page or blog post.

Why does the world need yet another syntax highlighter? Mainly, because of none of the existing .Net based ones had the features I needed. That's right, FormatC is the utility I've been using to format source code for my own blog. So if you read my site you've already seen many examples, including this one which demonstrates one of those features I mentioned: Visual Basic XML literals. I dare say I'm one of the first to actually support that, although it does have some limitations (which are mentioned on the FormatC page). In fact, I have support for all C# 3.0 and Visual Basic 9.0 features, including Linq.

You can format your source code using the interface on my site and simply copy/paste the results into a webpage or blog post, and customize the highlighting by editing the provided style sheet (or simply keep the default). You can also download FormatC as a class library to use in your own application, or look at the source code. It's designed to be easily extensible, so you can add your own languages if you want.

If you use it, let me know what you think.

Categories: Programming, Software, General computing
Posted on: 2008-09-06 09:46 UTC. Show comments (3)

Win an MSDN subscription

My good friend Christian Liensberger is giving away two MSDN Premium with Visual Studio Team System subscriptions, worth nearly $11,000! To be eligable you need to create a short screencast about a Microsoft technology, e.g. "how to get started with Silverlight 2". The competition runs from July 1st until July 31st. I will be helping with the judging.

See Christian's blog for full details.

Categories: Programming, General computing
Posted on: 2008-06-28 14:22 UTC. Show comments (1)

Latest posts




RSS Subscribe