Automate Word Mailmerge Preview Results

(Long story short: the property you need is ViewMailMergeFieldCodes. Set it to 0 to enable preview; -1 to disable preview)

The mail merge process in Microsoft Word is a bit of a bear to automate sometimes. I suppose I should be thankful that it can be automated at all, but there are bits of it that are very poorly documented, requring a bit of trial and error to work with. It doesn’t help that most Office interop documentation leans toward Visual Basic…

Anyway, today’s issue was attempting to programmatically Preview the results of a Mail Merge in a C# VSTO project, like the button in the ribbon:

Big surprise: Document.MailMerge doesn’t contain any properties or methods with the word “preview”

Turns out there is a property called ViewMailMergeFieldCodes that does what we need, but in reverse. Microsoft’s documentation states:

This property returns True if merge field names are displayed in a mail merge main document, and False if information from the current data record is displayed

Trouble is, the field is an int, not a bool! A little debugging to the rescue:
When this field is set to -1, Preview is disabled, and the field codes are displayed.
When set to 0, Preview is enabled, and the record data is displayed.

To switch the displayed record, change Document.MailMerge.DataSource.ActiveRecord.

Now if only there was an event that fired when the record changed…

On using a light bulb as a current limiter (and crude current meter)

If you search on Google for “light bulb current limiter” you should come across several articles, newsgroup and forum posts about the details of building one. (i.e. )

Essentially, you connect a incandescent light bulb in series with an outlet, so you can safely test a device that might be prone to blow a breaker, or draw so much current as to release magic smoke.

One common feature of many of these articles is the idea that the light bulb will “blow” if the device draws too much current. This is totally and completely false.

When a 60-watt light bulb is connected directly to mains, it will draw approximately 60-watts of power, or 500 milliamps at 120-volts. That is the maximum amount of power that it will permit to flow, and it will burn at full brightness.

When you connect a device in series with the light bulb, it is effectively acting as a resistor to the current through the light bulb. With a 60-watt bulb, a device that used 250-milliamps wired in series would cause the bulb to burn at about 50% brightness (although light bulb brightness as a function of current is non-linear so this is not entired true, this is just an example…)
Now let’s imagine a worst case scenario – what could be wrong with an electrical appliance that would cause it to draw the maximum amount of current? Why shorting the power cord of course.

If you short the power cord of a device attached in series with a light bulb, the circuit is 100% IDENTICAL to plugging the light bulb directly into the wall. Nothing blows up, nothing catches fire – the bulb limits the circuit to 60-watts.

So if you are testing an electrical device using a lightbulb current limiter, please be aware: the bulb will not stop the power if too much is used. It is up to you to know how much power your device should be using, selecting a light bulb of the correct wattage to prevent it from going above (or much above) this, and turning off the power if the bulb is burning at full brightness when it should not be.

.NET multiple dictionaries with the same keys memory usage

I need to create some objects that will allow me to access columnar data by header name. The access looks something like this:

class ParentObj {
string[] columnNames;
ChildObj[] Children;
}

class ChildObj {
Dictionary<string, string> Items;
}

All the child dictionaries will have the same set of keys, matching the column list from the parent.

Now this particular object is going to be used on computers that are resource constrained, and could contain large quantities of data. My big concern was should I actually use separate dictionaries, or should I just store the values in an array, and lookup the column number from a single dictionary.

After trying both methods with very large random data, I found the memory usage to only increase 10megs using separate Dictionaries. Certainly not worth the added complexity of managing my own Dictionary implementation.

My next question was if the CLR was wasting a bunch of memory on a bunch of duplicate keys. CLR Profiler to the rescue!

I modifed my test program to be able to either use the same keys in all child objects, or use random keys as well. After making all the strings the same size, it was clear that .NET does not keep a separate copy of each of the duplicate strings around:

Object memory when all keys are the same:

Object Memory when the keys are random:

So in conclusion, using many dictionary instances with the same set of keys does not result in a significant amount of duplicate data in memory (or memory waste).

SortedSet wrapper for .net 3.5

Here is a VERY basic SortedSet wrapper for .NET 3.5
The SortedSet is one of the few new features of the .NET Framework 4.0 that I hate to go without. I recently had to drop a Class Library from 4.0 to 3.5, and the SortedSet was the only thing missing. So, I just created my own SortedSet that is build on the SortedList where TValue is a byte,

Here is my implementation – if you need any of the really fancy features, you will need to implement them yourself.

    public class SortedSet<T> : SortedList<T,byte>
    {
        public SortedSet() : base()
        {
        }

        public T Min
        {
            get
            {
                if ((base.Count) >= 1)
                {
                    return base.Keys[0];
                }
                else
                {
                    return default(T);
                }
            }
        }

        public T Max
        {
            get
            {
                if ((base.Count) >= 1)
                {
                    return base.Keys[base.Keys.Count - 1];
                }
                else
                {
                    return default(T);
                }
            }
        }


        public bool Contains(T value)
        {
            return base.ContainsKey(value);
        }

        public void Add(T value)
        {
            base.Add(value, 0);
        }
    }

Dynamics CRM 4.0 Optimized Web Service Generator

Microsoft Dynamics CRM 4.0 is really a beautiful thing – with a few very annoying exceptions, it is a very flexible, easy to use, easy to customize business application development platform. It includes a comprehensive Web Service that allows you to perform pretty much any UI task programmatically.

There is one problem though – the CrmService proxy class can take upwards of 7 seconds just to initialize the class. Before a singe bit is passed from client to server, you have to wait for the .NET runtime to build the ginormous XmlSerializers for the equally ginormous Web service.

Normally Sgen.exe can be used to improve the startup time of Web Services, but for some reason the CRM Service doesn’t always get along with pregenerated XmlSerializers.

The solution: remove all those unused entities! My organization’s current CRM instance has 192 entities, which translates into (at least) 1,616 separate classes in the generated proxy code.
I have built a tool that consumes a CRM 4.0 web service wsdl, and produces a nice packaged .dll (complete with embedded XmlSerializers) with practically all the unnecessary fluff removed. The produced dll fully supports Fetch and the DynamicEntity – just no static types.

On a .net IIS server, creating a new CrmService now takes 0.12 seconds – instead of 6+.

Update: Released! You can get it on Codeplex here:
http://crmservicegenerator.codeplex.com/

Disabling the URL rewriting on a SonicWall SSL-VPN bookmark

The SonicWall SSL-VPN 2000 is an impressive and feature-packed appliance. For the most part, I have no complaints (well, it would be nice if it worked on the iPhone or iPad, but this is a bigger issue…), but recently we ran into a rather annoying problem.

The SSL-VPN allows you to configure “bookmarks” that are links to your internal resources. Bookmarks can be Remote Desktop, FTP, VNC, and (among others) http and https. For intranet sites that support basic authentication, it will even push credentials.

All urls accessed through the vpn are rewritten something like: https://sslvpn/go/http://intranetsite/index.html. All URLs referenced within are rewritten as well. This works great until it doesn’t.

Say your intranet page has a link to google.com. The SSL-VPN will happily proxy all traffic through itself, rewriting the link to https://sslvpn/go/http://www.google.com.
Now say you had a link to some cloud-based application that doesn’t tolerate being proxied, and you have a problem.

As far as I can tell, SonicWall provides no option to disable rewriting for a specific bookmark. If you have purchased the Web Application Firewall addon, I believe you can setup exceptions, but I’m not even so sure about that. So… I had to try to figure it out myself.

Well after experimenting and digging, I found a workaround involving javascript redirection, obscuring strings, and overriding functions. While I typically would post my solution, I fear that SonicWall might consider it a security hole and simply patch things up without providing a viable solution. So, if you are pulling your hair out over your SSL-VPN rewriting all your external links – there is hope! Shoot me a comment / email and I’ll see if I can’t help you out.

UPDATE 10/18/2011

One of the people who requested my workaround found that in his case there was a much simpler solution: If you simply need to create a bookmark to an external website, you can just configure the bookmark on the SSL-VPN as an “external website”. My workaround is for the case where you need the SSL-VPN to proxy an internal page, but that page has a link (or redirect) to an external page that gets mangled.

Thanks!
-Jason

Hiding command window when running VirtualBox Headless

I discovered a couple things today. First, VirtualBox 4 appears to be less resource intensive than Vmware Player for the same workload.

Second, while VirtualBox provides the ability to run in a headless manner (aka hidden, or in the background), the command line tool to do so must be left open (on windows at least)

Yeah… kinda defeats the purpose of being headless.

If you close the cmd window, it kills your VM.

The solution: well here, I’ll just attach it:
VBoxHeadlessSilent.exe
(Requires .NET Framework 4 Client Profile)

Just drop it in your c:\Program Files\Oracle\VirtualBox folder (or wherever you installed it to) and invoke it the same as you would VBoxHeadless.exe. Instead of staying open, it will print out the response from VBoxHeadless.exe and return, leaving it running in the background.

All this app does is create a process with a hidden window and passes through the parameters.

Update 9/13/2011: If you are having problems with this not working or otherwise erroring out, it might be because of spaces in the VM Name. Try renaming the VM without spaces and see if that fixes it.
(Thanks David!)

Here is the source code if you are curious.

using System;
using System.Text;
using System.IO;
using System.Diagnostics;

namespace VBoxHeadlessSilent
{
    class Program
    {
        static void Main(string[] args)
        {
            string headlessPath = "";
            string argString = "";

            for (int i = 0; i < args.Length; i++)
            {
                argString += args[i] + " ";
            }

            headlessPath = Path.Combine(Environment.CurrentDirectory, "VBoxHeadless.exe");
            if (!File.Exists(headlessPath)) headlessPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "Oracle", "VirtualBox", "VBoxHeadless.exe");
            if (!File.Exists(headlessPath)) headlessPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Oracle", "VirtualBox", "VBoxHeadless.exe");

            if (File.Exists(headlessPath))
            {
                Process p = new Process();
                p.StartInfo.FileName = headlessPath;
                p.StartInfo.Arguments = argString;
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.CreateNoWindow = true;
                p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                p.StartInfo.RedirectStandardOutput = true;
                p.Start();
                Console.Write(p.StandardOutput.ReadToEnd());
                Environment.Exit(0);
            }
            else
            {
                Console.WriteLine("Could not find VBoxHeadless.exe!");
                Environment.Exit(1);
            }
        }
    }
}

Launching Internet Explorer without address bar in .NET

I needed to launch an Internet Explorer window to a particular URL in a near “chromeless” fashion – no toolbar, no address bar, no scrollbars, from a C# .NET application. At first I used thread.start(url), but you cannot specify how Internet Explorer should open – there are no command line options to customize the window.

The internet failed me – I was supposed to reference some web COM dll, that I didn’t even have.

The solution is painfully simple. Make sure you have a reference to System.Windows.Forms, create a WebBrowser object in code (no need to add it to a form), give it an about:blank url, then use Document.Window.OpenNew() to launch a new IE window with parameters.

 

Examples speak louder than words: this snippet will open google in a new browser window

using (WebBrowser wb = new WebBrowser())
{
    wb.Url = new System.Uri("about:blank");
    wb.Document.Window.OpenNew("http://google.com", "location=no,menubar=no,scrollbars=no,status=yes,toolbar=no,resizable=yes");
}

If you will be opening a lot of windows, maybe you should keep the WebBrowser object in a class variable.

Maybe this one was out there somewhere, but I couldn’t find it…