June 2004 - Posts

Visual C++ 2005 Beta

The Visual C++ 2005 (and of course Visual Studio) beta will be available to MSDN subscribers in a few days. Subscribe to the downloads feed to be notified of its availability.

If you just can't wait for that, you can get the new Visual C++ Express Edition beta right now.


© 2004 Kenny Kerr

Posted by KennyKerr with no comments

New Arrival

Our baby boy finally arrived this morning just before 10 am. Daniel James Kerr weighed in at nine pounds and nine ounces. Danny and his mom are healthy and doing well.

Despite his youth, Danny prefers Web services to other distributed application platforms (apologies to Don Box).


© 2004 Kenny Kerr

Posted by KennyKerr with no comments

.NET Reflector Support for Visual C++ 2005

Lutz Roeder has released a new build of the .NET Reflector that fixes some problems I ran into while trying to browse assemblies built with Visual C++ 2005.


© 2004 Kenny Kerr

Posted by KennyKerr with no comments

On Productivity and API Wars

Joel Spolsky recently posted another essay, this time ranting about Microsoft, platform shifts, runtimes, etc. I'm a big fan of Spolsky's and I strongly encourage anyone who is at all interested in software to read all his essays on software. He seems to be showing a bit more bitterness than usual these days though. One of the points he tries to make is that the reason developers are more productive with programming platforms like Visual Basic or the .NET Framework compared with traditional programming languages like C and C++ is because the former have automatic memory management.

Hmm... Well I'm certainly a big fan of the CLR's garbage collector. But I really don't think you can attribute the huge productivity gains that .NET developers experience purely to automatic memory management. In my mind the reason for the productivity boost comes from two factors. The first is the extensive .NET Framework class libraries and the second is the common type system.

Consider what a C# application would look like if not for the base class libraries. Sure, all the heap based variables will be automatically freed by the garbage collector at some point in the future which does simplify the programming model to a degree, but without good libraries you're still stuck talking directly to the operating system in the only language that operating systems ultimately speak - C. After all, what does the ever popular FileStream class from the .NET Framework do? Internally it calls the CreateFile, CloseHandle, ReadFile and WriteFile functions, the same functions you would call from C or C++ to read and write to a file. If you've ever had to do any amount of P/Invoke work in C# you probably realized that it's just a whole lot easier from native C++. So good libraries are a must. But these libraries can also be written in C++. In fact C++ is all about creating class libraries of reusable functionality. In fact I think this is an area where C++ will begin to shine even more with the introduction of Visual C++ 2005 and its first class support for writing managed code using the C++/CLI language design.

So what about automatic memory management? Well it depends what you mean by automatic. If you mean that memory allocated on the heap must be freed at some unpredictable time in the future then garbage collection will serve you well. But if what you really want is to not have to worry about freeing memory explicitly well then gosh, but C++ has had that since day one with destructors. Here is an example of allocating a simple buffer in C# and C++ with its size determined at runtime:

[C#]

byte[] buffer = new byte[size];

[C++]

std::vector<BYTE> buffer(size);

In the C# case, the GC will collect the memory when there is memory pressure and there are no longer any roots referring to the variable. In the C++ case the memory will be released in the vector instance's destructor that is called when the variable goes out of scope. The C++ code is not any harder to write than the C# code. Sure there are issues around resource ownership but there are well-established techniques for solving those problems. Reference counting is a great example that COM popularized in some circles. Andrei Alexandrescu also presents some great techniques that you can use to write more flexible and extensible libraries in Modern C++ Design. Brian Harry goes into a lot more detail on the topic of memory management and explains the path to garbage collection in the CLR. But the point is that C++ does provide memory management and with good libraries, the code is just as concise and developers can be almost as productive. The trouble of course is that there just isn't a single library near the scale of the .NET Framework for C++. There are lots of smaller libraries that focus on different things and often overlap. That leads me to the second reason for the productivity boost owned to .NET.

The common type system is an often overlooked aspect of the CLR and the .NET Framework yet it is critical to its success. Let's for a moment stroll down memory lane and consider the infamous string. If you know anything about programming it is that we use strings to allow programs to communicate with humans. C defined the simplest of string types:

char* pString;

pString is a stable pointer into the process' address space. Programs can read the string, character by character, using memory addresses and pointer arithmetic until they reach a character with a value of zero, referred to as the null-terminator. Of course there are many problems with this type of string such as determining who owns the memory, string manipulation woes, security problems, etc. The StrSafe.h header file goes a long way toward helping developers write more robust code using C strings.

The next string type is the C++ string. Huh? What string? Do you mean CString or perhaps std::string or perhaps you mean your favorite home-grown string class? I'm sure I could find a dozen different string classes in common use today. The problem of course is that C++ didn't originally provide a native string type. The official C++ string, std::basic_string, was only introduced much later.

Then of course along came object/component technology and the desire to build large applications out of individual components engineered by different vendors. These different components would be written in different languages, each with their own string types. How do they interoperate? COM didn't mandate any standard string type. It did however popularize the Visual Basic string, or BSTR. Using BSTRs from C++ meant using a wrapper class around functions like SysAllocString and SysFreeString. So component technology in the 90's suffered from type friction and guys like me who loved digging into things like COM marshalling and interception and understood how to build large component based systems made a good living.

Clearly if every programming language and platform used a consistent set of types, building components to interoperate would be significantly simpler. This goes beyond strings. Consider approaches to error handling. COM enforced a strict error handling protocol not natural to either C++ or Visual Basic. So providing a common type system and programming model are essential ingredients in making developers more productive by reducing the noise involved in using different libraries from different teams and vendors.

So we've talked about the importance of good libraries and the value of a common type system. Both of these are present in the .NET Framework. As developers we need to strive to write our own types in such a way that they work naturally with other libraries. Using common types like System.String goes along way. Another common type that pervades the .NET Framework is the System.IO.Stream class. If you have some resource that is naturally represented as a stream of bytes then you should consider implementing a Stream-derived class to extend this library pattern to your types.

I was originally going to blog about Stream implementations today but I got sidetracked and this felt like a good introduction to it anyway. Stay tuned. I have an interesting post coming up on better design for .NET.


© 2004 Kenny Kerr

 

Posted by KennyKerr with no comments

Exploring Installations and Security Identifiers

With a shared computer you can get into a situation where one user installed a program and a different user wants to uninstall it. The trouble is that the program may not be listed in Add or Remove Programs when the second user logs in. You need to log in as the original user to view the program as an installed program in the list. So how do you discover who originally installed the program so that you can chase them down?

Search the HKEY_USERS hive in the registry for the name of the product. Chances are you will find it in a location something like this:

HKEY_USERS\<SID>\Software\Microsoft\Installer\Products\<Id>

<SID> is the security identifier (SID) for the user that installed the program. The next step is to look up the SID to determine the friendly name of the account. A SID is made of a number of components:

S-R-I-S-S-...

The first S simply identifies the string as a SID. The R is the revision level which is almost always 1. I is the universal authority of which there are only a few such as the World (1) and NT (5) authorities. The remaining S components are relative identifiers identifying sub authorities and ultimately the relative identifier of the account.

For example S-1-5-20 refers to the Network Service account (SECURITY_NETWORK_SERVICE_RID) that belongs to the NT authority (SECURITY_NT_AUTHORITY). This is a well-known account and will have the same SID on all machines.

Windows provides the ConvertStringSidToSid function to convert a string-formatted SID into a binary SID structure. Once you have a pointer to a SID structure, you can use the LookupAccountSid function to look up the display name of the authority and principal defined by the SID. This function takes care of connecting to the required authority or domain controller to determine the account name.

To automate this process I wrote a simple tool that takes a SID string and displays the account information for it. You can download the source and binary for it here. Here is an example of its use:

C:\>LookupSid.exe S-1-5-20
LookupSid 1.0
Copyright (C) 2004 by Kenny Kerr
http://www.kennyandkarin.com/Kenny/

  Authority: NT AUTHORITY
  Principal: NETWORK SERVICE
       Type: Well-known group

There are probably a lot of tools out there that can do this. It's really not hard once you know how. Incidentally you can also use the SID strings defined for the security descriptor definition language (SDDL):

C:\>LookupSid.exe BA
LookupSid 1.0
Copyright (C) 2004 by Kenny Kerr
http://www.kennyandkarin.com/Kenny/

  Authority: BUILTIN
  Principal: Administrators
       Type: Alias

 


© 2004 Kenny Kerr

Posted by KennyKerr with no comments
Filed under:

Displaying .NET Framework Versions

In supporting or diagnosing .NET based products, I often find it useful to check what versions of the .NET Framework are installed on a given machine. Most programmers know by now how to do this by checking the registry or some file on disk. But when you’re on the phone to a customer you want a simple solution that does not involve them cranking open the registry. What you need is a simple, low-tech solution.

1. Open the Run dialog box by typing Win+R.

2. Type the following command:

cmd /k dir %windir%\microsoft.net\framework\v?.* /b

Admittedly this could also be error prone to communicate over the phone. I suggest you send the customer an email.

:)

On my machine, it results in the following displayed in a console window:

v1.0.3705
v1.1.4322
v2.0.40426
v2.0.40510


© 2004 Kenny Kerr

Posted by KennyKerr with no comments
More Posts