October 2004 Entries

Enumerating GAC Assemblies with IronPython

 

I haven't been able to play with IronPython for a while now, work has been rather busy and I have also just received a copy of Programming .NET Security from the folks at O'Reilly to read and review. So far I am rather impressed with the book. This morning when I woke up I decided to sit down and play around with IronPython again. I love the fact that I can simple write a script yet have the power of the .NET Framework available to me at the same time. With the following script we can enumerate all of the assemblies installed within the GAC (Global Assembly Cache).

 

from System import *
from System.IO import *
from System.Diagnostics import *
def EnumAssemblies(di):
dia = di.GetDirectories()
if dia != None:
for d in dia:
EnumAssemblies(d)
fia = d.GetFiles("*.dll")
if fia != None:
for file in fia:
version = FileVersionInfo.GetVersionInfo(file.FullName)
print String.Format("{0}, {1}", file.Name, version.FileVersion)
path = Environment.ExpandEnvironmentVariables("%WINDIR%")
path += "\\assembly\\gac"
di = DirectoryInfo(path)
EnumAssemblies(di)

Interesting Quote

 

I came across this quote that I thought is was rather interesting. It came from a speech titled “The Man in the Arena: Citizenship in a Republic” that Theodore Roosevelt gave at the Univeristy of Paris, Sorbonne in 1910. The following can be found in the 9th paragraph of his speech:

It is not the critic who counts, not the man who points out how the strong man stumbled, or where the doer of deeds could have done them better. The credit belongs to the man who is actually in the arena; whose face is marred by dust and sweat and blood; who strives valiantly; who errs and comes up short again and again; who knows the great enthusiasms, the great devotions, and spends himself in a worthy cause; who, at the best, knows in the end the triumph of high achievement; and who at the worst, at least fails while daring greatly, so that his place shall never be with those cold and timid souls who know neither victory nor defeat.

SQL Server 2005 Webcasts

 

Check out the new SQL Server 2005 webcasts. There will initially be a week of 15 webcasts. Here is the kicker; if you attend a webcast you will receive a copy of the Beta 2 Resource Kit, and a Beta 3 Resource Kit when it ships. If you are truly devoted (you better be), the first 1500 people to watch 5 or more webcasts will receive a limited edition SQL Server 2005 webcast t-shirt. If that wasn't enough (you want more?), all webcast viewers will be entered into a competition to win an XBox (so you can play Halo 2 of course!)

What kind of social software are you?

 

I found this link via Tosh Meston, apparently I am 3°. You can run through the simple test located here. I am not currently employed by Microsoft, but maybe this is a sign of my calling?

Windows Groups and Python

 

So because of my recent interests with IronPython, I decided I should learn Python to better understand everything. Python really appears to be a nice language (from the weekend that I spent with it). It feels slightly strange not using curly braces to scope methods though. Anyway, I wanted to come up with a nice example of how Python works within Windows to help me better understand the language. I was watching Crossing Jordan tonight with Megan when I though of the script I threw together on Friday at work and how it would be a great sample to test Python. After I downloaded the Python Win32 extensions, I was off and running. After a little fiddling, this is what I came up with, which is very close to my original script:

 

import win32com.client
shell = win32com.client.Dispatch("WScript.Shell")
strName = shell.ExpandEnvironmentStrings("%USERNAME%")
strDomain = shell.ExpandEnvironmentStrings("%USERDOMAIN%")
objUser = win32com.client.GetObject("WinNT://" + strDomain + "/" + strName)
strMsg = strName + " belongs to the following groups:\n\n"
for group in objUser.Groups():
strMsg += group.Name + "\n"
shell.Popup(strMsg)

Windows Groups and VBScript

 

Someone at work recently came up to me and asked if I would write up a quick VBScript file to display in a message box the list of Windows Groups a user is assigned to if the user ran it locally. This is what I came up with:

Dim WshShell, objDomain, objUserName, list, oGroup

Set WshShell = WScript.CreateObject("WScript.Shell")

objDomain = WshShell.ExpandEnvironmentStrings("%USERDOMAIN%")
objUserName = WshShell.ExpandEnvironmentStrings("%USERNAME%")

Set objUser = GetObject("WinNT://" & objDomain & "/" & objUserName & "")

On Error Resume Next
list = objUserName & " belongs to the following groups:" & vbCrLf & vbCrLf
For Each oGroup In objUser.Groups
list = list & vbCrLf & oGroup.Name
Next
Set WshShell = Nothing
MsgBox list

IronPython and Generics

 

So lately I have been going through the source in Jim Hugunin's release of IronPython. This has been a really great experience for me as programming language design has always peaked my interest. I just got to thinking as I went through some of his code, how could generics help out when writing this language. So for an example I took a look at the Slot class and just a random method from his CodeGen class. The Slot class looks something like this:

 

public abstract class Slot
{
public abstract void emitGet(CodeGen cg);
public abstract void emitGetAddr(CodeGen cg);

public virtual void emitSet(CodeGen cg, Slot val)
{
val.emitGet(cg);
emitSet(cg);
}

public virtual void emitSet(CodeGen cg)
{
Slot val = cg.getLocalTmp(typeof(object));
val.emitSet(cg);
emitSet(cg, val);
cg.freeLocalTmp(val);
}

public virtual void emitCheck(CodeGen cg)
{
if (Options.CHECK_UNINITIALIZED)
{
cg.ilg.Emit(OpCodes.Dup);
cg.emitCall(typeof(Ops), "CheckInitialized");
}
}

public virtual Type type
{
get
{
throw new NotImplementedException("type");
}
}
}

public class ModuleSlot : Slot
{
public readonly Type _type;

public ModuleSlot(Type type)
{
this._type = type;
}

public override void emitGet(CodeGen cg)
{
cg.emitModuleInstance();
}

public override void emitSet(CodeGen cg)
{
throw new NotSupportedException("setting a module slot");
}

public override void emitGetAddr(CodeGen cg)
{
throw new NotSupportedException("addr of a module slot");
}

public override Type type { get { return _type; } }
}

So obviously there are a series of other classes (i.e., ModuleSlot) that use Slot as their base class. The important part is within the CodeGen class. Jim uses a private ArrayList to maintain free slots. This is simply declaired as such:

 

private ArrayList freeSlots = new ArrayList();

and the CodeGen class has a method I selected at random that is implemented as such:

 

public Slot getLocalTmp(Type type)
{
for (int i=0; i < freeSlots.Count; i++)
{
Slot slot = (Slot)freeSlots[i];
if (slot.type == type)
{
freeSlots.RemoveAt(i);
return slot;
}
}
return new LocalSlot(ilg.DeclareLocal(type));
}

However, with generics, we could do the following:

private LinkedList<Slot> freeSlots = new LinkedList<Slot>();
//...

public Slot getLocalTmp(Type type)
{
LinkedList<Slot>.Enumerator en = freeSlots.GetEnumerator();
while(en.MoveNext())
{
Slot slot = en.Current;
if(slot.type == type)
{
freeSlots.Remove(en.Current);
return slot;
}
}
return new LocalSlot(ilg.DeclareLocal(type));
}

It will be interesting to see if generics gets added to IronPython as we get closer to a RTM version of generics.

Dilbert via RSS

 

How cool is this, if you are a Dilbert fan, you can now receive an RSS feed of the daily comic right to your RSS aggregator. Check it out here.

MSN Music

 

I've been playing around with MSN Music recently and after downloading about 8 songs I have to say I'm pretty impressed. Nothing too heavy duty to download (a little ActiveX control), this beats both Musicmatch and iTunes out of the water. The UI for Musicmatch is so slow I was forced to uninstall it after about 10 minutes of usage (painful comes to mind). iTunes has a slightly better response rate in terms of UI however I simply wasn't that impressed with their product. The fact that iTunes requires a 19.6 MB download is a little discouraging to begin with. The fact that I had difficulty finding some of the songs I was looking for didn't help matters either. If you haven't tried MSN Music I highly recommend you check it out, if even integrates well with .NET Passport.

Checking for a valid Internet connection

 

This is just my temporary solution as I have been busy doing other things at the moment.

#include "stdafx.h"

bool IsConnected();

LPCTSTR url = "http://www.google.com";
HINTERNET hINet, hResource;

int main(int argc, char* argv[])

    if(argc == 2)
    {
        if(strcmp(argv[1], "/?") == 0)
        {
            printf("Help (Input format):\n\n\"Http Application\" URL(optional)\n\n");
            return 0;
        }
        else
        {
            if(strstr(_strlwr(argv[1]), "http://") > 0)
                url = argv[1];
        }
    }

    HANDLE hWnd = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTitle(url);
    SetConsoleTextAttribute(hWnd, FOREGROUND_GREEN | FOREGROUND_INTENSITY);

    while(true)
    {
        if(IsConnected())
            printf("Connection exists.\n");
        else
            printf("Connection terminated.\n");
        Sleep(2000);
    }

    return 0;
}

bool IsConnected()
{
    bool bStatus = false;
 
    hINet = InternetOpen("Connection", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
    if(hINet == NULL)
        bStatus = false;

    hResource = InternetOpenUrl(hINet, url, NULL, 0, 
                        INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_PRAGMA_NOCACHE, 0);
    if(hResource != NULL)
    {
        char buffer[1024];
        DWORD dwRead = {0};
  
        if(InternetReadFile(hResource, buffer, sizeof(buffer)-1, &dwRead))
        {
            bStatus = true;
        }
        else
        {
            bStatus = false;
        }
    }
    else
    {
        bStatus = false;
    }

    if(hINet)
    {
        InternetCloseHandle(hINet);
        hINet = NULL;
    }
    if(hResource)
    {
        InternetCloseHandle(hResource); 
        hResource = NULL;
    }
    return bStatus;
}

 

Canonicalization Explained

 

Larry Osterman explains Canonicalization. Seems pretty clear to me.

Singleton remarks

 

There are many different ways to skin the Singleton cat, well; at least there are slight variations of it anyway. However the following way is more efficient than using volatile because of performance implications.

public sealed class Singleton
{
private Singleton(){}
private static Singleton value;
private static object syncRoot = new Object();

public static Singleton Instance
{
get
{
if(Singleton.value == null)
{
lock(syncRoot)
{
if(Singleton.value == null)
{
Singleton s = new Singleton();
System.Threading.Thread.MemoryBarrier();
Singleton.value = s;
}
}
}
return Singleton.value;
}
}
}