Thursday, December 30, 2004

File Sharing Via RDP

This one might fall into the “I'm the last guy to find this out” category, but given that I'm a regular user of Remote Desktop and I didn't notice it until a friend pointed it out, I'm guessing that others haven't discovered this little gem, either.


If you're connecting via the Remote Desktop Client to another machine, and you want to be able to copy files from here to there, open up “Options” and under “Local Resources” check “Disk Drives”, like so:



Then, when you connect to the remote computer, the remote computer will be able to see your local drives as if they were on the remote computer, making it trivial to drag and drop files via Explorer.

Tuesday, December 14, 2004

I'm Pro-xs:choice

There's been lots of debate about use of DataSets with web services. The issue is interoperability: the default WSDL representation of a DataSet is an arbitrary schema followed by arbitrary XML. That's just a bit on the loose side for most toolkits to deal with in the general case. However, one use case that drives the desire to use a DataSet in the first place is that the type of data to be returned is not known precisely until runtime. Lately, I discovered yet another corner of XmlSerializer that helps me deal with some of these situations without having to resort to using a DataSet.


It turns out that sometimes, although you don't know the exact type of data you'll be returning, you do know that it's going to be one of a known set of types. This is particularly common when you're returning the results of a database query: you might know that all your columns are either strings, booleans, integers, dates, or floating point numbers. If that's the case, there's an XML schema construct that allows you to say, “I want to have one of the following elements appear here.” It's called <xs:choice>, and here's a schema fragment that demonstrates its use:



<xs:element name=“item“>
  <xs:complexType>
    <xs:choice>
      <xs:element minOccurs=“1“ maxOccurs=“1“ name=“string“ type=“xs:string“ />
      <xs:element minOccurs=“1“ maxOccurs=“1“ name=“integer“ type=“xs:int“ />
      <xs:element minOccurs=“1“ maxOccurs=“1“ name=“boolean“ type=“xs:boolean“ />
      <xs:element minOccurs=“1“ maxOccurs=“1“ name=“date“ type=“xs:dateTime“ />
      <xs:element minOccurs=“1“ maxOccurs=“1“ name=“float“ type=“xs:float“ />
    </xs:choice>
  </xs:complexType>
</xs:element>


What this schema means is that when an “item” element appears, it must have as a child exactly one of the elements <string>, <integer>, <boolean>, <date>, or <float>. Further, if the child element is <string>, the contents of that element must be a string. But if the child element is <integer>, then the contents must be an integer, and so on and so forth. It's a reasonably “normal“ bit of schema, and while I have no idea what the support in various non-.NET toolkits looks like, support for it is a lot more likely to exist than for the vagaries of DataSet.


From an XML standpoint, this is a pretty nice thing. It lets us express exactly what we want, namely, that we'll tell you at runtime what our choice for the type of the data is. Where this gets really great is that it's supported by System.Xml.Serialization, which powers the ASP.NET Web Services stack.


Here's how it maps: you define a class with the usual attributes from the System.Xml.Serialization namespace. But when you get to the element that you want to represent as an <xs:choice>, you simply use more than one [XmlElement] attribute, and you use the overload that lets you specify a type. Here's what I mean:


[XmlRoot(”item”)]
public class Item
{
  private object value; 

  [XmlElement(“string“, typeof(string))]
  [XmlElement(“integer“, typeof(int))]
  [XmlElement(“boolean“, typeof(bool))]
  [XmlElement(“date“, typeof(DateTime))]
  [XmlElement(“float“, typeof(float))]
  public object Value
  {
    get { return value; }
    set { this.value = value; }
  }
}


When the serializer encounters this type during either serialization or deserialization, it will use the attributes to control the mapping between element names and .NET types. Which is to say, when the Value is a float, you'll get <float>, when the Value is string, you'll get a <string>, and (better still) vice versa! You have to do a type test and typecast at the other end, like this:


if (foo.Value is string) { DealWithString((string) foo.Value); }
else if (foo.value is float) { DealWithFloat((float) foo.Value); }
// etc.


But big deal. :)


By itself, this is a fairly powerful feature. And there's still more we can do, but I think I'll stop this entry now while this entry is still reasonably short. More later.

Thursday, December 9, 2004

A Sad Day for Metal

I'm a fan of heavy metal music, although usually more specifically progressive heavy metal. Nevertheless, I enjoy straight-ahead, ass-kicking, hard-core metal quite a bit, and they don't come much harder core than Pantera. Thus, I was saddened to hear that Dimebag Darrell, their lead guitarist, was fatally shot while performing with his new band Damageplan last night. At this time, it's unclear whether his brother Vinnie Paul (formerly Pantera's drummer) was also shot, and if shot, whether he was killed. I certainly hope not for the sake of their family.


Dimebag was a huge influence on an entire generation of metal and nonmetal musicians. It's not unfair to compare the impact of his death on the musicians I most enjoy to that of the death of John Lennon on his generation...especially when you realize that Lennon was also killed on December 8th.

Wednesday, December 8, 2004

Tabs Are Evil

For about the 10,000th time today, I opened a file that looks something like this:


  static Crypto()
        {
            // Set up the Rsa provider to use the machine key store. If you don't,
            // creating the provider will fail when you run under ASP.NET. 


  CspParameters cp = new CspParameters();
            cp.Flags = CspProviderFlags.UseMachineKeyStore;


      // TODO: verify that we can encrypt 5 bytes, just so we don't get a 
           // false positive that makes us think we failed because of block size
     
I highly doubt that the developer who wrote it would have put up with this randomly indented presentation, so why do I have to? The problem is that developers love to hit the tab key to line things up, which generally inserts a tab character. Of course, different people and different editors choose different widths to use to display a tab character. Worse, it's easy to mix using tabs and spaces to align your code. After all, it'll look lined up to you, but when I open it, I get the mess above.


So, run, don't walk, to your favorite development tool and set the equivalent of this VS.NET option:



This will cause VS.NET to insert n spaces (instead of a tab character) whenever you hit the tab key, where n is whatever value you put in the “Tab size” textbox. I don't particularly care what number you use (although 2 is clearly the choice of the most discerning developers) - the point is that as long as you don't use tabs to line up your code, it'll line up for both of us.


This has been a public service message brought to you by the Terminally Picky Developers Association for Readable Code.

Wangdera.Controls 0.9.1 Released

Well, at least one person out there is using the Wangdera Control Suite...because they noticed I shipped a major bug with version 0.9. Basically, if you called the BatchFormat method to format a range of text, any text you subsequently typed into that range would be rendered as black on a black background. It's like, how much more black could this be? And the answer is none. None more black. Whoops.


I will protest that it's not entirely my fault. The problem is that the underlying Windows Rich Edit control (hate it!) will lie to you about what the format of the text is. So when I was saving the format of the text and then “restoring“ it later, it was causing a problem. But since I knew about the problem when I shipped 0.9, I probably should have caught the bug.


Anyway, it's fixed now, and you can download it. And it was a good excuse to refresh my memory on how branching and tagging works in CVS, since we're going to need it for FlexWiki.

Tuesday, December 7, 2004

Escaping ${} in NAnt Scripts

Today I was writing a NAnt script that calls an XSLT, passing in some regular expression replacement arguments so I could use replace occurrences of certain strings in an XML file. The problem I ran into is that the syntax for a regex replacement is ${group}, which is exactly the same as the syntax for a property in a NAnt script. I figured there must be an escape sequence in NAnt that lets you say, “No, I really want a dollar sign and a curly brace - I'm not specifying a property.“ But I tried backslash and the other usual suspects, then searched the web for a while. Nothing.


I banged my head against the problem for a while, and finally came up with this:


<property name="replacement" value="http://localhost/${product.name}-${websafe.version}${'${path}'}" />


It's the ${'${path}'} that actually does the trick: basically, I'm saying, “Use the string literal ${path}.“


I'm pretty sure this will only work in NAnt 0.85 and later, as that's when string literal expressions were introduced.

Why You Shouldn't Be Using Passwords of Any Kind on Your Windows Networks...

An interesting title for an interesting post. [ Robert Hensing's Incident Response WebLog ]

Sunday, December 5, 2004

Wangdera.Controls 0.9 Released

Babies do indeed take up a lot of time, but fortunately I'm still able to work on my little side projects now and then. So this weekend I was able to put the finishing touches on the 0.9 release of the Wangdera Control Suite. Specifically, I've fixed a bunch of bugs with RichTextBox2 and RichTextEditor, and added paragraph formatting capabilities in. So now you can do things like bulleted and numbered lists, set line spacing, and set the justification. Basically, I believe I've now exposed everything that's present in the underlying rich edit control. Combine that with the other performance and feature enhancements, and I think I've made something that's a real improvement over the (decidedly lame) RichTextBox.


Even though I labeled the version number 0.9, I really see this as more of a 1.0RC1 release. That is, I think it's ready for prime time, but I'm willing to believe there are still a few bugs. (Actually, I know there are a few minor bugs, but the ones I know about are because of weird behavior in the underlying control, so there's not much I can do about them.) Of course, I've already determined that the rich edit route is the wrong one for me, but like I said before, I still think it'll be useful for someone. So I got it done and posted so I can move on to the next thing. Enjoy!


If it seems like all I do on this blog lately is announce the release of software, well, that's because I've been working pretty hard on releasing software. :)


Now, on to understanding Uniscribe!

Wednesday, December 1, 2004

Nice Managed DirectX Site

I agree with David Weller on this one:



Big kudos to Andy "ZMan" Dunn who has created a website, The Z Buffer, that's completely dedicated to Managed DirectX goodness.  So, the best thing I can say is, "Stop reading this blog and get over there!" :-)