Wednesday, August 24, 2005

Funny stuff... Escape from Yesterworld

Microsoft published the Escape from Yesterworld site to promote 2005 development tools. It contains some funny parody videos on the first page (Main Control Room). Only four more months and 2005 will be Yester-year. Microsoft had better start shipping fast. Enjoy!

I found it interesting that MS used Flash to make the site. Didn't MS make that fancy IE browser to deliver rich content? Also, using IE the pop-ups to show the movies would not appear. When I clicked on the controls to show the movies, IE would just make a weak "beep" sound (maybe that was flash.) IE did not provide an error, neither did the yellow bar appear to enable the popup. So with IE, I couldn't easily view the movies! Good old Firefox worked just fine. (Who made this site?)

Monday, August 22, 2005

How to Create and Change Environment Variables using C# or .Net

Modifying environment variables seems like one of those easy tasks that you would expect .Net to support. Unfortunatley the System.Environment class only supports reading environment variables. So an alternative solution is needed. After a long search on the internet, I found one site that describes some options: Environment variable is handled. Unfortunately, this page is written in Japanese. An english translation is here. There are several options available, each with it's own limitations and issues. I tried each option and found they wouldn't work for me.

Windows Management Instrumentation (WMI) has the ability to easily read the environment. If an environment variable already exists, you can modify it using WMI. However, I could not find a good example of creating a new environment variable through WMI. I installed and ran Microsoft's WMI Tools (available here) to see if I could create an environment variable through the CIM Studio. No luck. There might be a way to use WMI to create a new environment variable, but I haven't seen it. Also, calling WMI causes a noticable performance hit on the first call.

Another solution is to modify the Registry (see MS KB Article) to create and modify environment variables. This seems to work, however the class Microsoft.Win32.RegistryKey doesn't provide the ability to create a REG_EXPAND_SZ value. Without REG_EXPAND_SZ, you can't use the %VAR% expansion! So using .Net framework falls short. (This is one example of my frustration with .Net, many framework interfaces are incomplete. Java never had this problem, instead Java tends to err on the side of giving you too much.)

The solution I found to work the best was to call Windows Scripting Host (WSH) Shell from .Net. This is described in Basic WSH Tasks: Manipulating the System Registry. I found an example of calling WSH from .Net in the article The Code Project - Creating Shell Links (Shortcuts) in .NET Programs Using WSH. Using WSH, it is easy to create and modify environment variables. Also, WSH allows you to set REG_EXPAND_SZ values. The final step after changing the environment variables in the registry is to broadcast the change by calling SendMessageTimeout as described in the KB article. I found this example calling SendMessageTimeout from C# on .Net 247.

So in short, here is the example code for creating and modifying environment variables from C#...

        public static void SetUserVariable( string name, string value, bool isRegExpandSz )
{
SetVariable( "HKEY_CURRENT_USER\\Environment\\" + name, value, isRegExpandSz );
}

public static void SetSystemVariable( string name, string value, bool isRegExpandSz )
{
SetVariable( "HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment\\" + name, value, isRegExpandSz );
}

private static void SetVariable( string fullpath, string value, bool isRegExpandSz )
{
object objValue = value;
object objType = (isRegExpandSz) ? "REG_EXPAND_SZ" : "REG_SZ";
WshShell shell = new WshShell();
shell.RegWrite( fullpath, ref objValue, ref objType );

int result;
SendMessageTimeout( (System.IntPtr)HWND_BROADCAST,
WM_SETTINGCHANGE,0,"Environment",SMTO_BLOCK | SMTO_ABORTIFHUNG |
SMTO_NOTIMEOUTIFNOTHUNG, 5000, out result);
}

[DllImport("user32.dll",
CharSet=CharSet.Auto, SetLastError=true)]
[return:MarshalAs(UnmanagedType.Bool)]
public static extern bool
SendMessageTimeout(
IntPtr hWnd,
int Msg,
int wParam,
string lParam,
int fuFlags,
int uTimeout,
out int lpdwResult
);

public const int HWND_BROADCAST = 0xffff;
public const int WM_SETTINGCHANGE = 0x001A;
public const int SMTO_NORMAL = 0x0000;
public const int SMTO_BLOCK = 0x0001;
public const int SMTO_ABORTIFHUNG = 0x0002;
public const int SMTO_NOTIMEOUTIFNOTHUNG = 0x0008;




Call either SetUserVariable or SetSystemVariable with the name and value. Set the boolean argument isRegEpandSz true if you need REG_EXPAND_SZ or false for REG_SZ type.

Thursday, August 11, 2005

TopCoder on Pair Programming

Shortly after blogging about pair-programming on TopCoder, the folks at TopCoder contacted me. They asked for more information about what we did while pair-programming. I gave them the details and tried to make a case for pair-programming in their Single Round Matches. The case I tried to make focused on the fun involved in pair-programming during their contest. Which for me was the whole reason to play TopCoder anyway. Pair-programming in the competition for me was a lot more fun than playing it by myself. Just like any sport, playing in pairs you build excitement and energy from your teammate. The added social-factor made the event very entertaining. Some of the discussions and comments we made while trying to hack code and race the clock would probably make a good reality-tv show. Pair-programming combined with the time-limit created a fun, social and exciting environment. This was simply FUN!

Unfortunately TopCoder's reply included...

Our current environment is setup to promote individual results and ratings. At this time, we dot not intend to add any type of pair programming or team competitions, but we'll consider your request. We've considered team contests in the past, but ultimately were hesitant due to the high potential for abuse.

If you like the pair programming experience within TopCoder, I encourage you attempt the same format but use the practice rooms instead of an SRM.
Ok, TopCoder has both technical and business issues to overcome before they can support team events. I'm sure if they really want to, they could find a way to support pair-programming. After all, don't they have access to the *Top Coders*? I hope TopCoder changes one day to allow team events. It really was a great form of Recreational Programming. Until then, Tom and I will look for other programming games to pair and play.