Unintelligible

Friday, July 20, 2007

Strongly-named assemblies and InternalsVisibleTo

One of the projects I work on wasn’t using strongly-named assemblies, so we decided to sign them (mainly to prevent version conflicts on sales laptops). However, after generating the key-pair and setting up the different assemblies to use it, building the solution gave this error:

Friend assembly reference ‘Company.Product.UnitTests’ is invalid. Strong-name signed assemblies must specify a public key token in their InternalsVisibleTo declarations.

The problem was that some of the assemblies were making their internals visible to the UnitTests assembly (making them accessible so that they could be tested), but when these assemblies are strongly names, the public key token must also be included in the InternalsVisibleTo declaration in Assembly.cs.

This introduces a chicken-and-egg scenario; the A assembly makes its internals visible to the UnitTests assembly, but must know the UnitTests assembly public key in order to build. The UnitTests assembly depends on assembly A to build, but assembly A can’t be built until we know what the public key token for UnitTests is, which in turn can’t build because it depends on assembly A…

After looking into a couple of solutions, the one that worked for me was:

  1. Sign all assemblies with the key-pair
  2. Generate the public key for the key-pair as such (from the Visual Studio command prompt):

    sn -p path\to\keypair.snk path\to\keypair.pub

  3. Get the public key token for the public key as such (still from the Visual Studio command prompt):

    sn -tp path\to\keypair.pub

    This will output a long (256 characters) public key; copy this to the clipboard

  4. Declare the InternalsVisibleTo attribute in Assembly.cs as such:

    [assembly: InternalsVisibleTo("Company.Product.UnitTests, PublicKey=<your public key>")]

    where <your public key> is replaced by the public key output in (3)

  5. Build the solution. The solution should now build as expected.

This assumes that all assemblies use the same key-pair - suggestions to use the public key token (using PublicKeyToken=... rather than PublicKey=...) didn’t work for me.

posted by Nick at 5:58 pm - filed in .net  

Friday, July 13, 2007

Rubyists and Photographers

I was browsing the net the other day, minding my own business, when I came across this:

http://giantrobots.thoughtbot.com/2007/5/1/coding-without-ifs

In summary, Jared Carroll is proposing to replace

def update_subscriptions
  Subscription.find(:all).each do |each|
    if each.expired?
      each.renew!
    else
      each.update!
    end
  end
end

with

def update_subscriptions
  subscriptions = Subscription.find :all
  expired = subscriptions.select {|each| each.expired?}
  expired.each {|each| each.renew!}
  active = subscriptions.reject {|each| each.expired?}
  active.each {|each| each.update!}
end

in the name of avoiding conditionals in Ruby. You’ll notice that the second version loops through the ’subscriptions’ array 3 times rather than one. In the comments (which span 9 A4 pages) follows a lengthy discussion on the aesthetics and validity of the design of the second solution. It struck me then that Ruby gives you power, a lot of power - perhaps, sometimes, too much power.

I’m reading Paul Graham’s Hackers and Painters at the moment, and continue with his “hacking is like a visual art” analogy, I’d like to propose the following: Ruby is to Java (or C#) what photography is to oil painting. As with all analogies, it has its limitations, but the logic is as follows:

  • creating an image using oil painting is long and hard
  • creating an image using photography is quick and easy
  • because creating an image is quicker with photography, the amount of time spent actually creating the image becomes a proportionally smaller part of the artistic process than it is with oil painting
  • as a result, the percentage of time spent on ’secondary’ considerations (lenses, film types, darkroom exposure techniques, filters, etc.) becomes a proportionally larger part of the artistic process

Most of the professional photographers I know actually spend little time thinking about the secondary considerations such as lenses, film types etc. - they seem to find something they like and stick with it, reviewing their choices only occasionally. However, some get tempted into spending a lot of time and energy debating the relative merits of different lenses, film types, darkroom exposure techniques etc. These items are still only a minor factor of a good picture; the most important element in a good picture is unarguably its content (in a studio picture, this could be the subject, angle, background, lighting, pose etc.)

The similarity here, I think, is that Ruby has empowered programmers to think about the lenses, film types etc. a lot more because taking a picture has just become so much easier. There is not doubt in my mind, however, that whether to use conditional logic or closures is a minor consideration compared to the main (and hardest to attain) aim of the hacker, which is the beauty of the resulting solution; as tempting as it may be to debate the best polarizing filter, debates about language constructs are only as valuable as their contribution to achieving that aim is (which in this case would probably be minor).

P.S. I’m not at all arguing that Jared Carroll or any of the commenters in his blog are bad programmers (most of them are probably more experienced and talented than I am), or that debating about lenses and cameras is pointless - it isn’t, but spending more time thinking about them than actually taking pictures is counter-productive for a photographer. I’m just reminding myself how easy it it to get sidetracked.

posted by Nick at 12:53 pm - filed in ruby  

Thursday, July 5, 2007

Multiple Monitors using Windows Remote Desktop

One of the main limitations of Microsoft’s Remote Desktop client (Terminal Services Client) was its inability to span multiple monitors. This limitation has been fixed in the latest version of Remote Desktop client (v6.0); in my case, this means I can connect to a remote Windows workstation from my home machine and have the remote desktop span both of my monitors, which helps productivity no end. To do this, the latest version of Remote Desktop client is required:

http://www.microsoft.com/downloads/details.aspx?familyid=26F11F0C-0D18-4306-ABCF-D4F18C8F5DF9&displaylang=en
(for Windows XP - it is bundled with Vista)

You can then start remote desktop up to span multiple monitors via the command line:

mstsc.exe /w:2560 /h:1024 /v:<server>

Or by editing the .rdp file in Notepad:

desktopwidth:i:2560
desktopheight:i:1024

Gives this:

desktop

posted by Nick at 10:57 am - filed in windows  

Wednesday, June 6, 2007

WPA using the WPC54G v3 wireless card in Ubuntu Feisty

OK, this is more of a pense-bete to myself than anything else. To get WPA v1 working under Xubuntu Feisty with my WPC54G v3 wireless card, I used the following guides:

To install the wireless card: http://ubuntuforums.org/showthread.php?t=197102
To add WPA: http://ubuntuforums.org/showthread.php?t=202834

The step by step version is as follows.

Installing the wireless card
1. Download this file to the desktop: http://ubuntuforums.org/attachment.php?attachmentid=30908&d=1177587401

2. Extract the file and run the setup:

cd ~/Desktop
tar -xf bcm4318*.tar.gz
sudo ./ndiswrapper_setup

At this point, the wireless card should be installed correctly. This can be verified as follows:

3. This should display some info about your wireless network interface, probably called ‘wlan0′

nick@nick-laptop:~$ iwconfig
wlan0     IEEE 802.11g  ESSID:xxx
Mode:Managed  Frequency:2.437 GHz  Access Point: 00:14:BF:3D:xx:xx
Bit Rate=54 Mb/s   Tx-Power:25 dBm
RTS thr=2347 B   Fragment thr=2346 B
Power Management:off
Link Quality:73/100  Signal level:-49 dBm  Noise level:-96 dBm
Rx invalid nwid:0  Rx invalid crypt:0  Rx invalid frag:0
Tx excessive retries:0  Invalid misc:0   Missed beacon:0

4. This should return a list of wireless networks in your vicinity, including the one you want to connect to:

nick@nick-laptop:~/Desktop$ iwlist scan
wlan0     Scan completed :
Cell 01 - Address: 00:11:50:84:1F:F4
ESSID:"espresso"
Protocol:IEEE 802.11g
Mode:Managed
Frequency:2.462 GHz (Channel 11)
Quality:60/100  Signal level:-57 dBm  Noise level:-96 dBm
Encryption key:on
Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s; 22 Mb/s
6 Mb/s; 9 Mb/s; 12 Mb/s; 18 Mb/s; 24 Mb/s
36 Mb/s; 48 Mb/s; 54 Mb/s
Extra:bcn_int=100
Extra:atim=0

Adding WPA
1. From the wireless access point, make sure of the following:

  • WPA security is enabled using WPA-Personal Shared Key (WPA-PSK)
  • The WPA encryption algorithm is set to TKIP (not AES)
  • You have a note of the SSID (wireless network name) and the PSK (shared key) - here, we will use ‘expresso’ for the SSID and ‘hohohoho’ as an (insecure) PSK example

2. Make sure wpasupplicant is installed:

sudo apt-get install wpasupplicant

3. Convert your PSK as follows:

wpa_passphrase 'your essid' 'your ascii PSK key'

In our example:

nick@nick-laptop:~/Desktop$ wpa_passphrase 'expresso' 'hohohoho'
network={
ssid="expresso"
#psk="hohohoho"
psk=57245dfdd9663e8c9792bfe9a15f41f07cc34a57bd1fc91f2820e3302dbfa7d1
}

4. Open /etc/network/interfaces for editing:

sudo mousepad /etc/network/interfaces

5. Find the lines that look as follows:

auto wlan0
iface wlan0 inet dhcp

Replace as follows:

auto wlan0
iface wlan0 inet dhcp
wpa-driver wext
wpa-ssid <your ssid>
wpa-ap-scan 1 #this assumes SSID broadcast is enabled - set to 2 if SSID broadcast is disabled
wpa-proto WPA
wpa-pairwise TKIP
wpa-group TKIP
wpa-key-mgmt WPA-PSK
wpa-psk <your hex key>

In our example:

auto wlan0
iface wlan0 inet dhcp
wpa-driver wext
wpa-ssid expresso
wpa-ap-scan 1
wpa-proto WPA
wpa-pairwise TKIP
wpa-group TKIP
wpa-key-mgmt WPA-PSK
wpa-psk 57245dfdd9663e8c9792bfe9a15f41f07cc34a57bd1fc91f2820e3302dbfa7d1

6. Make sure any ethernet cables are unplugged, and restart the network interfaces:

sudo /etc/init.d/networking restart

At this point, WIFI should be working with WPA enabled… For further reference regarding different WPA configurations, the WPA guide on the Ubuntu forums is excellent.

posted by Nick at 12:49 am - filed in linux  

Friday, June 1, 2007

Microsoft and Ruby

Martin Fowler’s post on Microsoft and Ruby reflects some of my recent thoughts on MS closely. As he points out, MS is a large company made up of individuals rather than single-minded giant; and as such, there are bound to be differences of opinion within the company as to the direction it should be taking, and how it should approach different situations.

My impressions is that there are two main currents within Microsoft at the moment: those who favour openness and dialogue, who show an understanding of developers’ concerns and who think that discussing these issues and their solutions openly will help Microsoft stay ahead of the pack; and those who seem more intent on responding to managers’ concerns, and who think that Microsoft’s innovations are precious IP and should be kept as far from potential competitors as possible.

Microsoft at the moment seems torn between these two currents, as the difficulties in the inception of Channel 9 (for example) illustrates. The problem for Ruby developers is to figure out which side is going to prevail; if the “open” side does, the result of collaboration with Microsoft could be a strong Ruby implementation on the Windows platform and possibly also good integration with MS’s own technologies, both of which would help further Ruby cause; if it doesn’t on the other hand, the result could be a lot of wasted time and effort which could have been spent more productively elsewhere, and possibly also a dilution of Ruby in a similar way that happened to Java with the MS Java Runtime and J#, which Ruby could take a while to recover from.

So, what to do from Ruby’s point of view? In the current situation, it’s hard to say; ideally, the best would probably be to wait for Microsoft to make its intentions clearer, which it could to by committing to implement a Ruby interpreter fully compatible with the MRI, by opening up the source code for the Iron Ruby implementation, or perhaps by issuing a Patent Non-Assertion Covenant on any Ruby-related technologies it develops. None of these may be realistic for Microsoft in the short term; efforts at openness are still relatively new at MS, and pushing through this type of measure internally probably takes a lot of time and determination. Perhaps the competition from Sun (one of MS’s traditional rivals) via JRuby combined with a better understanding of how Ruby could benefit MS could help move things forwards.

Update 4/7/2007: Martin Fowler’s post seems to have gotten those involved in Ruby implementations talking:
John Lam (IronRuby lead): Microsoft and IronRuby
Ola Bini (JRuby committer): There can be only one, a tale about Ruby, IronRuby, MS and whatnot
Charles O. Nutter (JRuby lead): A Response to Ola’s IronRuby Post

posted by Nick at 10:12 am - filed in ruby  

Tuesday, May 8, 2007

Problem Installing .Net Framework 3.0

The .Net Framework 3.0 refused to install on my machine this morning - a quick look through the installation logs (particularly C:\DOCUME~1\<your user name>\LOCALS~1\Temp\VSW1\VSSWMSIFailInfo.txt) revealed the following:

Error 1402.Could not open key:
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Eventlog/Security/ServiceModel 3.0.0.0.
System error 5. Verify that you have sufficient access to that key,
or contact your support personnel.

I am a local admin on my machine, so this surprised me a little. The permissions on this key were set to grant Full Control to the ASP.NET user. I granted myself Full Control, but this didn’t seem to help. Granting Everyone Full Control seemed to resolve the issue - other keys in the subtree grant Full Control to the local Administrator group and the System user, so I revoked permissions from Everyone and granted these access to the key once the installation was complete (ah, the power…).

posted by Nick at 6:55 pm - filed in .net  

Friday, May 4, 2007

Using WatiN to automate accessibility testing in .Net

WatiN is a web testing framework for .Net - it is a C# port of Watir, which is in Ruby. Both function by driving Internet Explorer and are fully scriptable, which means you can do things like:

[Test]
public void SearchForWatiNOnGoogle()
{
    using (IE ie = new IE("http://www.google.com"))
    {
        ie.TextField(Find.ByName("q")).TypeText("WatiN");
        ie.Button(Find.ByName("btnG")).Click();
        Assert.IsTrue(ie.ContainsText("WatiN"));
    }
}

This is from the WatiN documentation page, which is pretty helpful - as this shows, it’s easy to get started, and writing basic tests is straightforward (although perhaps not as fast as the Ruby version). WatiN also integrates well with NUnit and other testing frameworks (including TestDriven.Net and the Visual Studio 2005 test runner). I’ve been using this at work to run some basic accessibility tests on some of our web-based products; although accessibility testing can’t be completely automated, it’s pretty handy to be able to perform repetitive HTML inspections automatically. This checks that all <img> tags on a page have the required “alt” attribute (required in the WCAG 1.0 guidelines on images):

[Test]
public void CheckAllImagesHaveAltAttributes()
{
    using (IE ie = new IE("http://localhost/test.aspx"))
    {
        foreach (Image img in ie.Images)
            if (img.Alt == null || img.Alt.Trim().Length == 0)
                Assert.Fail(
                    String.Format("The image with id '{0}' "
                    + "and src '{1}' doesn't have a alt tag "
                    + "in '{2}'",
                    img.Id, img.Src, ie.Url)
                );
    }
}

This checks that all links on a page have a “title” attribute (an overly strict interpretation of the WCAG 1.0 guidelines on links):

[Test]
public void CheckAllLinksHaveTitleAttributes()
{
    using (IE ie = new IE("http://localhost/test.aspx"))
    {
        foreach (Link link in ie.Links)
            if (link.Title == null || link.Title.Trim().Length == 0)
                Assert.Fail(
                    String.Format("The link with id '{0}' "
                    + "and text '{1}' doesn't have a title tag "
                    + "in '{2}'",
                    link.Id, link.InnerHtml, ie.Url)
                );
    }
}

Or that all input fields in a form have an associated “label” tag (WCAG 1.0 guidelines on form labels):

delegate void TestInputFor(IE ie, Element inputField);
 
[Test]
public void CheckAllFormFieldsHaveLabels()
{
    using (IE ie = new IE("http://localhost/test.aspx"))
    {
        TestInputFor assertElementHasLabel =
            delegate(IE ieInstance, Element inputField)
        {
            //check whether the corresponding label exists.
            Debug.WriteLine("Checking whether element "
                + inputField.Id + " has a label");
            int cnt = 0;
            foreach (Label lbl in ieInstance.Labels)
                if (lbl.For.Equals(inputField.Id))
                    cnt++;
            //assert the label was found
            Assert.AreEqual(1, cnt,
                String.Format("Expected a label for text field"
                + " with ID {0}, but found {1:d} in page '{2}'",
                inputField.Id, cnt, ieInstance.Url));
        };
 
        foreach (CheckBox cb in ie.CheckBoxes)
        {
            assertElementHasLabel(ie, cb);
        }
 
        foreach (TextField tf in ie.TextFields)
        {
            if(tf.GetAttributeValue("type").Equals("hidden"))
                continue;
            assertElementHasLabel(ie, tf);
        }
 
        foreach (SelectList sl in ie.SelectLists)
        {
            assertElementHasLabel(ie, sl);
        }
 
        foreach (RadioButton rb in ie.RadioButtons)
        {
            assertElementHasLabel(ie, rb);
        }
    }
}

These are rather basic tests; and they are far from extensive. However, they should give a good idea how much time can be saved by automated testing, especially in the context of standard systems which get customised on a per-client basis (e.g. a content management system for which the layout is customised on a per-client basis; the tests are written once and can be run against each client’s version).

posted by Nick at 8:00 pm - filed in .net, accessibility, testing  

Thursday, October 5, 2006

String Formatting in C#

String formatting is handy to save on both code and garbage collection - it saves on code because it handles formatting including localisation in a way which would be tedious to reproduce manually, and on garbage collection because it uses a StringBuilder internally to perform its magic. This is a quick reference for the different types of formatting offered by the String.Format() method.

Basics

String formatting occurs via character subsitution: control characters in the string to be formatted are replaced with the arguments you provide it as such:

String.Format("{0} says hello", "John");

-> "John says hello"

Here, {0} is substituted with the argument provided - you can pass up to three arguments or an argument array:

String.Format("{0} from {1} says hello to {2}", "John", "Sheffield", "Jane");
 
String.Format("{0} from {1} says hello to {2} from {3}", new object[]{"John", "Sheffield", "Jane", "Hull"});

The parameters to be substituted (e.g. {0}) are formatted as such:

{<index>[,<alignement>][:<format specifier>]}

Where:

  • index is the index of the object in the argument array to be used in the substitution
  • padding determines whether the substituted string should be padded to be a certain length
  • the format specifier allows the use of predefined formatting for the parameter

The .Net Framework provides standard specifiers depending on the type of the argument, as well as the ability to perform custom formatting for numeric and DateTime data types. The following specifiers can be used:

Numerals - Standard Formatting

The following standard specifiers are available for formatting numbers:

Specifier Name Syntax Output
(using double 9.8765)
Output
(using int -98765)
c (or C) Currency {0:c} £9.88 -£98,765.00
d (or D) Decimal
(whole number)
{0:d} System.FormatException -98765
e (or E) Exponent {0:e} 9.876500e+000 -9.876500e+004
f (or F) Fixed point {0:f} 9.88 -98765.00
g (or G) General {0:g} 9.8765 -98765
n (or N) Number {0:n} 9.88 -98,765.00
r (or R) Round trippable {0:r} 9.8765 System.FormatException
x (or X) Hexadecimal {0:x} System.FormatException fffe7e33

The currency specifiers is culture-dependent, and output will depend on the Locale of the current thread - the example outputs come from my box running with the “en-UK” locale, but would be different when run on another locale.

Numerals - Custom Formatting

In addition to the standard date specifiers, the following specifiers can be used for custom number formatting:

Specifier Name Syntax Output
(using double 9.8765)
Output
(using int -98765)
0 Zero Placeholder {0:00.0000} 09.8765 -98765.0000
# Digit Placeholder {0:##.##} 9.88 -98765
. Decimal Point Separator {0:#.#} 9.9 -98765
, Thousands Separator {0:#,#} 10 -98,765
% Percentage {0:#%} 988% -9876500%
e (or E) Exponent Placeholder {0:00e+000} 99e-001 -99e+003
; Group Separator {0:#,##0.00;(#,##0.00);Zero} 9.88 (98,765.00)

Dates - Standard Formatting

The following standard specifiers are available for formatting dates:

Specifier Name Syntax Output
(using June 6th, 2000, at 00:00:01)
d Short Date {0:d} 01/06/2000
D Long Date {0:D} 01 June 2000
t Short Time {0:t} 00:00
T Long Time {0:T} 00:00:01
f Full date and time (short time) {0:f} 01 June 2000 00:00
F Full date and time (long time) {0:F} 01 June 2000 00:00:01
g Default date and time (short time) {0:g} 01/06/2000 00:00
G Default date and time (long time) {0:G} 01/06/2000 00:00:01
M Day and Month {0:M} 01 June
r RFC1123 date string {0:r} Sat, 01 Jun 2000 00:00:01 GMT
s Sortable date and time (ISO 8601) {0:s} 2000-06-01T00:00:01
u Universal, local time {0:u} 2000-06-01 00:00:01Z
U Universal, UTC time {0:U} 31 May 2000 23:00:01
Y or y Month and Year {0:Y} June 2000

Dates - Custom Formatting

In addition to the standard date specifiers, the following specifiers can be used for custom date formatting:

Specifier Name Syntax Output
(using June 6th, 2000, at 00:00:01)
dd Day Number {0:dd} 01
ddd Short Day Name {0:ddd} Sat
dddd Full Day Name {0:dddd} Saturday
f, ff, fff etc… Second fractions {0:fff} 000
gg Era {0:gg} A.D.
hh 2 digit hour (12 hour) {0:hh} 00
HH 2 digit hour (24 hour) {0:HH} 00
mm 2 digit minute {0:mm} 00
MM Month Number {0:MM} 06
MMM Short Month Name {0:MMM} Jun
MMMM Full Month Name {0:MMMM} June
ss Seconds {0:ss} 01
tt AM/PM {0:tt} AM
yy 2 digit year {0:yy} 00
yyyy 4 digit year {0:yyyy} 2000
zz Short Timezone Offset {0:zz} +01
zzz Full Timezone Offset {0:zzz} +01:00
: Separator {0:hh:mm:ss} 00:00:01
/ Separator {0:dd/MM/yyyy} 01/06/2000

All of these specifiers are culture-dependent (apart from the Universal specifiers, which are universal and therefore not culture-dependent), and will depend on the Locale of the current thread - the example outputs come from my box running with the “en-UK” locale, but would be different when run on another locale.

Enumerators

The following standard specifiers are available for formatting Enums:

Specifier Name Syntax Output
(using DateTimeKind.Local)
g General (Flag if present, Decimal otherwise) {0:g} Local
f Flag (string) {0:f} Local
d Decimal {0:d} 2
x Hexadecimal {0:z} 00000002

Strings

The only formatting available to Strings is the padding option, which can be positive or negative depending on whether the string should be left- or right-aligned:

String.Format("'{0,10}'", "John");

-> ' John'

String.Format("'{0,-10}'", "John");

-> 'John '

Culture

As mentionned previously, the currency and date formats are culture-dependent. This means that the output of the formatted string will depend on what locale is made available to the method. By default, the String.Format method will use the locale of the current thread as a basis for formatting; the current thread locale can be set as such:

//set the culture in the current thread to French
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");
String.Format("{0:c}", 22.45);

-> 22,45 €
String.Format is also overloaded to accept a CultureInfo argument, which can be used to format a DateTime or currency based on a specific locale:

//Format a currency using French currency formatting
String.Format("{0:c}", 22.45, new CultureInfo("fr-FR"));

-> 22,45 €

Sample Code

Sample code demonstrating all of the specifiers mentionned above and setting the culture for the current thread:
C# String Formatting - Sample Code

This code can be compiled using the C# compiler and run from the command line. Using the command prompt (and assuming the code has been saved to C:\StringFormatExample.cs):

C:>SET PATH=%PATH%;%WINDIR%\Microsoft.NET\Framework\v2.0.50727;
C:>csc StringFormatExample.cs
Microsoft (R) Visual C# 2005 Compiler version 8.00.50727.42
for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727
Copyright (C) Microsoft Corporation 2001-2005. All rights reserved.

C:>StringFormatExample.exe fr-FR

Reference

There is actually quite a reasonable amount of reference material available - I only found the other two blog posts after writing this though :-/ (I decided to post anyways)

MSDN docs for standard number formatting

MSDN docs for custom number formatting

MSDN docs for standard date formatting

MSDN docs for custom date formatting

http://blog.stevex.net/index.php/string-formatting-in-csharp/

http://idunno.org/archive/2004/14/01/122.aspx

posted by Nick at 6:51 pm - filed in .net  
Previous Page