Thursday, June 12, 2003

schtasks




Keith Brown just pointed me to schtasks, the new (as of XP, apparently)
command-line task scheduler. It’s the replacement for the venerable at command,
and running schtasks /? from the command
line shows that it has a boatload of
options. Including the abilities to run the tasks under arbitrary credentials and
to terminate tasks at a specific time. Cool.



I’ve been meaning to get my backup story whipped into shape…this
may be just the ticket.



Saturday, June 7, 2003

Gone for a few




My wife and I are about ten hours away from walking off into the Rocky
mountains. We’ll be spending a few days camping here in Colorado. The weather
looks to be beautiful, although at higher elevations it seems we’ll be hiking
over, and camping on, snow. I’m looking forward to it!



Side Effects and Code Generation

I’ve been working with Tim Ewald this week here in not-so-sunny Minnesota. As is usual when I hang out with Tim, my brain hurts from trying to keep up.

We had an interesting discussion over lunch yesterday. We were discussing – among other things – how the CLR has made things so much easier than they used to be that programmers have fallen into a death spiral of trying to abstract everything away. The fact that you can write the same application with about 4x less code leads us to try to cut things even further: a whole app in zero lines of code being the ultimate experience. Obviously I’m exaggerating, but I think the phenomenon of seeking to do things with fewer and fewer lines of code is a real one. And not a new one – if you’ve ever seen a C++ program that got a little bit too clever with preprocessor macros, you know what I mean.

The latest incarnation of “less is more” is the declarative programming model popularized (in the Microsoft world) by MTS and then COM+. The idea there was that you’d simply write your code, flip a few switches, and suddenly all sorts of magical services would appear at your fingertips. Transactions! Synchronization! Security! Just check a box. Or, if you’re programming in the CLR, just add an attribute. Clemens Vasters has been making the rounds lately showing how he has embraced this model to allow you to do all sorts of things by simply adding attributes to your code. It sounds like a great idea.

The problem is, it doesn’t work. It never has.

For a while, I tried to take the other side against Tim. Probably mostly because I’d recently done a bunch of this “hide everything from the programmer” work for a client of mine. But Tim has traveled this road for too long – after all, he wrote the best COM+ book there is. He made mincemeat out of my arguments. Which is hardly surprising – I studied COM+ under Tim for years, and already agreed with him. I just needed to be reminded. Tim pointed out a few things I already knew:

·        How COM+ is fundamentally broken around synchronization and STAs

·        How switching off one service in COM+ often requires you to switch off several others (e.g. transactions and synchronization)

The basic problem here is that services are not generally orthogonal. What that means is that it’s impossible to simply slap a new behavior onto code without understanding all the other behaviors that are already there. Don’t believe me? Then ask yourself why the CLR’s context infrastructure has IsContextOK. This is the method that – when implementing a new service – lets you look around your environment and decide if you’re compatible with all the other services that are already present. This has two basic problems:

1.      How do you know if you’re compatible with a given service that didn’t even exist when you were created?

Wednesday, June 4, 2003

runas Magic




If you have followed any of the “Running as non-admin”
traffic that’s been fairly prevalent of late, you’ve probably heard of
the
runas command. Runas lets
you  launch a process with alternate credentials in the current window station.
Generally, you use this to do things like fire up a new instance of Visual Studio
under administrative credentials so you can debug ASP.NET applications or something.



Today I ran across an entirely new option: the /netonly switch.
Using it means that the credentials you supply don’t
have to be valid on the machine you’re running it on, but will still be passed
on when remote calls are made!
So
cool. Why? Because I’m doing work with Microsoft, and I need to do things against
their servers that require authentication. I don’t want to join my machine to
their domain, which means I can’t get a process running under my Microsoft domain
account. However, using this switch, I can make a process look to remote systems as
if it were running under my Microsoft domain account. This turned out to be crucially
important for getting our build process working on my machine.



The one caveat is that since it doesn’t do an actual login, it’ll
take whatever password you throw at it. Even if it’s wrong – you won’t
find out until you try to actually use those credentials.



Tuesday, June 3, 2003

Public Domain Enhancement Act




This sounds like a good idea to me.  I signed.




From Larry
Lessig
:




We have launched a petition to
build support for the Public Domain
Enhancement Act
. That act would require American copyright holders to pay $1 fifty
years after a work was published. If they pay the $1, the copyright continues. If
they don't, the work passes into the public domain. Historical estimates would suggest
98% of works would pass into the pubilc domain after 50 years. The Act would do a
great deal to reclaim a public domain.



This proposal has received a great deal of support.
It is now facing some important lobbyists' opposition. We need a public way to begin
to demonstrate who the lobbyists don't speak for. This is the first step.



If you are an ally in at least this cause, please
sign the petition. Please blog it, please email it, please spam it, please buy billboards
about it -- please do whatever you can. And most importantly, please help us explain
its importance. There is a chance to do something significant here. But it will take
a clearer, simpler voice than mine.




Now go and sign that petition.




Never doubt that a small group of thoughtful
committed people can change the world: indeed it's the only thing that ever has.

-- Margaret Meade







[BitWorking]




In MN This Week

My work with MSDN has taken me to the Minneapolis/St. Paul area this week. It turned out to be convenient because one of the team members lives here (the rest of us are scattered elsewhere) and MSFT has a big empty office we can work in. You won't hear me complaining about making the trip: I lived here until a year ago, and still have a lot of family and friends in the area.

Nothing like a free trip home.

Sunday, June 1, 2003

These Are a Few of My Favorite Things




I was writing some code Friday, and I realized I was working with three
of my favorite namespaces all at once:
System.IO, System.Xml, and System.Diagnositcs.
Most people will have used all of these namespaces at least once, but there are a
bunch of hidden gems that not everyone will have seen.



The task I was trying to pull off was to dump an XML document for debugging
purposes. I wanted to send it both to the console and to a logfile, to give me a real-time
idea of what was going on as well as a permanent record I could go back and analyze
later.



The ability to write a piece of information to more than one place
for diagnostic purposes just cries out for
System.Diagnostics.Trace.
So I started my program off with the following lines of code:



using System;

using System.IO;


using System.Diagnostics;




public class App

{

  public static void Main()

  {

    Trace.Listeners.Add(

      new TextWriteTraceListener(Console.Output));


    string logfile =

      DateTime.Now.ToString("yyyy-MM-dd-hh-mm-ss")
+ ".txt";


    Trace.Listeners.Add(

      new TextWriteTraceListener(logfile);



which sets it up so that any time I call Trace.WriteLine,
a piece of text is written both to the command console and to a logfile whose name
is derived from the current date and time. The overload of ToString that
lets you specify the exact format for the date and time is pretty cool, I think.



Later, when I wanted to actually dump the XML, I did this:



StringWriter sw = new StringWriter();


XmlTextWriter wtr = new XmlTextWriter(sw);


wtr.Formatting = Formatting.Indented;


xml.WriteTo(wtr);




Trace.WriteLine(sw.ToString());


wtr.Close();



where xml is the XmlDocument that
I wanted to dump out.



There are a number of cool things in these few lines of code:



·        The StringWriter class
give you a stream that  you can use anywhere you’d use a normal TextWriter (e.g.
the constructor of XmlTextWriter),
but it writes to an internally maintained StringBuilder instead.
Handy.



·        The Formatting property
of XmlTextWriter to get that nice “every
nested element gets indented one level” look. Makes for much more readable output.



·        Of
course, the call to Trace.WriteLine to
actually spew this same XML to more than once place.



A few caveats:



·        You
need to define the symbol TRACE in your build (Project Properties->Configuration
Properties->Build->Conditional Compilation Constants – just type in TRACE)
or Trace.WriteLine will not even make
it into the compiled program.



·        I
found that I needed to go through and flush each trace listener independently, or
my log file would get truncated. That was easy, though: just a foreach loop over the Trace.Listeners collection,
calling Flush and Close on
each TraceListenener.