When VSTO was in Beta 2 the Excel "BeforeRightClick" event handler would receive an instance of an Excel.Range type. Now, instead of the range it receives a Transparent Proxy that consequently causes my Application.Intersect() method invokation to fail ("No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE))").
I'm not sure where the Transparent Proxy came from, it was not in the Beta 2 code, but it seems like when I try to use it, the Intersect method now fails.
Can anyone help out
Thanks,
- jim

Excel BeforeRightClick TransparentProxy
markep12
The reason you only see this with the Intersect() method is because not all Excel OM methods use the COM locale parameter. This makes the unwrapping/closure issue particularly insideous as it leads to weird errors for the developer down the line.
I also agree with your comments on the OM when used with C#. Obviously the best solution here would be to provide a better OM that was written with managed code in mind. Other than telling your that we're completely aware of this issue I can't comment further on Microsoft's plans at this time.
Let me know if I can be of further help...
Ade
Developer, VSTO
Yes!
First off, thanks a lot for your response, it did the trick. Let me know if this seems like a sound way to integrate your suggestion. Instead of "wrapping" the application object every time I want to get a reference to it, I moded the code generated by the IDE for the ThisWorkbook type and changed the assignment of ThisApplication in the Initialize() method to wrap the Application object:
[Microsoft.VisualStudio.Tools.Applications.Runtime.
StartupObjectAttribute(0)][System.Security.Permissions.
PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust")] public sealed partial class ThisWorkbook : Microsoft.Office.Tools.Excel.Workbook, Microsoft.VisualStudio.Tools.Applications.Runtime.IStartup {...[
global::System.Diagnostics.DebuggerNonUserCodeAttribute()][
global::System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] public void Initialize() { this.HostItemHost = ((Microsoft.VisualStudio.Tools.Applications.Runtime.IHostItemProvider)(this.RuntimeCallback.GetService(typeof(Microsoft.VisualStudio.Tools.Applications.Runtime.IHostItemProvider)))); this.DataHost = ((Microsoft.VisualStudio.Tools.Applications.Runtime.ICachedDataProvider)(this.RuntimeCallback.GetService(typeof(Microsoft.VisualStudio.Tools.Applications.Runtime.ICachedDataProvider)))); object hostObject = null; this.HostItemHost.GetHostObject("Microsoft.Office.Interop.Excel.Application", "Application", out hostObject); this.ThisApplication = (Microsoft.Office.Interop.Excel.Application)Microsoft.Office.Tools.Excel.ExcelLocale1033Proxy.Wrap(typeof(Microsoft.Office.Interop.Excel.Application),((Microsoft.Office.Interop.Excel.
Application)(hostObject))); Globals.ThisWorkbook = this;System.Windows.Forms.
Application.EnableVisualStyles(); this.InitializeCachedData(); this.InitializeControls(); this.InitializeComponents(); this.InitializeData(); this.BeginInitialization();}
...
}
Regards,
Dima Kherson
Mauro Araujo
If you simply change your customization code to use this.Application, rather than ThisApplication, then you'll get a wrapped object back and will not have to modify the generated code. Both properties return the same Application object.
The fact that ThisApplication isn't wrapped is a bug, both properties should behave identically.
Ade
DotNETKans - 2005
Regards,
Dima Kherson
Werwolf13
Thank you for the reply. Dima and I are a working on this together. As Dima mentioned above, the explanation and solution you provided did resolve our issue.
- Jim
Nicole Johanson MSFT
I've expanded a bit more on this in my latest blog post.
http://spaces.msn.com/members/AdeMiller/
Ade
Lydon
In our specific case the Locale is irrelevant so perhaps it would be best to turn off the LCID proxy by setting the attribute as your described. As to the this.Application vs Globals.ThisWorkbook.ThisApplication point. The code doesn't always execute in the context where this.Application is available such as a Worksheet or Workbook. Hence, I have to make explicit use of Globals.ThisWorkbook.ThisApplication. The only failure that I've run into so far (due to this bug) was when I called the Application.Intersect() method but I've mended that situation by employing your fix.
On a separate note, the PIAs for Office seem a bit raw. Are there plans to create a "finer" layer to use in C# that can better accomodate for optional params by using overloads and "params" arguments Also, many properties and methods still take and return "object" where they should be able to return a more specific type. In fact, the method I had troubles with--Application.Intersect()--is a perfect example of a horrific method from the point of view of a C# programmer. I had to write a wrapper for it in order to not have to pass it 30! arguments on every call:
public Excel.Range Intersect(Excel.Range range1, Excel.Range range2, params Excel.Range[] args)
{
if (range1 == null) throw new ArgumentNullException("range1"); if (range2 == null) throw new ArgumentNullException("range2"); if (args.Length > 28) throw new ArgumentOutOfRangeException("args", "Cannot exceed 28 elements"); object[] args2 = new object[28];args.CopyTo(args2, 0);
object missing = Type.Missing; for (int i = args.Length; i < args2.Length; i++) args2args2[11], args2[12], args2[13], args2[14], args2[15], args2[16], args2[17], args2[18], args2[19], args2[20], args2[21], args2[22], args2[23], args2[24],
args2[25], args2[26], args2[27]);
}
Overall, it seems that at the moment VB.NET is the language better suited for VSTO.In any case, we're grateful for your help.
Regards,
Dimitry Kherson
General
If you really don't want to use the LCID proxy you have two options:
1) You can turn it off entirely by setting the following attribute in the AssemblyInfo.cs file:
[assembly:
ExcelLocale1033(false)]I wouldn't recommend this. If you do this customizations running in non EN-US locales WILL NOT WORK.
2) You can also unwrap and wrap specific calls, again you have to be careful with locale issues because Excel OM calls to methods/properties that have a COM locale parameter will FAIL in non EN-US locales.
I may be able to help you further but I'd need to know more about what your application is doing with wrapped objects. It's possible that you're doing a lot of OM access, maybe in a tight loop and the proxy is effecting perf. If you can send me more detail I'll think about it some more.
Ade Miller
Developer, VSTO
sql2k5 newbie
http://blogs.msdn.com/eric_carter/archive/2005/06/15/429515.aspx
I think the problem here is that your application object is unwrapped - if so this is a bug.
There is a known issue where the ThisApplication property returns an upwrapped object, e.g:
Globals.ThisWorkbook.ThisApplication
If you use this.Application to obtain your Application object you will not see this problem.
Application app = (Application)Microsoft.Office.Tools.Excel.ExcelLocale1033Proxy.Wrap(typeof(Application), Globals.ThisWorkbook.ThisApplication);Please let me know if this solves your problem.You can tell if the object was correctly wrapped using System.Runtime.Remoting.RemotingServices.IsTransparentProxy, this will return true if the LcidProxy is enabled.
You can also wrap an unwrapped object using the Wrap() method, e.g.
Thanks,
Ade Miller
Developer, VSTO