Strong name assembly required only since .NET 4.0

0

I have an old application originally build against .NET 2.0 that used Office 97 Interop and it worked. When it was upgraded to .NET 4.0 the application crashed when it tried to load the Excel Interop with error:

System.IO.FileLoadException: Could not load file or assembly 'Interop.Office, Version=2.1.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. A strongly-named assembly is required. (Exception from HRESULT: 0x80131044)
File name: 'Interop.Office, Version=2.1.0.0, Culture=neutral, PublicKeyToken=null'

I was able to reproduce the issue with a very simple new application. The exception occurs whenever calling a method that instantiates an Excel.Application object. The application references the following libraries:

<Reference Include="Interop.Excel, Version=1.3.0.0, Culture=neutral, PublicKeyToken=5d41fe291391dcf0">
  <HintPath>..\..\Thirdparty\Microsoft\Office\97\Interop.Excel.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />

The Interop.Excel.dll library is in the application's folder and it's strongly-named. Here's its manifest:

// Metadata version: v1.1.4322
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
  .ver 1:0:5000:0
}
.assembly extern Interop.Office
{
  .ver 2:1:0:0
}
.assembly extern Microsoft.Vbe.Interop
{
  .publickeytoken = (71 E9 BC E1 11 E9 42 9C )                         // q.....B.
  .ver 11:0:0:0
}
.assembly Interop.Excel
{
  ...
  .hash algorithm 0x00008004
  .ver 1:3:0:0
}

There is no other library in the application's folder. There is Interop.Office.dll in a Thirdparty folder with the following manifest:

// Metadata version: v1.1.4322
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
  .ver 1:0:5000:0
}
.assembly Interop.Office
{
  ...
  .hash algorithm 0x00008004
  .ver 2:0:0:0
}

It is not strongly-named.

Summarising, when the application is built against .NET 2.0 or .NET 3.5, it runs fine and interacts with Excel without any exception. After changing its target Framework to .NET 4.0 or .NET 4.5.1, it crashes with the exception mentioned above. It makes no difference whether the application itself is strongly-named or not. I am not aware of any breaking changes in .NET 4.0 that would affect it.

Moreover, no configuration flag in app.config when in .NET 4.0 seems to help:

<runtime>
  <bypassTrustedAppStrongNames enabled="true"/>
  <NetFx40_LegacySecurityPolicy enabled="true"/>
  <legacyCasPolicy enabled="true"/>
  <loadFromRemoteSources enabled="true"/>
</runtime>

I have no idea where Interop.Excel.dll tries to load Interop.Office.dll from and why it succeeds in .NET 2.0 and fails in .NET 4.0. Neither Fusion Log nor Process Monitor are able to detect any loading of the latter library. I'm attaching the Fusion logs below if they might be helpful:

When run in .NET 2.0:

*** Assembly Binder Log Entry  (31/07/2014 @ 09:43:49) ***

The operation failed.
Bind result: hr = 0x80070002. The system cannot find the file specified.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscorwks.dll
Running under executable  C:\tmp\WindowsFormsApplication2\WindowsFormsApplication2\bin\Debug\WindowsFormsApplication2.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: User = domain\user
LOG: DisplayName = Interop.Excel, Version=1.3.0.0, Culture=neutral, PublicKeyToken=5d41fe291391dcf0
 (Fully-specified)
LOG: Appbase = file:///C:/tmp/WindowsFormsApplication2/WindowsFormsApplication2/bin/Debug/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = NULL
Calling assembly : WindowsFormsApplication2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
LOG: Start binding of native image Interop.Excel, Version=1.3.0.0, Culture=neutral, PublicKeyToken=5d41fe291391dcf0.
WRN: No matching native image found.

When run in .NET 4.0:

*** Assembly Binder Log Entry  (31/07/2014 @ 09:43:08) ***

The operation was successful.
Bind result: hr = 0x1. Incorrect function.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable  C:\tmp\WindowsFormsApplication2\WindowsFormsApplication2\bin\Debug\WindowsFormsApplication2.exe
--- A detailed error log follows. 

BEGIN : Native image bind.
END   : Incorrect function. (Exception from HRESULT: 0x00000001 (S_FALSE))


*** Assembly Binder Log Entry  (31/07/2014 @ 09:43:08) ***

The operation was successful.
Bind result: hr = 0x0. The operation completed successfully.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable  C:\tmp\WindowsFormsApplication2\WindowsFormsApplication2\bin\Debug\WindowsFormsApplication2.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: DisplayName = Interop.Excel, Version=1.3.0.0, Culture=neutral, PublicKeyToken=5d41fe291391dcf0
 (Fully-specified)
LOG: Appbase = file:///C:/tmp/WindowsFormsApplication2/WindowsFormsApplication2/bin/Debug/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = WindowsFormsApplication2.exe
Calling assembly : WindowsFormsApplication2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
WRN: No matching native image found.
LOG: IL assembly loaded from C:\tmp\WindowsFormsApplication2\WindowsFormsApplication2\bin\Debug\Interop.Excel.dll.


*** Assembly Binder Log Entry  (31/07/2014 @ 09:43:08) ***

The operation was successful.
Bind result: hr = 0x0. The operation completed successfully.

Assembly manager loaded from:  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable  C:\tmp\WindowsFormsApplication2\WindowsFormsApplication2\bin\Debug\WindowsFormsApplication2.exe
--- A detailed error log follows. 

=== Pre-bind state information ===
LOG: DisplayName = Interop.Excel, Version=1.3.0.0, Culture=neutral, PublicKeyToken=5d41fe291391dcf0
 (Fully-specified)
LOG: Appbase = file:///C:/tmp/WindowsFormsApplication2/WindowsFormsApplication2/bin/Debug/
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = NULL
LOG: AppName = WindowsFormsApplication2.exe
Calling assembly : WindowsFormsApplication2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
===
WRN: No matching native image found.
LOG: IL assembly loaded from C:\tmp\WindowsFormsApplication2\WindowsFormsApplication2\bin\Debug\Interop.Excel.dll.

EDIT

I have found a workaround by using the useLegacyV2RuntimeActivationPolicy attribute in app.config:

<startup useLegacyV2RuntimeActivationPolicy="true">
  <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>

More information on the attribute can be found here:

Although it seems to help and its meaning seems to be valid (running legacy components after migration to .NET 4.0), it also disables Side-by-Side Execution for COM Interop. Shouldn't it be enabled (and the attribute avoided) when using Office Interops?

EDIT

The previous workaround actually did not work. It seemed to, but it was caused by other change and not because of the attribute. Namely, I re-added the Interop.Excel.dll library to the project which automatically set Embed Interop Types to True. When the library is embedded it does work and interacts with Excel. I don't want to embed it, though.

.net
office-interop
excel-interop
strongname
asked on Stack Overflow Jul 31, 2014 by Łukasz Nojek • edited Jul 31, 2014 by Łukasz Nojek

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0