Tag Archive for CodeSnippets

Preventing Outlook from closing with Alt-F4

I have come to the realization, at some point, that I never want to close Outlook. Really, there's no reason for me to shut it down except when doing something special, like freeing every available byte of memory, or when developing add-ins to it. During day-to-day work, I always want it on and minimized. The problem is that there's no easy keyboard shortcut to minimize Outlook like there is to close it – I don't like the two-step shortcut of Alt+Space – n, and I don't want to define a new non-standard keyboard shortcut that I have to remember in addition to the standard Windows keys.

So instead, I've decided to go the route that RSSBandit and other programs did – intercept the Alt-F4 keypress, and minimize to the tray rather than closing. Whenever I do want to close Outlook, I can do it via the File->Exit option. It's rare enough not to bother me.
Writing this proved to be ridiculously easy when using VSTO 2005 SE and a library I had already developed a while ago to hook into the keyboard events.

The steps are simple:

1) Create the Outlook Add-in Project. I wrote this for Outlook 2007 – it should work the same for 2003:

2) Add a reference to the HookLibrary mentioned above.

3) Write the following code in the ThisAddin_Startup event:

private KeyboardHook altF4Hook;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
   altF4Hook = new HookLibrary.KeyboardHook();

   // false/true/false is for ctrl/alt/shift modifiers, respectively.
   altF4Hook.AddFilter(Keys.F4, false, true, false);
   altF4Hook.KeyPressed += new KeyboardHookEventHandler(altF4Hook_KeyPressed);
   altF4Hook.Install();
}

void altF4Hook_KeyPressed(object sender, KeyboardHookEventArgs e)
{
   Outlook.Explorer exp = Application.ActiveExplorer();
   exp.WindowState = Microsoft.Office.Interop.Outlook.OlWindowState.olMinimized;

}

 

And that's it. On our development machine it should automatically be installed in Outlook. For other machines, we can build the MSI file that's created for us and install it. I've attached the MSI here, as well as the full code. Enjoy.

Reflecting over an Event

A coworker (Hey, Evgeny!) came to me with a puzzler today. He has an object that exposes an event, and he wants to know whether he's already subscribed to that event.

Two things immediately came to mind – the first was that he really shouldn't be doing that, and the second was to suggest that if the reason for this is to avoid multiple registrations, he can always call -= and then += afterwards, thus making sure he's subscribed only once. Having established that, I got down to thinking about it.

I started checking out what reflection can do for me. I could easily get the EventInfo object for the event using:

myObj.GetType().GetEvent(“MyEvent”);

but that proved fruitless – I could get the Add and Remove MethodInfos, add a new handler and even get the delegate type for that event, but not the actual instance of the delegate. So I started thinking again.

An event in the .NET Framework is basically a wrapper around a multicast delegate. Just like a property can be a wrapper around a private data field. Rather than exposing the delegate directly, we expose a more limited subset of functionality (subscribe and unsubscribe) rather than allow my consumers to mess with my internal delegate list.

By that logic, it stands to reason that there should be an internal, private member holding the delegate itself. Probably having the same name as the event. A quick check confirmed that:

myObj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance):
{Dimensions:[1]}
[0]: {System.EventHandler`1[System.EventArgs] MyEvent}

Right. EventHandler is my delegate type (that ugly format is the internal representation of generic types) and MyEvent is the name of the event. Using this, it's a piece of cake to get the value of the field and cast it to the multicast delegate:

FieldInfo delegateField = myObj.GetType().GetField(“MyEvent”, BindingFlags.NonPublic | BindingFlags.Instance);
EventHandler del = delegateField.GetValue(myObj) as EventHandler;

And once we had that – it's a simple matter of iterating the invocation list and seeing whether I've registered already:

foreach (EventHandler handler in del.GetInvocationList())
{
    if (handler.Target == this)
        return true;
}.

Now, I'm not saying this is a good technique – it's better not to reach a point where I don't know if I've registered or not. But still, it's good to know.

I've attached the full code listing, which is more complete, has comments and a few checks so we don't crash. Enjoy.

UPDATE: This solution is all nice and well, but as Evgeny pointed out in the comments below, this doesn't work with COM Objects. In fact, Reflection as a whole seems to be very limited, always returning __COMObject as the reflected type. Anyone know how to get more information from the RCW?

Outlook Calendar as your Windows Desktop

In a Channel 9 conversation, user Dr. Herbie expressed his long-standing desire to see his Outlook calendar as a desktop wallpaper. This, I admit, has never once occured to me. The nice thing about it is that it's so amazingly simple to implement.

Ever since Windows 98 and the Active Desktop, you could use HTML as the desktop wallpaper and embed anything you want in it. For the last 4 versions at least, Outlook comes with an ActiveX control that lets you display the contents of any Outlook folder in your application. Mix the two – and you have an HTML page that embeds the Outlook View Control maximized to fullscreen, defaulting to today's date, and add two simple Javascript buttons to move back and forward in the days.

A less lazy developer can make this much nicer, with a monthly date-picker and less ugly buttons. Considered as as Proof of Concept, it works with some caveats:

1) Due to the whole Eolas/ActiveX lawsuit fiasco, you need to click on the desktop once to enable interaction with the ActiveX control.

2) You can click on desktop icons, but you can't drag them around (well, without dragging them into an appointment. :). This can be fixed by resizing the control to allow some free desktop space, I suppose.

 

3) This keeps an instance of Outlook permanently in memory. Probably isn't a problem, but good to know.

4) As it stands, the control will mirror the view current selected in your Outlook calendar.

Here's a screenshot of my desktop right now. Thanks for the idea, Herbie!

 

TO INSTALL:

Download the specified attachment (CalendarWallpaper.zip) and unzip into any convenient place. My Documents, for instance.

Then, Go to your desktop properties -> Desktop -> Browse and choose the unzipped file (CalendarWallpaper.htm). Et voila!

VSTO for Outlook 2007 – Building the Add-in (part 2)

Writing the Outlook add-in described in my previous post was composed of the following steps:

1) Creating the project

Ah, the wonders of VSTO. Saving us all the unnecessary hassle of adding COM references, implementing interfaces and working too hard. After installing VSTO 2005 SE we can create a new Outlook 2007 Add-in project that creates both the add-in project and the MSI Setup project that can be used to install it.

2) Building the Context Menu

To add my own menu items to each item's Context Menu, I use the new ItemContextMenuDisplay event that is exposed by the Outlook 2007 object model. In the pre-supplied Startup method I simply add the following event registration:

this.Application.ItemContextMenuDisplay += new Microsoft.Office.Interop.Outlook.ApplicationEvents_11_ItemContextMenuDisplayEventHandler(Application_ItemContextMenuDisplay);

In my event handler method I start by fetching the current Outlook folder:

MAPIFolder currentFolder = Application.ActiveExplorer().CurrentFolder;

and creating the root of the popup menu tree:

// Create a new button in the commandBar. The command bar itself is received as a parameter to the event
// handler  method.

CommandBarPopup rootButton = (CommandBarPopup)commandBar.Controls.Add
(Office.MsoControlType.msoControlPopup, Type.Missing, “MoveToFolder”, commandBar.Controls.Count + 1, Type.Missing);
 

rootButton.BeginGroup = true;
rootButton.Tag = “MoveToSubFolder”;
rootButton.Caption = “Move To…”;
rootButton.Visible = true;

Now I recursively go over the current folder and its subfolders, adding new buttons under the rootButton as I go along.

Things to note:

  •  I create a different menu control depending on whether I'm creating a leaf node or a node that has children – one is a Button, the other a Popup. For some reason I couldn't create a PopupButton, maybe it's a control that's reserved for a toolbar and can't be used in a ContextMenu. This means that a node with children cannot be clicked, and we can't copy items to it. There may be a workaround to this using the OnAction property rather than the Click event, but I haven't gotten around to checking it out. I'd appreciate feedback.
  • I'm saving the FullFolderPath in each node's Tag object. This is so I can access it later when I'm moving the items. I originally wanted to save the EntryID + Store's EntryID in the Tag for a totally unique identifier, but for some reason Outlook crashed whenever I tried to save that in it. I have no idea why.
  • Note the recursion – each folder is addings its leaf-nodes as buttons, and sending each non-leaf children to another call to AddFolder.

private void AddFolder(MAPIFolder folder, CommandBarPopup menu)
{
      foreach (MAPIFolder subFolder in folder.Folders)
      {
MsoControlType linkType = (subFolder.Folders.Count > 0) ? 
               MsoControlType
.msoControlPopup : MsoControlType.msoControlButton;

     
CommandBarControl folderLink = menu.Controls.Add
(linkType, Type.Missing, subFolder.Name, 1, Type.Missing);
 
            folderLink.Tag = subFolder.FullFolderPath; 
            folderLink.Caption = subFolder.Name;

 
            if (linkType == MsoControlType.msoControlPopup)
            {
AddFolder (subFolder, folderLink as CommandBarPopup);
            }
            else
            {
(folderLink as CommandBarButton).Click += new
                             _CommandBarButtonEvents_ClickEventHandler
(
            MoveToFolder);
            }             
      }
}

3) Moving the items

As we could see above, each leaf node's Click event is handled by the MoveToFolder method:

Again, noteworthies:

  • The FullFolderPath we saved earlier is translated to a MAPIFolder object using the GetFolderFromPath function, a glaring omission in the Outlook object model that we have to rectify by hand. I'll post the full (and simply) code for this in a different post. It's included in the attached project. 
  • Note that we're casting the items in the current selection to MailItem objects, meaning standard outlook email messages. We're ignoring non-MailItems in this code. Since the COM object model doesn't give us any shared base-classes or interfaces for other entities, we need to write some ugly code to handle PostItems, AppointmentItems and so forth.

 

 
void MoveToFolder(CommandBarButton Ctrl, ref bool CancelDefault)
{
          MAPIFolder destFolder = GetFolderFromPath(Ctrl.Tag);
 
          foreach (object item in Application.ActiveExplorer().Selection)
          {
                    MailItem mi = item as MailItem;
                    if (mi != null)
                    {
                             mi.Move(destFolder);
           }
                    else
                    {       
                             // Can only copy MailItems;
                    }
          }
}

4) Profit!

Well, maybe not. But this is the entire extent of the code needed to implement this add-in. I've attached the whole project (including the MSI project) so you can install it at home, or use the code as a base for whatever add-in you feel like writing. The pre-built MSI is in the MoveToFolderAddInSetupDebug folder. Enjoy!

Wrapping the RAS

A couple of years ago I had a need to automate dialing a RAS connection and retrieving the IP address allocated by the server. I found myself writing a small, rather limited wrapper around the RAS P/Invoke calls. Far from complete, it only covered the functionality I needed for that project. But it was useful, and I kept it around.

Over the years I've had several people contact me to get a copy of that wrapper to save them time and effort, so to simplify matters, I'll simply attach my RasWrap project here and let google lead people to my blog, rather than to an ancient post on Channel9 where I last mentioned it.

The attachment contains two projects – the RasWrap project itself containing the P/Invoke signatures and wrapper classes to facilitate use, and a RasCaller project, a simple WinForm with example code on using the package.

Both are written for .NET 1.1, though they compiles and should work fine under 2.0.

The project includes a RasPhonebook class for iterating over a PBK file (RAS Phonebook), a RasEntry for retrieving information about an entry, and a RasConnection in order to dial or hang up against a RasEntry.

There is no support for writing new phonebook entries simply because I didn't need that functionality. If you have any problems, do let me know.

WCF Serialization Part 2d: A Solution, a Conclusion and a Contribution

This is the last part of my continuing saga of serializing dictionaries over WCF and beyond.

Quick recap: While WCF allows me to serialize an IDictionary easily, trying to serialize that dictionary later for other uses fails – specifically, caching it to disk using the Enterprise Library. This is because the Enterprise Library relies on the BinaryFormatter, which in turns relies on the type implementing ISerializable. An alternate solution was to use the NameValueCollection which implements ISerializable, but is incompatible with WCF's serialization.

I felt trapped, having to juggle between two incompatible serialization engines – one for communications, one for persistance. Frustrated. Annoyed. Helpless.

But then, as I was whining to my teammates, the solution came to me – there really isn't any reason to jump from one serialization method to the other. Since WCF gives me the most freedom and lets me use the IDictionary that I want, I can simply use WCF's serializer – the NetDataContractSerializer – for the Enterprise Library's cache serialization.

Going over EntLib's code proved very easy – the Caching project has a class called SerializationUtility that exposes two methods – ToBytes() and ToObject(). I'll reproduce the entire method, just to illustrate how simple it is:

public static byte[] ToBytes(object value)
{
   if (value == null)
   {
     
return null;
   }
  
  
byte[] inMemoryBytes;
  
using (MemoryStream inMemoryData = new MemoryStream())
   {
     
new BinaryFormatter().Serialize(inMemoryData, value);
      inMemoryBytes = inMemoryData.ToArray();
   }
  
return inMemoryBytes;
}

Given this simple method (and its even simpler brother, ToObject()) it's not hard to see that all the work that needs to be done is adding a reference to System.Runtime.Serialization and replacing BinaryFormatter with NetDataContractSerializer – and that's it. Their methods have identical signatures, so there's no work there, either.

The lovely thing about EntLib is that it comes with comprehensive unit tests. The only thing I did after making this change is letting NUnit chew on the 200-odd test methods defined and give me a positive result, and I'm good to go.

I've attached the new SerializationUtility.cs for those too lazy to make the change themselves, and the compiled Microsoft.Practices.EnterpriseLibrary.Caching.dll for those who want to just drop it in. Enjoy.

WCF Serialization part 1: Interfaces, Base classes and the NetDataContractFormatSerializer

One of WCF's goals is interoperability with standard protocol stacks, like WSE or other WS-* implementations. This led, I am told, to the design of WCF's default object serializer – the DataContractFormatSerializer. This handy little engine serializes primitive types, common objects, enums, Collections and anything that implements IXmlSerializable or ISerializable, giving us a much nicer out-of-the-box-and-over-the-wire experience for our objects.

Because of the aforementioned design goal, however, it has one little problem – the serialized data it generates does not contain information about the .NET CLR type from which this data was serialized. This makes sense when you have interoperability in mind – the datatypes you pass should be described in your service metadata, such as WSDL, and not rely on an implementation detail like the CLR type itself.

When we're writing closed systems, however, where we control both ends of the pipe and use WCF code, it can get limiting. Conside this scenario:

[ServiceContract]
interface MyService
{
   [OperationContract]
   void SendMessage (IMessage message);
}

This is a pretty realistic simplification of my current system, and we often have interfaces or abstract base classes defined in our service contracts.

What happens now? Let's I try to send a concrete IMessage implementations to this contract. When the service receives the messages and tries to deserialize the message parameter, it's stuck – there's no way to create an abstract IMessage from the serialized data, and the data carries no information on how to deserialize it.
If my contract defined this:

 [OperationContract]
   void SendMessage (MessageBase message);

I would be in the same jam – it would try to deserialize a DerivedMessage object into a MessageBase – at best, there would be loss of data. At worst (and as it happens) it simply fails to work.

The first solution that WCF's object model offered is to explicitly mark the service with the concrete types it can receive. This is a stop-gap measure that works, but takes the whole point out of using interfaces and inheritance trees:

[OperationContract]
[ServiceKnownType(typeof(DerivedMessage)]
void SendMessage (MessageBase message);

This would require me to add a ServiceKnownType attribute for every single concrete type, past, present and future. Obviously, not a good solution.

An alternate method involved a daring bit of magic:

[OperationContract]
[ServiceKnownType(“MyKnownTypeMethod”)]
void SendMessage (MessageBase message);

In this case, some backstage voodoo looks for a static method of that given name, calls it during the type's static constructor and asks it to return a list of Known Types. Not only is this totally unintuitive, it also simply doesn't work, at least for me. Maybe it's the beta, maybe it's me.

The third solution came to me from the future. I was shaking my fist at the heavens and asking why couldn't WCF simply serialize the typenames inside, like is done with Remoting. Interop isn't my concern, and it's silly to lose such a powerful feature. My answer came from Aaron Skonnard's blog, and from his August 2006 MSDN Magazine article, not quite yet published:

It seems the standard DataContractFormatSerializer has a shy little brother called the NetDataContractFormatSerializer. The 'Net' here, like in other parts of WCF, means “.NET”. This is a formatter than can be used when both ends of the stream are running .NET, and it can thus embed the type information in the serialized blob. This makes all the fudging around with knowntypes completely unneccesary, and gives us the flexibility we had with earlier methods.

Using it, unfortunately, is a closely held secret. Skonnard's blog is the only mention of the name outside of the sketchy SDK documentation. It seems that we have to write our own OperationBehavior attribute (which Skonnard graciously supplies) and put it on our OperationContracts. The code can be found in his page, and usage is as follows:

[ServiceContract]
interface MyService
{
   [OperationContract]
   [NetDataContractFormat]
   void SendMessage (IMessage message);
}

And that's it. The new attribute will add code that will replace the Formatter used during serialization, and from now on we're on easy street.

Notice that we have to set this attribute on every operation we need it. I was originally frustrated with not getting it to work because I instinctively put the attribute not on the SendMessage operation but rather on the IMessage definition – it stood to reason that we put it on the serializee, not the serializer. Once I got my head wrapped around that, it turned out you can't put it on the ServiceContract but have to do it for each operation seperately.

It seems a lot of work, but it really is much simpler than the alternatives above. Thank you, Aaron, for revealing this hidden gem! 

 

Ping Notifier!

How many times have you connected to a server via Remote Desktop to install some components?
How many have you rebooted a remote server and sat around waiting for it to go up?
How many times have you opened a command prompt and ran ping -t until the server started responding?


Well, your days of manual pinging have come to an end!
The PingNotifier comes to the rescue!


With one small click, you will be able to start pinging a server, and receive a systray notification when the ping is successful, or if an error occurs:



I’ve attached the full source to this blog post.


(Disclaimer: Code is neither secret nor safe. Does not check validity. Does not care about network load. Does not floss regularly. Does not do tracerouting, change TTLs to try alternate packets sizes. Does not care about the environment. Do not trust the code. Do not trust the code.)

Hiding properties from the Property Grid

Taking a break from the main components, I decided to get around to writing a small configuration editor using .NET 2.0’s lovely ability to edit .config files from code.


I have a custom Section Handler defined for my data, and decided the simplest thing to do would be to stick my custom ConfigurationElement objects onto a PropertyGrid and let the user edit the values directly.


The problem with that is that ConfigurationElement has several public properties that I inherit, and they show up in the grid:



My first instinct to hide them was to implement ICustomTypeDescriptor on my ConfigurationElement and implement GetProperties() so it only returns the properties I want. This turned out to be a ridiculously complicated endeavor, requiring me to implement many methods I don’t care about just so I could get to GetProperties, which in turn required me to subclass the PropertyDescriptor class and override lots of properties that I didn’t care about either. This whole design-time framework really needs an overhaul – it’s way too complicated and the documentation is vague at best.


So I abandoned that approach and immediately set off on achieving my goal in the ugliest, hackiest way I could find. The easiest way to hide a property from the propertygrid is using the [Browsable(false)] attribute. Since the properties are unfortunately non-virtual, I had to hide them in order to override their attributes:


#region Shadow unneeded properties.


[Browsable(false)]
public new bool LockItem { get { return base.LockItem; } set { base.LockItem = value; } }


[Browsable(false)]
public new ElementInformation ElementInformation { get { return base.ElementInformation; } }


[Browsable(false)]
public new ConfigurationLockCollection LockAllAttributesExcept { get { return base.LockAllAttributesExcept; } }


[Browsable(false)]
public new ConfigurationLockCollection LockAllElementsExcept { get { return base.LockAllElementsExcept; } }


[Browsable(false)]
public new ConfigurationLockCollection LockAttributes { get { return base.LockAttributes; } }


[Browsable(false)]
public new ConfigurationLockCollection LockElements { get { return base.LockElements; } }


#endregion


I simply hide them behind my new properties, and have those call the base’s implementation in case they’re actually used for anything.


Result? Works perfectly. Hardly clean, but it works:


 


 


 

Query SUBST information

For various reasons involving out testing framework, I found myself needing to get the full command-line of the current executing assembly. However, our development environment uses the DOS SUBST command to map a virtual drive letter for our dev files, so we have a consistent environment for all development machines. This is problematic, since I need this command-line to be launched in a different user context, where this SUBST mapping doesn’t exist. In short, I needed a way to get the real path to a file beyond the SUBST illusion.


The answer turned out to be surprisingly easy, and required only a tiny bit of P/Invoking. I’ve included the signature here and also updated it on pinvoke.net, where it was using a more complicated signature using IntPtr that is only required if we want more than one return value for the function.
Make sure the ucchMax parameter you pass the function is the same size as you initialize the StringBuilder’s buffer:


private static string GetRealPath(string path)
{
   
string
realPath = path;
   StringBuilder pathInformation = new StringBuilder
(250);
  
string driveLetter = Path.GetPathRoot(realPath).Replace(“”, “”
);
   QueryDosDevice(driveLetter, pathInformation, 250);
   
   
// If drive is substed, the result will be in the format of “??C:RealPath”.
   
if (pathInformation.ToString().Contains(??
))
   {
      
// Strip the ?? prefix.
      
string
realRoot = pathInformation.ToString().Remove(0, 4);
      
      
//Combine the paths.
      
realPath = Path.Combine(realRoot, realPath.Replace(Path.GetPathRoot(realPath), “”
));
   }

return
realPath;
}



[DllImport(“kernel32.dll”)]
static extern uint QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, int ucchMax);