12 Tenets to Promote Competition Announced
20 July 06 11:58 AM | ScottSeely | 0 Comments   

Over here, we just put out a press release about what we will do to allow for more competition within the Windows ecosystem. The words point to some potentially exciting developments. My curiosity is piqued in that I'd like to find out how much can be replaced from the OS. Dropping in a new browser or media player isn't too tough-- that problem has a well understood solution. I'm more curious about how much one can replace. I know that more than a few research types would like to be able to replace things like:

  • The memory manager
  • The device management subsystem
  • The file system
  • The registry

If anyone has more data that is publically available, it would be great to see it posted.

Using Virtual Machines
19 July 06 08:04 PM | ScottSeely | 0 Comments   
I've found an interesting way to interact with a Virtual Server 2005 R2 Virtual Machine in a fairly performant way: through Terminal Server/Remote Desktop Connection/mstsc. If you are a person with access to an MSDN subscription, install Windows Server 2003 on a machine. Then, go out to the web (http://www.microsoft.com/windowsserversystem/virtualserver/default.mspx) and install the free Virtual Server 2005 R2 on that Server box. Once the virtual machine is all setup, enable remote desktop connection on the machine and the use Remote Desktop to use the virtual machine. In my experience, the overall user experience and perceived performance is better than when using the Virtual Server ActiveX control from within a Web Browser. And this definitely trumps using Virtual PC.

Using Remote Desktop on Windows Server 2003: http://technet2.microsoft.com/WindowsServer/en/Library/1e4a44de-2be1-4d29-9387-9f04b79cc17a1033.mspx?mfr=true. The easy way to enable the feature is under the heading "Using System Properties".
Running Vista at home
18 May 06 11:01 AM | ScottSeely | 4 Comments   

I recently moved over to the Transactions team-- proud owners of System.Transactions, MSDTC, and OleTx. As I ramp up over there, I thought I would get in the habit of posting by keeping a small journal of what it's like to convert over to Vista at home.

First, what does the machine look like? It's an HP Pavilion zd8000. I bought this machine for two reasons: it is a portable desktop and it works well as a Media Center PC. I figured that when the laptop inevitably falls too far behind the technology curve, it'll still work as a PVR. As a portable desktop, it has a 100 GB hard drive, 17" widescreen monitor, !GB main memory, 256 MB video RAM, full size keyboard, and built in everything (wireless, network, modem, bluetooth, firewire, loads of USB ports, and a multi-function media card reader). FWIW, I also discovered that the particular machine I own shipped with a 64-bit CPU. Unfortunately, most of the drivers only exist as 32-bit, so I stuck with a 32-bit install of Windows.

Yesterday, I brought in the laptop and loaded Vista + Office 2007 onto the machine. Why both? That's the way the image is setup on the network. We're currently dogfooding Windows Deployment Services, the successor to RIS. My first impression of WDS-- NICE! I did a clean install on my machine and was logging into my account within 20 minutes. Previously, a similar install would take about one hour.

I spent about 30 minutes loading drivers for devices Device Manager identified as missing. Between Windows Update and the manufacturer's web site, everything was up and running.

This PC spends a lot of time as a PVR and bedroom TV. Last night, I saw the following improvements in Media Center:

  • The volume is greatly improved. The control has a set of levels scaled from 1 to 25. On Media Center 2005, I needed to have the volume control somewhere around 19 in order to hear the show from about 10 feet away. Last night, the control spent a good amount of time around 3 or 4. The laptop has built in Altec Lansing speakers. Media Center on Vista is finally driving the speakers much better.
  • When viewing the Guide, changing settings, or doing other navigation while watching a show, Media Center 2005 would drop the current show to a miniscule box that was only viewable if I was on top of the computer. On Vista, the current program still takes up the full screen and the menu navigation just overlays the whole thing so you can read the guide and see your program.
  • Channel switching feels faster. I can't quanitify this, but the responsiveness seems to match that of my other TVs instead of being slower.

Vista also has a new technology called 'SuperFetch'. The idea is that over time, Vista will learn your habits and load commonly used applications faster. This PC sees most of its time in Visual Studio, Outlook and Media Center (I haven't loaded any games... yet). My first few loads of these applications did seem SSSLLLLLOOOOOWWWW. Slow enough that I was thinking "If things don't improve, I'm ending the experiment." This morning, I booted up and flicked on Media Center to watch the local news. Instead of seeing a long delay, I was just in and watching TV. This was faster than what I had experienced yesterday on Media Center 2005. It seems that I got a sub-second response to having the application open. I think I just experienced SuperFetch.

I see some things that I have yet to figure out too. I'll go into those in my next post.

WCF Config guy has started blogging
28 April 06 01:40 PM | ScottSeely | 0 Comments   
If you have any questions on config, check out http://blogs.msdn.com/markgabarra/. He took over config shortly after I went 'dark'.
dark blog
22 November 04 03:46 PM | ScottSeely | 0 Comments   

I just wanted to state that this blog is dark because I'm busy working on things that I can't talk about... yet. I'll start posting again when Indigo goes to beta.

Origins of the Bill Gates e-mail hoax
30 June 04 12:42 PM | ScottSeely | 2 Comments   

!Warning. Pointless entry follows!

Jonathon Keats at wired.com managed to track down the person who started the “Forward this e-mail and Bill Gates will send you money” hoax. I think everyone in my family has, at one point or another, asked me if this program was still going on. The article is a good read.

Configuration Backgrounder
21 April 04 01:13 PM | ScottSeely | 5 Comments   

disclaimer This posting is provided "AS IS" with no warranties, and confers no rights.

 

In my last blog entry, I got a couple of requests for getting “strongly typed” accessors for config. Since the blog format lets me take a meandering walk through configuration, I’ll address things you should do to make your ConfigurationSection-derived class easier to use. First, let me hit some background information because it looks like y’all want some context.

System.Configuration.ConfigurationSettings

In v1.0 and 1.1, there was only one view of configuration: run-time. That view is implemented by an object call System.Configuration.ConfigurationSettings. ConfigurationSettings returns configuration sections through calls to a static method named GetConfig(string sectionName). The sectionName you passed into GetConfig checks to see that the sectionName itself is valid before any config files are opened. The list of valid sectionName strings can be discovered by looking at the configuration section named configSettings. configSettings itself can contain two types of elements:

  • section: Indicates the name of the section and the type that knows how to parse the section. Note: this is not guaranteed to be the same as the type returned by ConfigurationSettings.GetConfig().
  • sectionGroup: Used to “bucket” other sections and sectionGroups. In v1.0 and v1.1 of the framework, this element only had a name attribute. In Whidbey, this element also has a type (more on that in a bit).

Let’s take a look at a hypothetical configuration file:

<configuration>

    <configSettings>

        <section name="sectionOne"

            type="MyNamespace.SectionOne, MyAssembly,..."/>

        <sectionGroup name="sectionGroupOne"

            type="MyNamespace.SectionGroupOne, MyAssembly,...">

            <section name="sectionTwo"

                type="MyNamespace.SectionTwo, MyAssembly,..."/>

            <sectionGroup name="sectionGroupTwo"

                type="MyNamespace.SectionGroupTwo, MyAssembly,...">

                <section name="sectionThree"

                    type="MyNamespace.SectionThree, MyAssembly,..."/>

            </sectionGroup>

        </sectionGroup>

    </configSettings>

</configuration>

Given this set of settings, the following strings can be passed into ConfigurationSettings.GetConfig() and the caller has reason to believe that a value should be returned:

  • sectionOne
  • sectionGroupOne/sectionTwo
  • sectionGroupOne/sectionGroupTwo/sectionThree

What happens here is that the configuration system will take any of these strings and attempt to return a valid object. In v1.0 and v1.1, you will find that most of the objects returned by this call are only understand by the consumers of the configuration. Producers of the configuration (the folks that write the XML) have little hope of being able to make sense of most of the objects that are returned by calls to ConfigurationSettings.GetConfig(). ConfigurationSettings.GetConfig() returns something of type object. Unless you know what type of object to cast to, you have little hope of making sense of the object. In v1.0 and 1.1, that consumer was a runtime thing. The consumer knows what to cast the object to and how to use it.

ConfigurationSettings.GetConfig() looks for xml based on the path passed in via the sectionName argument. In a typical EXE, this search occurs in two files:

  1. machine.config
  2. [appname].exe.config

For a web application, the search happens in two or more files:

  1. machine.config
  2. web.config (in app v-root)
  3. Repeat #2 until you’ve descended roots to the directory the page is hosted in.

Web applications have another interesting wrinkle called location tags. You can find some information about location tags here. A full discussion on this topic is out of scope for this blog entry.

As each of these files is read, the XmlNode at the particular sectionPath location is searched for. When that XmlNode is located, the XmlNode is handed off to the type identified in the section tag for further parsing and validation. Example:

Machine.config has this XML:

<configuration>

    <configSettings>

        <section name="sectionOne"

            type="MyNamespace.SectionOne, MyAssembly,..."/>

    </configSettings>

   

    <sectionOne someTimeSpan="00:30:00"

        someString="Hello, World!" someBool="false"/>

</configuration>

MyApp.Exe.Config has this XML:

<configuration>

    <sectionOne someString="Hello, Application!"/>

</configuration>

The code that consumes the sectionOne section will see the following set of values, assuming that the type picked as a handler merges the sectionOne values in a “typical” fashion:

  • someTimeSpan: 00:30:00
  • someString: Hello, Application!
  • someBool: false

This particular mechanism works just fine for applications consuming the XML. For folks that need to automate the updates to configuration, only one option really existed: load the configuration files into XmlDocument and make your edits against that document. Everyone else edited by hand. Frankly, it’s pretty hard to remember everything that can possibly be set in a particular sectionGroup or section.

Other fun facts about ConfigurationSettings:

  • Values requested through GetConfig() are read from file on the first request and cached for subsequent requests.
  • There is one GetConfig() cache per AppDomain. New AppDomains have to go hit the configuration files anew.
  • Values are cached based on the string passed into GetConfig(). In the first example in this article, the cache would hold, at most, three items.

System.Configuration.Configuration

In Whidbey, a new set of objects was added to System.Configuration. What follows is a list that is exhaustive enough for this discussion:

  • Configuration: Used to load and save configuration files. Machine and Web-based configuration can be edited remotely.
  • ConfigurationSectionGroup: This particular type is only instantiated when called through the Configuration object.
  • ConfigurationSection: This type parses sections and is sometimes the return base type from a call to ConfigurationSettings.GetConfig().
  • ConfigurationElement: Whenever the ConfigurationSection contains sub-elements, this class helps out. ConfigurationElement is also the parent to ConfigurationSection.
  • ConfigurationElementCollection: Used for repeating elements used in collections.
  • ConfigurationProperty: Contains meta-data about the parseable entity. A parseable entity is an XML element or attribute. The metadata includes the following information: element/attribute name, data type, default value, and an indication if the property is required or not. If the property type is a collection, the indicator can also state how to serialize/deserialize the collection.

The Configuration object has the following static methods to load configuration in read/write mode:

  • GetMachineConfiguration() + two overloads: Loads machine.config.
  • GetExeConfiguration(string exePath, ConfigurationUserLevel userLevel): Loads the configuration for a particular EXE. The configuration is either for the EXE or the configuration for the user including the roaming and local settings.
  • GetWebConfiguration(string path) + three overloads: Loads web.config at the specified location.

Each of these three calls returns a Configuration instance. These instances do not share a cache. Each Configuration instance reads configuration independent of the others. These instances stand alone. These instances DO represent the merged view of config (machine.configàapp.config or machine.configàweb.configàweb.config…àweb.config).(Sorry for belaboring the point, but I’ve seen much confusion when I fail to belabor this particular point.) The Configuration instance has two properties that you will be interested in:

    1. SectionGroups: A collection of all the recognized sectionGroups at the scope this particular instance was loaded at.
    2. Sections: A collection of all the recognized sections at the scope this particular instance was loaded at.

SectionGroup has two identical properties. Both of these collections have array indexes with string and integer arguments that return objects. Authors of the sections and sectionGroups are expected to provide a static function that takes a Configuration instance and returns a strongly typed instance of the section or sectionGroup. This is only suggested for sections or sectionGroups that are child elements of the <configuration> element. Example:

public class SectionOne : ConfigurationSection

{

    static public SectionOne(Configuration config)

    {

        return (SectionOne)config.Sections["sectionOne"];

    }

 

    // Getters and setters for properties omitted

}

As the user gets the various sections, changes values, and so on, the underlying code tracks those changes and figures out what it needs to write to the active file. These edits can include the following things:

  • Edits to existing sections.
  • Addition and/or removal of sections and sectionGroups.

The only file that Configuration will ever write to is the file specified by the call to the static Configuration.GetXXX method. Eventually, the user will call the instance method Configuration.Update(). At this point, the changes to configuration are written out. These changes will not be visible to the consumer of configuration until an AppDomain that has never asked for the settings before is created and makes the request.

What’s the difference between these two classes?

ConfigurationSettings is used by the end-consumers of configuration to get configuration from the AppDomain-wide cache. Configuration is used by administrators, setup code, and configuration editors to read and write config for applications and the machine. When you use the Configuration class, you can expect that the type returned by calling Configuration::Sections[] or Configuration::SectionGroups[] is the same as the type indicated in the configuration file.

Exception: The type will not be the same if the type does not inherit from ConfigurationSection and instead implements IConfigurationSectionHandler.

When you call ConfigurationSettings.GetConfig(), you may get back the same type as defined in the configuration file. This is not a guarantee. ConfigurationSection contains a virtual function named GetRuntimeObject(). GetRuntimeObject() allows the author of the ConfigurationSection to store a different representation of the data for consumption by the code that uses the particular set of configuration settings to set behavior or do work.

Summary

This entry is a summary of what exists in configuration. It attempts to delineate the differences between the runtime configuration class, ConfigurationSettings, and the administrative time class, Configuration. There are a lot of interesting things to talk about with respect to configuring applications using the new classes. This is just a foundation for those future entries.

By the way, if you are reading this and are wondering what has happened to any perceived eloquence or good writing that I maybe used to show in my MSDN writings, I have an explanation. I’ve typically worked with good editors at MSDN, Addison Wesley, and Prentice Hall. Here, I’m performing without a net. I’ll gladly fix areas that are poorly worded though J

Configuration is a breeze.
14 April 04 01:59 PM | ScottSeely | 17 Comments   

In the current Visual Studio .NET 2005, you’re going to find that a great thing has happened to configuration. Basically, the mechanism for creating, editing, and parsing configuration sections just got really easy. If this particular item snags a bit of interest, I’ll go as deep as I can in future posts. Here is a teaser to see if there is any real interest.          

Let’s say that I have a reason for configuration. The data I need to store happens to be the following:

  • A string
  • An integer
  • A TimeSpan (for timeouts?)

Let’s say that I want the serialized format to look like this:

<mySpecialSection someString=”value” someInteger=”9” timeout=”00:12:30”/>

Previously, I would have to write a bunch of code that parsed an XML stream and sorted the data into the right data members. Today, the code to read and write the above looks like this:

using System;

using System.Configuration;

using System.Reflection;

 

public class MySpecialSection : ConfigurationSection

{

    [ConfigurationProperty(MySpecialSection.configSomeString,

        DefaultValue = "default")]

    public string SomeString

    {

        get { return (string)base[MySpecialSection.configSomeString]; }

        set { base[MySpecialSection.configSomeString] = value; }

    }

 

    [ConfigurationProperty(MySpecialSection.configSomeInteger,

        DefaultValue = 1)]

    public int SomeInteger

    {

        get { return (int)base[MySpecialSection.configSomeInteger]; }

        set { base[MySpecialSection.configSomeInteger] = value; }

    }

 

    [ConfigurationProperty(MySpecialSection.configTimeout)]

    public TimeSpan Timeout

    {

        get { return (TimeSpan)base[MySpecialSection.configTimeout]; }

        set { base[MySpecialSection.configTimeout] = value; }

    }

 

    const string configSomeString = "someString";

    const string configSomeInteger = "someInteger";

    const string configTimeout = "timeout";

}

Then, to write out the configuration AND make sure that this section was included in the right configuration file, you would have this:

public class App

{

      static public void Main(string[] args)

      {

        Configuration config = Configuration.GetExeConfiguration(

           Assembly.GetExecutingAssembly().Location,

           ConfigurationUserLevel.None);

 

        //Load my section from config

        MySpecialSection section = config.Sections["mySpecialSection"]

            as MySpecialSection;

        if (section == null)

        {

            // The section wasn't found, so add it.

            section = new MySpecialSection();

            section.RequireDeclaration(true);

            config.Sections.Add("mySpecialSection", section);

        }

        section.Timeout = TimeSpan.FromMinutes(4);

        section.SomeInteger = 15;

        section.SomeString = "Hello!";

 

        // Save the changes.

        config.Update();

    }

}

The output of the above is:

<?xml version="1.0" encoding="utf-8"?>

<configuration>

    <configSections>

        <section name="mySpecialSection" type="MySpecialSection, Test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" />

    </configSections>

    <mySpecialSection someString="Hello!" someInteger="15"

        timeout="00:04:00" />

 </configuration>

Not bad! I don’t know how you are configuring your applications today, but this particular model is nice. This particular OM has a few other benefits as well. For example, calls to ConfigurationSettings.GetConfig always succeed for configuration sections that are implemented by a ConfigurationSection-derived class. No more checking for null and filling in your defaults from some other area. Instead, you set the default values in your ConfigurationSection.

Why have the default values in the ConfigurationSection? Doing so provides the following benefits:

  1. If the user is happy with the default value, this is what you read back.
  2. If the user sets the setting to the default value, the configuration system writes out nothing. It’s also faster to read back the default setting since it takes zero time to read nothing.

I’ve been using this framework to develop a lot of configuration code for Indigo, System.Net, and System.Transactions. If you have stayed away from config up until now, give this stuff another look. You’ll be pretty happy!

By the way, at runtime when your application is reading the settings you would still load the settings using ConfigurationSettings.GetConfig(”mySpecialSection”).

April 1 WebService proposals
02 April 04 02:22 PM | ScottSeely | 0 Comments   

I was just going through last night's lower priority e-mail and saw the following from the DevelopMentor SOAP mailing list. In the tradition of the April 1 RFCs, here are some for Web Services (and if someone could post a link to the April 1, 2004 prank RFC, I'd appreciate it:) ):

[Followup, the RFC is http://ietf.org/rfc/rfc3751.txt?number=3751)

 

Web Services Performance (WS-Performance [1]) provides policy assertions that can be used to describe Web service performance characteristics and in particular provides set of metrics for already existing Web Services specifications. One of the most important concerns when composing Web Services is impact on performance of each specification. Therefore if there could be a synthetic indicator of performance impact of each specification it could help to automate estimation of composed Web Services performance and that is the role of WS-Performance to provide framework for such estimations.

This specification composes especially well with WS-Goodness [2] to provide Web services that are both good and of reliable performance and although currently may be a bit slow (as all Web Services ...) but WS-Performance helps to estimate how fast (or slow) they are!

For details see:

[1] http://www.extreme.indiana.edu/xgws/specs/wsp/

[2] http://www.extreme.indiana.edu/xgws/specs/wsg/ws-goodness.html

Thanks,

Aleksander Slominski

--

The best way to predict the future is to invent it - Alan Kay

 

 

Search

This Blog

Tags

No tags have been created or used yet.

Syndication

Page view tracker