Search code examples
c#exceptioncominterop

PreserveSig for Non-Static Interop Method


Question

Can the PreserveSig attribute be applied to externally defined non-static functions? For example, can we mark the following method with PreserveSig = true:

https://learn.microsoft.com/en-us/dotnet/api/microsoft.office.interop.excel.range.specialcells?view=excel-pia

Research

Microsoft Docs outline the usage of the PreserveSig attribute for controlling whether an error type returned as a HRESULT gets returned as is or if it gets converted to an exception. But all the examples of this online apply to static methods e.g. see:

https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.dllimportattribute.preservesig?view=netframework-4.8

Finally, if we are the one defining the COM Interop library then it looks like we can easily tell methods not to convert errors to exceptions by marking them with PreserveSig, e.g. see:

https://blogs.msdn.microsoft.com/adam_nathan/2003/04/30/preservesig/

But the problem here is that it assumed we are the one writing the library. It doesn't apply to an external library defined in an imported DLL.

Related

.NET C#: Is it possible to import TLB (semi-)automatically and add PreserveSig to one type?

Use Case

I am using the interop library Microsoft.Office.Interop.Excel to loop through each worksheet in a workbook and check for errors by using the Range.SpecialCells function on the UsedRange of each sheet. I access all the interop objects starting off with a click of a button on the ribbon, and pulling off the Application object:

Window window = e.Control.Context;
return window.Application;

I then use this Application object to get a workbook, and then the worksheets, and then the UsedRange of each worksheet, which is a Range object, part of the Interop library. From this Range object, I can call the SpecialCells function, but I have no control over the fact that it throws an exception to indicate no cells were found. I was looking for a way to tell the interop library "don't throw an exception for this method", or even a way of wrapping/overriding the method with a version that doesn't throw the exception.


Solution

  • Alas, you cannot apply attributes to managed code that you don't control.