A while back Eric blogged about How VSTO solves the Excel LCID or Locale issue using a transparent proxy object. While I didn’t write the original code I did spend a fair amount of time working on it. The LCID Proxy ensures that all calls to the Excel OM are called using the EN-US locale, regardless of the locale of the calling thread.
However, I thought I’d explain a bit about what was going on under the hood as it might help people using VSTO understand the limitations of the LCID Proxy.
It’s all about closure. No, I’m not about to tell you about my last bad breakup. The VSTO team uses “closure” to refer to the way wrapped proxy objects always return other wrapped proxy objects.
Excel.Application app = this.Application;
Excel.Range range = app.ActiveCell;
The Application property returns a wrapped Application object. Which, when its ActiveCell property is called, returns a wrapped Range object. This means that whenever you call a method or property on the Excel OM you always call on a wrapped so you never encounter problems when running in non EN-US locales.
As an aside you can use the System.Runtime.Remoting.RemotingServices.IsTransparentProxy(object) method to determine if a particular object is actually a proxy. You can also use the ExcelLocale1033Proxy. Wrap and Unwrap methods if you want to switch from a wrapped to an unwrapped proxy.
For example if you want to write a library for use within a VSTO customization but also for use in some other application code that automates Excel you can use the Wrap method to wrap the Excel.Application object after to create it but before you call your common code.
Note: There is a bug in the shipped version of VSTO 2.0 where we accidentally break closure. While this.Application will return a wrapped object, Globals.ThisWorksheet.ThisApplication does not. Try not to use ThisApplication. If you have to then you can use the ExcelLocale1033Proxy.Wrap() method to re-wrap the returned object.