DCSIMG
February 2011 - Posts - Pavel's Blog
Sign in | Join | Help

Pavel's Blog

Pavel is a software guy that is interested in almost everything
software related... way too much for too little time

February 2011 - Posts

COM Fun with Microsoft Agent

Published at Feb 25 2011, 03:44 PM by pavely

Whenever I teach COM interoperability in .NET, I try to show some nice demo for this. The classic is to use one of the Office applications (such as Word) to do some automation by creating a document, adding some text, etc. This is effective enough but not really fun.

A much more fun way is to use the Microsoft Agent technology. MS Agent is discontinued as far as further development is concerned, but it’s still fun and great for (at least) learning purposes.

What is MS Agent? Its most well known appearance (pun intended) was in the Office 2000 product suite, featuring the (in)famous “Clippy” that offered advise and allowed a somewhat “human” interaction with the application. Some users were fed up with Clippy and turned it off for good. Still, as a technology, it has its strong points. Other users swapped Clippy for another avatar, such as Merlin or Robbie.

Although MS Agent is now deprecated, and does not come preinstalled with Windows Vista and later, it can still be installed explicitly from the MS agent home page.

After installation, the required MS Agent COM DLL is AgentObjects.Dll and is located by default in the %SystemRoot%\msagent folder. Any characters you install appear in the Chars subdirectory (files with the ACS extension). Here’s how the Add Reference Dialog looks like:

image

One caveat to watch for is that MS Agent is 32 bit only, so any .NET project must be changed from “Any CPU” to “x86” (critical for 64 bit systems).

Initializing the MS agent server and loading a character can be done like so:

Agent _main;

IAgentCtlCharacterEx _merlin;

 

_main = new Agent();

_main.Connected = true;

_main.Characters.Load("merlin", "merlin.acs");

_merlin = _main.Characters["merlin"];

_merlin.Show(false);

_merlin.Play("Greet");

 

I’ve attached a sample project that demonstrates some of MS agent capabilities. It can also use a text to speech engine (must be SAPI 4.0 compliant) and even understand user speech.

Have fun!

Dealing With Native DLLs in .NET “AnyCPU” Builds

Published at Feb 13 2011, 09:27 PM by pavely

A .NET application can be compiled using the “AnyCPU” configuration, meaning the application runs as 32 bit on a 32 bit OS, and 64 on a 64 bit OS. As long as the application is purely managed, everything should be just fine.

However, if the application must use some native DLL through interop (e.g. P/Invoke), then “AnyCPU” may be an issue. A native DLL cannot be both 32 and 64 bit – it’s one or the other.

The traditional solution to the problem is to switch the .NET build to a “Win32” or “x64” configuration, thus aligning it with the “bitness” of the native DLL. But suppose I have two versions of the native DLL, can I use the correct one when doing interop so that “AnyCPU” just works as expected?

The answer is yes. Here’s one relatively convenient way to do it. Suppose I want to P/invoke to a function named foo() in some DLL with both 32 and 64 bit versions (named e.g. mynative32.Dll and mynative64.dll). Here’s some code that can make the interop seamless:

[DllImport("mynative32.dll", EntryPoint = "foo")]

private extern static void foo32();

 

[DllImport("mynative64.dll", EntryPoint = "foo")]

private extern static void foo64();

 

public static void foo() {

   if(Environment.Is64BitProcess)

      foo64();

   else

      foo32();

}

 

The actual inetrop methods are separated, accessing the proper DLL and name corrected using the EntryPoint property. Note they are marked private, so they are not callable directly.

The “actual” method checks the Environment.Is64BitProcess property, indicating whether we’re running in a 64 bit process or not, allowing the correct function to be invoked. The caller does not know (nor cares) that this is actually happening behind the scenes.

Interestingly enough, the Environment.Is64BitProcess property was introduced in .NET 4. If you’re running in a prior .NET version, the check is a bit more complex and might look something like this:

public static class ProcessHelper {

   [StructLayout(LayoutKind.Sequential)]

   internal struct SYSTEM_INFO {

      public ushort processorArchitecture;

      ushort reserved;

      public uint pageSize;

      public IntPtr minimumApplicationAddress;

      public IntPtr maximumApplicationAddress;

      public IntPtr activeProcessorMask;

      public uint numberOfProcessors;

      public uint processorType;

      public uint allocationGranularity;

      public ushort processorLevel;

      public ushort processorRevision;

   }

 

   [DllImport("kernel32.dll")]

   internal static extern void GetNativeSystemInfo(ref SYSTEM_INFO si);

 

   [DllImport("kernel32.dll")]

   internal static extern bool IsWow64Process(IntPtr handle, out bool result);

 

   [DllImport("kernel32.dll")]

   internal static extern IntPtr GetCurrentProcess();

 

   public static bool Is64BitProcess {

      get {

         SYSTEM_INFO si = new SYSTEM_INFO();

         GetNativeSystemInfo(ref si);

         if(si.processorArchitecture == 0)   // zero meaning x86 (check the docs)

            return false;

         // 64 bit OS, is it a 64 bit process?

         bool result;

         if(!IsWow64Process(GetCurrentProcess(), out result))

            throw new InvalidOperationException();

         return !result;

      }

   }

 

}

 

Now we can use the ProcessHelper.Is64BitProcess in .NET versions prior to 4 (of course it works for .NET 4 as well):

public static void foo() {

   if(ProcessHelper.Is64BitProcess)

      foo64();

   else

      foo32();

}

Enjoy!

ASP.NET MVC: History Repeating?

Published at Feb 09 2011, 10:52 AM by pavely

In the early days of the web, all we had is HTML, and that was fine for a while.

Then, we wanted something more “dynamic” or personal, so a bunch of sever side technologies were created (ISAPI, CGI, …) and then (in the Microsoft world) there was ASP, now sometimes referred to as “Classic ASP”. ASP was a mix of HTML and VBScript, later to be fondly named “spaghetti code” because of the intertwining of markup and code with a bunch of <% %> symbols and other variants.

When ASP.NET came out, one of its selling points was (apart from being based on a new framework – .NET) that you don’t need to know or write HTML – you have server controls, which do the actual rendering behind the scenes. Great!

Fast forward a few years…

Now, with ASP.NET MVC there is a new (preferred) view engine to use, named “Razor”, and one of its selling points is that you use plain HTML! No server side controls that render a bunch of unexpected HTML, ViewState and other nasties. Suddenly web developers like HTML, and want to use it as plainly as possible without server controls obscuring anything. And you can mix that HTML with code (now CSHTML). That code looks better, for sure… but hey – aren’t we back to the way classic ASP was written?

Maybe it’s just me, but this is irony if I ever saw one!

C++ 0x, Will you save C++?

Published at Feb 05 2011, 08:20 PM by pavely

The emerging new standard of C++ (dubbed C++0X, where X was supposed to be a decimal digit, but now can be considered a hexadecimal digit) will probably be finalized and approved this year (probably to become “C++11”), and is supposed to march C++ into a new era of productivity. Will that actually happen?

In recent years, I saw declining usage of C++ in “regular”, data driven applications, UI and graphic applications, in lie of other environments, namely .NET and Java. As I do a lot of training, the number of C++ or advanced C++ classes I’ve taught has dropped dramatically, from at least once a month of C++/advanced C++/COM/DCOM fully booked class about 8 years ago, to about a single(!) C++/advanced C++ class a year! C++ has largely been replaced by .NET and Java. Although this observation is somewhat personal, this is also evident in my consulting jobs – most of them in the .NET arena (in the Microsoft world) as opposed to the native C++ world.

Bjarne Stroustrup , the inventor and original implementer of C++ states in one lecture he’d given on C++ 0x, that one consideration in developing the new standard is to make it easier on beginners to get a good grasp of C++. Unfortunately, I find it to be quite the opposite. C++ is complex as it is, adding more intricate features cannot simply make it easier. Although features like auto, enum class, “for each” and nullptr should make things easier, or at least, more understandable, other features will make things harder, especially for those coming from a C background. Features, such as lambda functions, rvalue references, decltype and variadic templates (to name a few) will make it harder for beginners to step into C++ – they will go for C#/.NET or Java unless they really have no choice. And I would have to agree with them - C++ has some complex features in the pre-C++ 0X standard – and it’s going to get worse.

The last C++ standard came out in 1998 (with slight unimportant modifications in 2003). That’s more than 12 years - almost an eternity in “computer time”. C++ simply fell behind. And the language itself is not the only issue. A more important issue is the standard library.

Once upon a time, C++’s standard library seemed well and good, made clever use of templates and seemed rich enough. Today it’s not even close to what other platforms offer. For example, C++ has no threading support, no database access support and no XML support. Some would say database support is too specific, and should not really be in a standard library. What about the other two examples? Sure, there are many libraries out there that give all that and more (most notably the boost libraries), but this should really be a core of the languages support libraries. The new C++0x standard makes up for much of those, adding support for threading, for instance.

What’s important in a language, really?

A computer language is not just a sum of the keywords and some syntactic rules; the other part is its accompanying libraries – they are the first key to productivity. But is that all? I believe that a third factor has emerged in recent years, becoming more important than even the standard libraries – tools.

To be productive you need tools. Sure, you can create any program using Notepad or (heaven forbid – vi), run command line compilation, build ridiculously unreadable makefiles (that only you and the compiler can decipher), but it’s not going to be productive for most programmers. You’ll need some more tools such as a debugger. For a language to be successful, it must have good tools, and productivity is everything.

In the Microsoft world (of which I’m part as a Visual C++ MVP at least), the main work tool is Visual Studio, which continues to grow in features, most of them geared towards .NET developers. I must admit, when I start a new project, I use .NET/C# unless there is a compelling reason to use C++ (such as writing a device driver or doing low level Win32 work). I am not “ashamed” of this, even though I’ve used C++ for the most part of my professional life – .NET is simply more productive. Using C# is a pleasure, because of tooling support and the language itself. Advanced C++ programmers sometimes take pride in devising clever template meta-programming code, but I see this as an exercise in cleverness, not in productivity.

Where is C++ going?

The next statement may be harsh, but I think C++ is destined to become a niche language, good for Real Time code, device drivers, and the like. There’s simply no good reason (in the long run) to continue to use it for “standard” applications with UI, databases, graphics and the like. Mobile platforms don’t use (for the most part). It simply provides no real advantage. The .NET and Java libraries are huge and cover almost everything one may need, the tools are pretty good and getting better, and the safety features of C#/Java is a must. In C# you cannot corrupt memory, you cannot leak memory (at least not in the long run) – unless you use “unsafe” code or native code. In a pure managed environment you cannot do real damage. I think this is not a luxury, but a requirement for good quality code. I’m not saying it’s not possible to create quality code using C++ – I’m just saying it’s more difficult, as the programmer needs to take more things into consideration and worry about things like low level memory management. If you’re thinking COM (in Microsoft’s world), with its reference counting strategy, or things like shared_ptr<>, etc., they both have issues (e.g. cyclic references), and in any case they are not the “default”, so require a conscious effort to use.

In today’s powerful hardware some things should be moved to the platform level. Just as most programmers don’t use assembly language on a day to day basis – although a good assembly programmer can create faster code than the best compiler – it’s taken for granted that the benefits of a high level language are more important that squeezing a few more machine cycles. I believe this is the same in relation to native/managed code. The benefits of managed code outweigh the performance and memory footprint penalties that are inherent in such environments, and these penalties will be reduced with time, with better compilers and better hardware, just as it did with C/C++ vs. assembly.

What about kernel code?

An area where C/C++ is currently dominant is in an OS kernel. Whether it’s Windows, Mac or Linux, the kernel is written mostly in C (with some C++ and some assembly). It seems this this area will continue to be dominated by C/C++. But does it have to?

I’ve written some device drivers in the past, and it’s a pain. Granted, some people really love it, but even they can’t claim it’s easy. And any exception is brutally unforgiving, giving (on Windows) the infamous Blue Screen Of Death (BSOD). the BSOD is not a Microsoft directed punishment, as some naturally assume, but a mechanism to save Windows from not booting again. If a kernel code would be allowed to continue running, critical files may be damaged or parts of the registry corrupted, so the safest route is to stop everything. This means driver writers need to be extra careful, as they can cause a system crash, not just crash a specific process. Microsoft mandates various tests for drivers to ensure stability and quality, making it even harder on drivers writers. But does it really have to be that hard?

The Singularity project from Microsoft Research is an interesting attempt to create an operating system in managed code. Imagine: you write drivers in C#! You get all the safety and comfort of a managed environment within the kernel! Although there are naturally issues to resolve, I believe this is the way of the future. There’s really no good reason not to write most of an OS kernel in a managed environment, be it .NET, Java or whatever.

Conclusion

C++ is still pretty widely used in the game industry, for example. It was always a given that games need top performance, squeezing every once from the platform. The existence of libraries such as Microsoft’s XNA (and other managed game engines), that can be used to produce respectable games on the PC and even XBox 360 prove that you don’t really have to use a native language. In a world where video card’s GPUs are key and multi core is everywhere - not every single machine cycle has to count.

Managed environments are the way of the future (and the present). It’s a bit sad that noble languages like C++ suffer as a result, but that’s more a nostalgic vision than anything else. Sometimes we simply must let go, even when it’s painful.

That’s my two cents.