Archive

Archive for October, 2012

Here, There, and Anywhere (part 1)

Technology is an amazing thing… throughout the years it has made our lives “better”.  I double quote the “better” because it is a very personal thing, where better might mean more free time, more luxury, more information, and in my case better means more open sky.

This year my wife and I decided to turn our plans for the future into our plans for the day.  We sold our house in Calgary, a city of over a million people, and headed to the open prairies of Saskatchewan.  While in a very small town right now, our final destination will be 6 acres of country side living about 10 minute drive from Yorkton, Saskatchewan.  As we meticulously plan out our new acreage home to be built next year, I think about how our ‘retirement dreams’ is a lifestyle we can enjoy in our younger years and provide to our children, all thanks to Technology.

A few years ago I decided to leave the full-time employment world and get back into contracting, seeing how much of that I could do working from home… well it can be a bit too quiet.  Although you spend a lot of time with the headphones on while writing software, there is a huge aspect of the work that is collaborative and social.  When I started a contract with NeoStream Technologies in Calgary, I was back to working out of an office (planned to be part time, but became full time).  Well when it comes to fun places to work, NeoStream certainly ranks at the top, and I say fun in a broad sense of what I consider fun… great people, bleeding edge tech, intriguing challenges, and a very social approach to business.

So with the first contract renewal and the approaching sale of our home, the realization that I would miss the in person interaction that working in an office affords.  Enter ‘Microsoft Lync’… the communication system NeoStream had recently incorporated for phone and messaging… add a few web cams, and viola, ‘Virtual Baydon’ was born.  Eight hours a day, five days a week, with two way video and voice, I can see and be seen by all the team members as if I was still sitting at my desk.  A camera was added to the product room, so conversations during meetings are engaging and interactive, and with desktop sharing of our onscreen planning board, everyone and everything is visible to all.

A few things were still missing, mainly due to the locations of certain events such as the morning huddle (an all staff standup meeting where we hear daily updates and announce our top tasks for the day), and our product sprint meetings.  These are in areas not covered by a camera, so recently NeoStream added a large screen TV and camera to the open area for morning huddles, allowing anyone to join in, including people working offsite or from home.  We even recently started having people working in other parts of the office join into the ‘Virtual Baydon’ session, so that they could contribute to conversations going on in the bull pen while continuing their work at their own desks.

I will delve into more details next time on both the work and home sides of things, but for now I must say, I didn’t expect working remotely to go so well.  Apart from not being able to go for coffee, not much is different… but I am definitely enjoying not having the commute.

Disable Password Prompts In Microsoft Word and Excel Automation

It’s not an easy task to automate MS Office, and especially to run it as a service or within a ASP.Net web site, but it is possible and with a little bit of hard work and research you can actually have a very stable interaction.  This is the first of my many "things to note" and "gotcha’s" I found when dealing with MS Office Automation, and it’s a long list.

Disabling Password Prompts in MS Word and Excel Automation, seemed to be a hot topic in a lot of forums with few insights to an answer, but here is the trick that I figured out.

First you have to accept that fact that you likely aren’t going to be able to open the password protected file, and that Word or Excel is going to fail the open request, so you have a COM Exception to catch.  The nice thing is that the Error Code returned from the exception is unique for password issue so you can catch it specifically and deal with it (either tell the user or simply ignore it, whatever you want).  Again I will post a sample with the codes soon, but if you try to open a password protected file and hit cancel you will see the exception returned so you can get the code from there.

Now onto the second and most important point, the brilliant engineers at Microsoft figured that if a document isn’t password protected then there is no point in even trying to use any password supplied.  So basically… enter a garbage password into the various password fields (something around 8 chars seems fine; too many though and it causes another exception all the time).  Both word and Excel behave the same way, only using the password when the document is protected, and so normal documents will open fine since they won’t use the password, and documents that require a password will use the garbage one you provided instead of prompting, and will simply fail with ‘Invalid password’ which you can catch and handle.

   1:  const uint COM_CODE_BADPASSWORD = 0x800A1520;
   2:  const string OPEN_OPTION_MOCK_PASSWORD = "GARBAGE1";
   3:   
   4:  object missingValue = Type.Missing;
   5:  object fileNameObject = fileName;
   6:  object confirmConversions = false;
   7:  object openAsReadOnly = true;
   8:  object addToRecentFiles = false;
   9:  object passwordDocumentObject = OPEN_OPTION_MOCK_PASSWORD;
  10:  object passwordTemplateObject = OPEN_OPTION_MOCK_PASSWORD;
  11:  object revertObject = missingValue;
  12:  object writePasswordDocumentObject = OPEN_OPTION_MOCK_PASSWORD;
  13:  object writePasswordTemplateObject = OPEN_OPTION_MOCK_PASSWORD;
  14:  object formatObject = missingValue;
  15:   
  16:  object doNotSaveChanges = WdSaveOptions.wdDoNotSaveChanges;
  17:   
  18:  try
  19:  {
  20:      // Using OpenOld is documented to be more compatible with older versions of Word.
  21:      // Word only tries the password if it needs it.
  22:      Document document = wordApplication.Documents.OpenOld(
  23:          ref fileNameObject,
  24:          ref confirmConversions,
  25:          ref openAsReadOnly,
  26:          ref addToRecentFiles,
  27:          ref passwordDocumentObject,
  28:          ref passwordTemplateObject,
  29:          ref revertObject,
  30:          ref writePasswordDocumentObject,
  31:          ref writePasswordTemplateObject,
  32:          ref formatObject
  33:          );
  34:   
  35:      // Do stuff with the document.
  36:   
  37:      document.Close(ref doNotSaveChanges, ref missingValue, ref missingValue);
  38:   
  39:  }
  40:  catch (COMException ex)
  41:  {
  42:      if (((uint) comException.ErrorCode) == COM_CODE_BADPASSWORD)
  43:      {
  44:          Debug.WriteLine("Detected a password protected Word document.");
  45:      }
  46:      else
  47:      {
  48:          throw;
  49:      }
  50:  }

You may ask, that’s fine for Word and Excel, but what about the other office apps… well unfortunately I haven’t tried Publisher or Access since I didn’t have need at the time, but I did learn that PowerPoint doesn’t expose any way to enter a password for opening the presentation, so the old Dialog Killer thread was the only resolution we had, looking for visible dialog windows with a particular name and sending them a WM_CLOSE message (I say ‘visible’ dialog since we were also dealing with Acrobat which keeps invisible dialog boxes with the particular name we were monitoring, and visible only seems to work 100% of the time).

My next post will be on using the Automatic Recovery options to open documents and some very frustrating issues I had with those.

Using Find and Replace in Visual Studio .Net with Regular Expressions to Bulk Change Properties and Methods (or anything else)

This is a really quick sample of using Regular Expression in Visual Studio .Net to perform and intelligent Find and Replace.  Documented mainly so I don?t forget it.

The need for this arose when I was extracting properties from a class, so that the data of the class was separate from the functionality.

Unlike normal regular expressions, Visual Studio doesn?t let you reference groups derived in the expression, instead a different syntax is used as {?} to tag parts of the string, and then in your replacement expression you refer to those tagged parts by \n (0 being everything, and then 1, 2, 3, etc for the individual tagged parts).

Find

public {[A-Za-z\<\>\[\]]*} {[A-Za-z]*} \{ get\; private set\; \}

Replace With

public \1 \2 \{ get \{ return someClass\.\2\; \} private set \{ someClass.\2 \= value\; \} \}

Note* Be sure to check ?Use: Regular expressions? in the Find and Replace dialog box.

For more details see: http://msdn.microsoft.com/en-us/library/2k3te2cs(VS.80).aspx

Categories: Visual Studio .Net

Macro Framework For .Net To Dynamically Populate String Content

As much fun and functionality there is in the ToString() and formatting, sometimes you just want to whole lot of freedom to safely populate a message template with any and all values that might come along.

I found this need when I was building a SOAP API test harness, then again in a Printer test harness when I needed a way to pass arbitrary values into command scripts without wanting to complicate the process with tons of arguments or mudding the scripts with code to parse strings to split arguments out.

This framework is pretty simple but works well and is very flexible when it comes to the source of the actual values.  It is broken out into a set of very small, specifically tasked classes and interfaces, the primary ones of which follow here:

The MacroUtilities, which consists of a single public ExpandMacros method to take a string, and a callback to a MacroEvaluator.  The ExpandMacros method uses a light regular expression Replace call to enumerate all of the “$(?)” patterns in the string, and then calls the MacroEvaluator callback for each one, then repeating the process recursively to expand any macros with those just expanded.  Really this is the actual brains of the process, as the return string from the regular expression is the final expanded result.

The MacroExpander (IMacroExpander) is an instance wrapper of the MacroUtilities methods, which maintains the reference to a single MacroEvaluator callback.  It?s just a nice wrapper.

The MacroEvaluator delegate is used to pass reference to a method call that takes a macro name, everything within the opening “$(” and closing “)”, as a string and returns the expanded result.

The IMacroLibrary interface is used to expose a means for any implementing object to provide access to properties or just about any value by a name.  See the ReflectionMacroLibrary for an included library that uses .Net Reflection to map macro names to public properties automatically.

The last key part of the framework is the MacroManager which links the MacroExpander instance with a macro library.  The MacroManager implements the IMacroExpander and IMacroLibrary interfaces.  It is an instance of this class that ties all the others together and is the one to keep a link to and use by the rest of your application.

IMacroLibrary macroLibrary = someMacroLibrary;
IMacroExpander macroManager = new MacroManager(macroLibrary);
expandedMacroString = macroManager.ExpandMacros(templateMacroString);

The reference to “someMacroLibrary” can be any object that implements the IMacroRepository interface.  There are a number of examples in the attached file that demonstrates different libraries, and I will go more into those later.

Macro libraries can be nested, which is a real strength, so you can have a default set of macro and then expand upon them to include static or dynamic content on the fly.

Download Source

Categories: .Net Framework Tags: ,