With Windows Forms 2.0 and a bit of ingenuity, you can easily make your application minimize to the system tray – that little area to the left of your clock. So let’s see how it’s done…


First stop – the NotifyIcon. The NotifyIcon is a new widget in Windows Forms 2.0, which displays a tray icon for your form. Simply drop a NotifyIcon on your form, set its Icon property to an .ico file of your choice, and set its Visible property to false. (I’m assuming that you want to either display the tray icon or your application, but not both.)


So far, so good. Now we want to find out when the form is minimized. We do this by finding out when the form is resized and examining its current WindowState, which we’ll do by overriding the OnResize method. (Overriding the OnXxx() methods is the preferred method for handling these types of Windows events if you’re creating a derived class since you don’t incur the overhead of a multicast delegate. If you want to capture these events from outside the form, use the appropriate event, such as Resize in our case.) If your WindowsState is minimized, display your tray icon and hide your form.


Now when we double-click our tray icon, we want to reverse the process by hiding the tray icon and displaying the form again. We do this by restoring the previous WindowState, but how do we know what the previous Window state was. We better keep track of it. Whenever a form is minimized, maximized, or restored, OnResize is called (and the Resize event is fired). So as long as the current WindowState isn’t minimized, we squirrel away the current value in a member variable. We then know what to restore the form to when the tray icon is double-clicked. There’s some additional logic in the constructor to set our restore state to a sane value when the application starts up.


That about wraps it up. You can download the sample code MinimizeToTray.zip (22.08 KB), though most is below for your viewing pleasure. Enjoy!

using System;
using System.Windows.Forms;

namespace JamesKovacs.Samples.MinimizeToTray {
public partial class Form1 : Form {
private FormWindowState m_previousWindowState;

public Form1() {
InitializeComponent();
// Store the initial window state that we want to restore to when we double-click the tray icon
m_previousWindowState = (this.WindowState == FormWindowState.Minimized ? FormWindowState.Normal : this.WindowState);
}

protected override void OnResize(EventArgs e) {
base.OnResize(e);
// We need to keep track of whether you’re minimizing from a normal or maximized window
if(this.WindowState != FormWindowState.Minimized) {
m_previousWindowState
= this.WindowState;
}
notifyIcon1.Visible
= (this.WindowState == FormWindowState.Minimized);
this.Visible = !notifyIcon1.Visible;
}

private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e) {
this.Visible = true;
notifyIcon1.Visible
= false;
this.WindowState = m_previousWindowState;
}
}
}

Continuing the series on life in a managed world, I promised you Developer Deathmatch. It was honestly more of a friendly challenge between Rico Mariani and Raymond Chen. This is only one application and your mileage will vary from application to application, but the main point here is to show that managed doesn’t necessarily mean slow. Now onto the main event…


Raymond wrote a series of articles about perf tuning an unmanaged application, a Chinese/English dictionary reader. Rico ported the same application to managed code and also perf tuned it. (Links to all of Rico’s and Raymond’s blog posts on the topic can be found here on Rico’s blog.) The results are staggering. Remember, both developers are at the top of their game. So this isn’t a naive unmanaged application versus a highly optimized managed application. Let’s look at the execution times:


































Version Execution Time
(seconds)
Unmanaged v1 1.328
Unmanaged v2 0.828
Unmanaged v3 0.343
Unmanaged v4 0.187
Unmanaged v5 With Bug 0.296
Unmanaged v5 Corrected 0.124
Unoptimized Managed port of v1    0.124
Optimized Managed port of v1 0.093
Unmanaged v6 0.062


It was only after Raymond pulled out all the stops with unmanaged v6 and wrote a custom allocator to replace the new operator that the unmanaged version surpassed Rico’s first try. This is not suggestive that Raymond is a poor coder – far from that – he’s probably one of the best.


In the end, Raymond won, but at what cost? It took six versions of the unmanaged code and who knows how much effort analyzing and tuning to beat the managed version. As for the managed version, at 0.093 seconds a large portion of the time is the startup overhead of the CLR. So you’re hitting a performance limit of managed code, but for most reasonable, and long-running, applications, ~50 milliseconds firing up your runtime at the beginning of application execution isn’t going to make a dent in your overall perf.


Why do people think that managed code is slow? One reason is that .NET makes it really easy to do colossally stupid things. Things like sucking 1 GB XML file off your hard disk and parsing it into an in-memory tree.


XmlDocument dom = new XmlDocument();
dom.Load(“someHonkingHugeFile.xml”);


Just because you can do this in two lines of code doesn’t absolve you of the fact that you need to understand what you’re doing. You need to understand your toolset. It is not the fault of the toolset designer if you use it improperly. Let me tell you that XmlDocument.Load isn’t going to be returning control to you anytime soon if someHonkingHugeFile.xml is 1 GB. I haven’t tried it, but you’ll probably throw an OutOfMemoryException on 32-bit Windows if you try something dumb like that.


Next time I’ll talk about some of my own personal experiences in developing performant managed applications.

This is the first in a series on life in the managed world. Originally it started as a single post and has been growing tentacles ever since. To tame the beast, I’ll only write about a few tentacles at a time…


The performance characteristics of managed code have been an interest of mine for a long time. I love writing C# code because it’s so much easier to write, maintain, and debug compared to unmanaged C++ code. But let’s be honest, if managed code doesn’t truly perform compared to C++, then you’re left with a nice prototyping language. Any serious work will still have to be done in C++.


So let’s start by looking at Microsoft’s use of managed code in its own products. This should be suggestive of whether it’s possible to write performant managed applications. (If anyone can do it, it should be the creators of the managed environment!) Dan Fernandez, Lead Product Manager of Visual Studio Express, released some interesting stats:



































Product Estimated Managed Code
Visual Studio 2005
7.50 million lines
SQL Server 2005
3.00 million lines
BizTalk Server
2.00 million lines
Visual Studio Team System
1.70 million lines
Windows Presentation Foundation
0.90 million lines
Windows Sharepoint Services
0.75 million lines
Expression Interactive Designer
0.25 million lines
Sharepoint Portal Server
0.20 million lines
Content Management Server
0.10 million lines

Take a closer look. Let’s look at the not-so-interesting ones first. WSS and SPS, though great products that both use .NET, are still very much unmanaged code bases at the core. (Read big C++ ISAPI filter that takes over IIS.) From what I’ve heard, this will be changing with WSS/SPS v3.0. (Bil, correct me if I’m wrong here.) Same goes for CMS, SQL Server, and VS 2005. Basically unmanaged applications/servers with .NET bolted on the side. Great for extensibility, but they really don’t tell us anything deep about the performance characteristics of managed code.


The interesting data points are BizTalk Server 2004, WPF, and Expression (aka Sparkle). These products are .NET from front-to-back.


BizTalk is a fantastic EAI tool and pivotal to Microsoft’s strategy in that space. Do you think Microsoft would “bet the farm” if .NET didn’t perform? They’ve got smart engineers. If managed code couldn’t perform up to its unmanaged counterpart, they’d write the core in unmanaged C++ and provide extensibility points by hosting the CLR. But they didn’t. They wrote the whole thing in .NET. That’s rather suggestive (though not conclusive) that managed code can perform well compared to C++.


Windows Presentation Foundation (WPF) is the new windowing framework that is set to replace Win32-style windows. We’re going from a bitmap/HWND-based windowing environment to a composable, vector-based windowing environment. At its core, it uses DirectX technology for drawing. Vista is getting a full UI facelift in the form of Aero, which is built on top of WPF. As developers, we love to hate our end users who buy apps based solely on visual appearance. The actual code can be a dog’s breakfast, but as long as it looks pretty, users will love it. So this is another huge bet for Microsoft. If WPF doesn’t perform, it will be immediately noticible by end users.


Expression (codename Sparkle) is a new design tool for graphic designers to develop WPF applications. Developers will still work in Visual Studio, but graphic designers will author XAML using Expression. (You didn’t expect Microsoft to force VS onto the artist community, did you?) The nice thing is that the XAML will roundtrip between VS and Expression. Like it or hate it, what will drive most users to upgrade to Vista is a prettier interface. If applications are going to have nice Vista-style visuals, Expression better be fast, easy, and intuitive for graphic designers. (Interesting tidbit. Expression only makes one P/Invoke call. Everything else is pure .NET. The one call? To show Help. The managed wrapper to the Help subsystem is in System.Windows.Forms and it was deemed silly to take a dependency on Windows Forms solely for this reason.)


Microsoft is making some pretty serious bets on managed code and is baking it more and more deeply into Windows and its server products. From experience, managed code is just plain easier. Forget the machismo about whether you’re man (or woman) enough to handle pointers and pointer arithmetic. Pointers have a time and a place. Sure, break out the C, C++, and even assembly language when it is warranted, but only when warranted. Most of the time you should be living in a managed world.


Next time I’ll look at Developer Deathmatch: Rico “Managed” Mariani vs. Raymond “Unmanaged” Chen.

As usual, I’ve been reading voraciously about all things .NET and here’s a selection of articles and blog posts that every developer should read in their copious amounts of spare time over the holidays.


Our first stop is security… Security for developers has long been near and dear to my heart. So it should come as no surprise that I’m a big fan of Keith Brown‘s work. His articles on security for developers are very insightful and his book, The .NET Developer’s Guide to Windows Security, should be on every developer’s bookshelf. Keith recently published an article in MSDN Magazine entitled Encrypting Without Secrets, where he lays out a foundation for encrypting data (such as credit card numbers) without placing the decryption keys on an internet-accessible server. He uses a technique very similar to SSL where he uses public/private key cryptography (RSA in his example) to encrypt a dynamically generated symmetric key (AES aka Rijndael, pronounced rain-doll). You keep the private (decryption) key on a secure server in your back office and the public (encryption) key on your web server. Even if the web and/or database server are compromised, the attacker doesn’t have the decryption key to make use of the encrypted credit cards numbers he (or she) just harvested. Very cool stuff.


Our next stop is SharePoint land… Bil Simser has a great blog post that discusses why you shouldn’t use your lightsabre to slice cheese. (Because it will melt the cheese, silly!) His point is that although SharePoint is a cool tool, you should use it for what it was designed for. Like any tool, it cannot be all things to all people. A good developer/architect knows his toolset and knows how to pick the right tool for the job. When all you’ve got in your toolbox is SharePoint, everything looks like a webpart. If this is you, learn a few more tools so you can pick the right one for the job.


Last stop is the world of ASP.NET… There are a wide variety of ways to redirect a user to a new web page and ASP.NET 2.0 adds some new tricks. Ting-hao Yang enumerates the options, including pros and cons of each technique, in this blog post. A very worthwhile read for anyone doing ASP.NET development, either 1.X or 2.0.

I present to you, my dear readers, this humble set of links that I’ve found helpful in my own learnings in the arcane (sometimes black) art of SharePoint development. Honestly I’ve had this list kicking around my desktop for a few months and have been meaning to blog about it. (I put them together for a course that I taught on SharePoint development and webparts awhile ago.) So hopefully you find them useful on your path to SharePoint greatness.


Let’s start with the basics on SPS architecture and webparts:




That’s fun, but is there a webpart template that you can use in Visual Studio 2003? I’m glad you asked:

That’s all great, but I hear that you can connect web parts together and do other funky things. Where can I get a more detailed discussion on creating advanced web parts?


What if my webpart needs some external resources like an image or client-side script. Where do I put it? And what’s the difference between wpresources and _wpresources anyway?


OK, all this webpart stuff is really cool, but I’m feeling lazy. How can I drag and drop my way to a webpart like I do with ASP.NET User Controls?


But I want to code a really cool webpart that might not be granted sufficient permissions by CAS. What should I do?



Now that I’ve finished developing my webpart, how can I easily install it on a production server?


I’ve got a bunch of content that I want to move from one server to another. Do I have to code up some gnarly T-SQL to make it happen? No, just learn your way around stsadm.exe and smigrate.exe:



I still need more information. Where should I start looking?


For all things SharePoint, don’t forget to subscribe to Bil “SPS God” Simser’s blog.

 

And what, you might ask, does this have to do with System.Web.UI.WebControls.WebParts in ASP.NET 2.0? Not much, but that’s a post for another day…

If you’re running as a non-admin (which you know you should be), you are used to Right click… Run as… if you need to execute an application that needs admin privileges. This is easy and good. This even works for installers that are packaged as EXE. The pain is when you want to install a MSI package. Right click… and there is no Run as… option. So you do what I do, which is launch a command prompt as an admin user, browse to the directory containing the MSI package, and then execute from the command line. Or if you’re Michael Willers, you hack the registry and add an Install as… option. Doh! Why hadn’t I thought of that? Great idea, Michael. His steps are reproduced below:



  1. Run regedit.exe under an account with administrative privileges
  2. Create the key HKEY_CLASSES_ROOT\Msi.Package\shell\runas\
  3. Set the default value to Install &as…
  4. Create the key HKEY_CLASSES_ROOT\Msi.Package\shell\runas\command\
  5. Set the default value to msiexec /i “%1”

Michael’s link to the reg file isn’t working so I’ve duplicated it here.

If you’re a developer like me, you can appreciate an aesthetically pleasing website, but couldn’t create one if your life depended on it. Oh sure, I can sling HTML, DHTML, CSS, and JavaScript with the best of them, but I’m an implementer, not a graphic artist. So what to do if you’re too cheap to hire a graphic artist (or too lazy to deal with cross-browser compatilibity)? Microsoft has released a series of pre-built templates with some nifty features for ASP.NET 2.0. A wide variety of ASP.NET 2.0 features are used in the templates, ranging from Master Pages to Profiles to Themes to new ASP.NET controls. So go check out the ASP.NET 2.0 Design Templates.

No, I’m not confused. Read on and all shall become clear…


Since the dawn of time*, the conditional-expression operator, ?:, has confused C-language newbies for generations. Not to be outdone, C# 2.0 has introduced the ?? operator. This is a little known addition to the C# language that has an interesting use – besides confusing VB developers, that is. Consider the following code:


if(title != null) {
   return title;
} else {
   return string.Empty;
}


Basically you want to return a default value if your reference is null. If your type happens to be a string, this could be a shared instance (such as string.Empty) or “Default Value” or something else. Other reference types (or Nullables) could do something else.


This isn’t hard code, but it is a fair amount of typing. So many would shorten it to:


return (title != null) ? title : string.Empty;


Checking for null returns is fairly common, especially in database work or when reading from config files. So C# 2.0 introduced the ?? operator:


return title ?? string.Empty;


This does exactly the same thing as the previous two examples, just with less typing. Another interesting use is when working with Nullables:


int? x = ReadFromConfig();
// Do some work
int y = x ?? 42;


It will take awhile to get used to, but is an interesting addition to the C# toolbox.


* The dawn of time is roughly sometime in the early 1970s.

Alright, I’ll admit it. I’m probably the second to last VS developer to figure out how snippets really work. I’m writing this post in the hopes that the last developer finds this…

Code Snippets is a new feature in VS 2005. I’ve been using them via the somewhat laborious Right Click… Insert Code Snippet… scroll to the appropriate snippet, double-click, and it’s inserted. Then you fill in some information. (For instance, if you insert a “for” snippet, you provide the name of the iteration variable and the length by tabbing between the fields. Press Enter and you jump to the insertion point in the loop where you can start coding.) You can put this to great use both for repetitive coding tasks like properties, events, etc. as well as during demos. (For everyone who does technical presentations, I can read faster than you can type – especially if you take into account the inevitable typos. I’d rather watch you debug through the code and explain it rather than watching you fumble your way through Intellisense.) The problem, especially for repetitive coding tasks, is the time it takes to go through the dance – Right-click… Insert Code Snippet… etc. Yes, there’s a keyboard shortcut (Ctrl-K, X), but it’s still time-consuming to find what you want in the list. Then, I noticed the “shortcut” defined for snippets. After some quick digging, I found this document that outlines the 5 different ways to insert code snippets. The best way, once you know the shortcut, is [shortcut]-TAB-TAB to insert the snippet. (i.e. for-TAB-TAB) This is fantastic for the snippets you use frequently.

I also like the simple format for snippets. You define variables for replacement by enclosing them in “$”. For example $classname$. If you repeat the same variable twice, it automatically updates when you change the first instance. You can also specify default values and prompt text. This means that it’s super simple to create your own snippets for common tasks. Roland Weigelt (creator of the AWESOME VS addin, GhostDoc) has crafted up code snippets for an NUnit test, events, properties, and debugger break. I created my own property snippet based on Roland’s for the way I prefer to define properties. The actual code for the read/write property is:

private $type$ m_$property$;

public $type$ $property$ {
  get { return m_$property$;}
  set { m_$property$ = value;}
}
$end$

It doesn’t take a proverbial rocket scientist to figure out how to code your own snippets.

Once you have your snippet created, simply drop it into %My Documents%\Visual Studio 2005\Code Snippets\Visual C#\My Code Snippets and it will immediately appear in VS 2005. You can also add new locations to search for code snippets via the Code Snippets Manager (Tools… Code Snippets Manager… or CTRL-K, CTRL-B.)

Code Snipets are a fantastic addition to make a developer’s life more productive. You’ll definitely be seeing me using code snippets in upcoming presentations. Although I’m a reasonably fast touch-typist, one’s ability to type varies inversely with the number of people wathcing.

I’ve been playing with SQL Server 2005 and like what I see so far. It’s especially nice for developers as everything now resides in VS 2005, whether you know it or not. (SQL Server Business Intelligence Development Studio and SQL Server Management Studio are really just the VS 2005 shell hosting the appropriate widgets.) One thing that I do miss from SQL Server 2000 is Service Manager for starting and stopping the various parts of SQL Server. (I don’t like to clutter my RAM with all the SQL Server bits when I’m not doing DB-related development.) You can start and stop SQL Server from the other tools, but I run as a non-admin and non-admins can’t start/stop services. (You could run SQL Server Management Studio as a local admin, but that’s rather heavyweight since all I want to do is start/stop the services.) The other option that I’ve been using is shelling out to an admin command prompt and typing “net start MsSqlServer” or “net stop MSSQL$SQLExpress” or similar.


Seems that Jasper Smith had the same problem and implemented a very nice Service Manager replacement called appropriately SQL 2005 Service Manager. It does everything the original did and a whole lot more that it should have. It supports all SQL Server 2000 and 2005 editions, including SQL Express instances. The list of services that you can manage includes SQL Server, SQL Agent, Analysis Services, Full Text Search, MSDTC, and Reporting Services. (My favourite is start/stopping Reporting Services, which the original never did.)


I even configured it to prompt for alternate credentials so I can run it as the local admin. (You can configure any shortcut to prompt you for credentials by Right-clicking the shortcut… Shortcut tab… Advanced… “Run with different credentials”.)


Very cool tool and highly recommended if you’re doing SQL Server 2005 development!