3

I have a C# / .NET Windows service that is archiving Exchange mailboxes, and I recently "packaged" the Veeam O365 Backup DLLs to be able to backup Exchange Online mailboxes automatically.

I 'll show you some piece of log showing that the program runs without issue for a while, then starts to fail out of nowhere with the error:

  • "Could not load file or assembly 'System.IO.Compression, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference."

... until the service is restarted:

(see Edit1, my picture got overwritten)

The stacktrace:

System.Management.Automation.CmdletInvocationException: Could not load file or assembly 'System.IO.Compression, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) ---> System.IO.FileLoadException: Could not load file or assembly 'System.IO.Compression, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
   at Veeam.Core.FileLoggerTransport.AutoArchive()
   at Veeam.Core.FileLoggerTransport.ArchiveAndDelete()
   at Veeam.Core.FileLoggerTransport.ControlLogSize()
   at Veeam.Core.FileLoggerTransport.WriteLine(UInt32 level, String message)
   at Veeam.Core.LoggerTransport.LogDefault(UInt32 level, String message, Object[] args)
   at Veeam.PowerShell.Core.BasePSCmdlet.BeginProcessing()
   at System.Management.Automation.Cmdlet.DoBeginProcessing()
   at System.Management.Automation.CommandProcessorBase.DoBegin()
   --- End of inner exception stack trace ---
   at System.Management.Automation.Runspaces.PipelineBase.Invoke(IEnumerable input)
   at System.Management.Automation.PowerShell.Worker.ConstructPipelineAndDoWork(Runspace rs, Boolean performSyncInvoke)
   at System.Management.Automation.PowerShell.Worker.CreateRunspaceIfNeededAndDoWork(Runspace rsToUse, Boolean isSync)
   at System.Management.Automation.PowerShell.CoreInvokeHelper[TInput,TOutput](PSDataCollection`1 input, PSDataCollection`1 output, PSInvocationSettings settings)
   at System.Management.Automation.PowerShell.CoreInvoke[TInput,TOutput](PSDataCollection`1 input, PSDataCollection`1 output, PSInvocationSettings settings)
   at System.Management.Automation.PowerShell.Invoke(IEnumerable input, PSInvocationSettings settings)
   at VeeamArchiverConnector.VeeamArchiverConnector.ConnectToVeeamServer(String serverName, Int32 port)
   at REMOVED.DeprovisionObject.DeprovisionOnline(String deprovisioningOu) in C:\Users\REMOVED\Source\Repos\ExchangeProvisioning\Deprovisioning\DeprovisionObject.cs:line 442
   at REMOVED.DeprovisionObject.Start() in C:\Users\REMOVED\Source\Repos\ExchangeProvisioning\Deprovisioning\DeprovisionObject.cs:line 125 

The project does reference System.IO.Compression, although:

  • The Nuget Package version is "4.3.0"
  • The version on the reference is "4.1.2.0"
  • The file version once built is "4.6.24704"

In my .csproj file I have this:

<Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
      <HintPath>..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
      <Private>True</Private>
      <Private>True</Private>
</Reference>

I don't have access to the code / project of "Veeam.Core.*" as they are Veeam DLLs coming with the Veeam O365 backup installer.

But globally what I don't understand, is the fact that it work for a while (usually around an hour or two), and then the error start unless I restart the service?

Any advise is welcomed!

Thanks


Edit 1 :

I added more logs and custom exception throw inside my "Veeam Connector" project, but it's the same thing: the final error is still about System.IO.Compression missing, and the inputs never changed:

detailedlogswithsteps

stillsameerrorevenwithcustomexception

Arvind Maurya
  • 910
  • 12
  • 25
JRouzies
  • 81
  • 1
  • 6
  • I looks like you had bad input. Try running with input that previously work to make sure the code still runs. – jdweng Nov 20 '19 at 11:57
  • Thanks for your reply, I will try to add more logs regarding the inputs, but note that they never change during the whole execution I showed you: once the service is started, it runs in loop, always with the same Input parameters (veeams server and port). That's my big issue here. When the error happens, nothing different is called compared to when it worked 15 mins before. – JRouzies Nov 20 '19 at 14:25
  • Not a solution, but this [blog](https://web.archive.org/web/20130328034650/http://tech.blinemedical.com/debug-could-not-load-file-or-assembly-or-one-of-its-dependencies/) helped me to debug the run time issues related to the missing assemblies and unable to load files/assemblies. It can help you – Badri Nov 20 '19 at 14:32
  • @Badri thanks, I'll make sure to check this link – JRouzies Nov 20 '19 at 15:55
  • The error message indicates the data is coming continuously and fails due to input being bad. I would modify your code to send the data to an output file while it is running to determine what data is being processed when the code fails. Even better to add an exception handle and break in the exception handler so you can do some debugging. – jdweng Nov 20 '19 at 17:14
  • My guess is that when the execution succeeds, the DLL was not required, then when it finally was needed, it got the version mismatch. In VS, when you right-click the DLL in Solution Explorer and pick Properties, what version does it show? I wouldn't be surprised if it says 4.2.0 instead of 4.1.3. This can happen if you are on .NET Framework and one or more different package references are using the `netstandard2.0` of their DLLs. If you find this is true, you will need to manually edit your .csproj file to use the `netstandard1.0` (or 1.1) versions instead. – howcheng Nov 20 '19 at 18:30
  • @howcheng it is correct, my project is a .NET Framework 4.7.2, and it is referring at least one .NET Standard project, so the version forced for this DLL is 4.3.0.0. I checked with another developer, and I was only having this info in the packages.config, pointing to "4.2.0.0", which obviously didn't exists (as I am forced to have 4.3.0.0), I updated like below, will let you know if the error happens again: – JRouzies Nov 21 '19 at 07:20
  • well the bindingRedirect didn't help, still getting the error, I guess I'll have to dig more with the Process Monitor tools – JRouzies Nov 21 '19 at 12:26
  • 2
    That binding redirect won't do it because there is no 4.3.0.0 version. It's confusing because the 4.3.0 package includes the 4.1.2.0 version. Take a look at https://stackoverflow.com/questions/55037565/projects-with-same-nuget-package-referencing-different-version-of-assembly – howcheng Nov 21 '19 at 17:02
  • @howcheng oh ok, I will update the redirect, this might be the source of the issue, as at first it was redirecting to 4.2.0.0 (which I guess still did not exists). Will put the redirect to 4.1.2.0 and let you know again. Thanks! – JRouzies Nov 22 '19 at 10:06

2 Answers2

5

@howcheng Thank you! That did the trick, service running for multiple hours with no issues.

So the issues was this binding:

<assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-4.2.0.0" newVersion="4.2.0.0" />

That was redirecting to 4.2.0.0. I Suppose it was good on my only .NETFramework project, but as you mentioned, .NETStandard System.IO.Compression forces a version 4.1.2.0, and didn't update the binding when installed > so it was now trying to find 4.2.0.0, which was no more and it was only 4.1.2.0.

Updating the binding to "newVersion=4.1.2.0" did it!

JRouzies
  • 81
  • 1
  • 6
0

I had the same problem. A netstandard2.0 library is using System.IO.Compression and is consumed from a .NET Fx 4.7.2 test project. The Could not load file or assembly 'System.IO.Compression, Version=4.2.2.0, Culture=neutral' exception happened when attempting to load System.IO.Compression from the netstandard2.0 code.

The fix was just to

  1. reference System.IO.Compression from the .NET Fx 4.7.2 test project

  2. call this method from the test, this way System.IO.Compression is resolved from a .NET Fx environement.

    private static void AvoidCannotLoadSystemIOCompressionException() {
     var justToAvoidStrangeException = ZipArchiveMode.Create;
    }
    

Odd but it works

Patrick from NDepend team
  • 13,237
  • 6
  • 61
  • 92