VSTS build: roles keep recycling because they can't locate valid DLLs - c#

My different roles run fine on my local machine. They run well enough when I deploy my project to Azure manually.
However, when I deploy them via VSTS CI/CD tools, the various apps roles refuse to start with "Could not load file or assembly" errors. I'm using Simple Injector.
Some of my projects say they can't find a DLL of another project in the solution:
Unhandled Exception: Could not load file or assembly 'DeviceCloud.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. at DeviceCloud.Application.CacheWorker.SimpleInjectionInitializer.RegisterPerWebRequestObjects() ...
Others complain more indirectly. I'm including yet another project, MasterNLogger, that depends on the ILogger interface, so I think what's really going on is it can't locate my MasterNLogger DLL:
Unhandled Exception: The configuration is invalid. Creating the instance for type ILogger failed. The registered delegate for type ILogger threw an exception. The registered delegate for type ILoggingAdministration threw an exception. Could not load file or assembly 'NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c' or one of its dependencies. The system cannot find the file specified. at SimpleInjector.InstanceProducer.VerifyExpressionBuilding()...
Why is this working when I deploy manually, and not when I'm deploying with the VSTS tools and build agent?

You need to add task(s) before build task to restore the packages:
Add NuGet Tool Installer task to build definition (Version of NuGet.exe to install: 4.4.1)
Add NuGet restore task (Path to solution, packages.config, or project.json: **\*.sln)

Related

Azure DevOps (VSTS) can't find Moq DLLs when running tests

I keep getting this error:
System.IO.FileNotFoundException: System.IO.FileNotFoundException: Could not load file or assembly 'Moq, Version=4.2.1507.118, Culture=neutral, PublicKeyToken=69f491c39445e920' or one of its dependencies. The system cannot find the file specified.WRN: Assembly binding logging is turned OFF.
It compiles fine in my project, and all of my Moq Nuget packages are set to version 4.2.1507.118. I don't have any binding redirects for Moq.
By the way, is there any way to turn assembly binding logging on for a VSTS hosted agent?
Log files:
Here's my build step log output
Here's my test step log output

Referencing library using Windows.winmd

What I'm trying to do
I'm trying to create a library (Arduino.dll) to interact with my Bluetooth device from a laptop (Windows 10). This library is intended to be used by a desktop application.
To achieve that, I had to reference both Windows.winmd and System.Runtime.WindowsRuntime.
What's working
I did write the library and tested it on a console application which was on another project in the same solution. To make it work, I had to reference the project and Windows.winmd in the test project. Note that this test project is used to test all of my libraries, so it is heavily manipulated and I tinkered with the settings a lot for years.
What's not working
I finished to write my dll, and wanted to use it in my desktop application. Therefore, I referenced both Arduino.dll and Windows.winmd as in my test project, expecting to work the same way. Sadly, on running the application, I got a "dll not found" when instantiating a class for Arduino.dll :
An unhandled exception of type 'System.IO.FileNotFoundException' occurred in LuxAFX4.exe
Additional information: Could not load file or assembly 'System.Runtime.WindowsRuntime, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The system cannot find the file specified.
Strange, but well, I tried to reference the (same) System.Runtime.WindowsRuntime as in Arduino.dll but no luck, I now got an even weirder error :
An unhandled exception of type 'System.BadImageFormatException' occurred in LuxAFX4.exe
Additional information: Could not load file or assembly 'System.Runtime.WindowsRuntime, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. Reference assemblies should not be loaded for execution. They can only be loaded in the Reflection-only loader context. (Exception from HRESULT: 0x80131058)
During my search for a solution, I understood that I shouldn't try to load this "reference library" and if it is not found, it must be because it is not installed on the system. But then, why would it work in my test project?
Another thing I may have understand, is that if my library doesn't expose members of referenced 'sub'-libraries, they won't be needed when referencing my library. Should I try to 'hide' all references? If so, is there a way to catch all exposed members? Source : How to to avoid referencing a dll's referenced dll
Side note : I use C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5.1\System.Runtime.WindowsRuntime.dll and C:\Program Files (x86)\Windows Kits\10\UnionMetadata\Windows.winmd.
May be related : Could not load file or assembly Windows.winmd and How to reference Windows.winmd from a .NET Core library?
After some more research, and with the hint given by Hans Passant, I finally understood that I had chosen the wrong System.Runtime.WindowsRuntime.dll to start with. Changing it to use C:\Windows\Microsoft.NET\Framework64\v4.0.30319\System.Runtime.WindowsRuntime.dll instead in both the project with the DLL and the project using it, resolved my problem.
I got the new file location here : C# “await” error when using WinRT from Desktop app

Add Reporting.WinForms Reference to VS2015

I'm looking at adding the reference;
Microsoft.Reporting.WinForms
to my VisualStudio (2015) project but when I go to Add the Reference in the Solution Explorer I couldn't find it.
Eventually I added it through NuGet but now I am getting the error message;
Could not load file or assembly 'Microsoft.ReportViewer.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.
which leads me to believe I just haven't added the package properly. I've installed Microsoft SQL Server Data Tools through program features but still no luck.
What am I missing?
You can try by executing this into Package Manager Console
Install-Package Microsoft.Reporting.WinForms.v11

Why does Powershell error importing a module by demanding a specific assembly version?

I have a PowerShell module (.NET assembly) that references the Autofac v3.5.2 and Autofac Configuration v3.3.0 libraries. When I load this module in PowerShell:
PowerShell.exe -NoExit -Command "& {Import-Module -Name .\MyModule.dll }
PowerShell opens, but displays the error:
"Could not load file or assembly 'Autofac, Version=3.3.0.0,
Culture=neutral, PublicKeyToken=17863af14b0044da' or one of its
dependencies. The system cannot find the file specified."
However, making the same Autofac references from within a Forms or WPF app does not result in an error - everything loads correctly. Note that both the module and UI apps invoke AutoFac Configuration code - they aren't just making reference to those two libraries.
I double checked all the assembly references and they're all set to "Specific Version=False". What then about PowerShell is telling it to require a specific version of the assembly?
Based on your most recent comment, you might also have some luck handling AppDomain.CurrentDomain.AssemblyResolve as per the article linked below. I've only ever used this when creating proxies that load an appropriate x86 or x64 assembly at runtime, but it does appear you can use it for version forwarding too.
http://blog.slaks.net/2013-12-25/redirecting-assembly-loads-at-runtime/

ILMerge: How to merge Azure runtime library?

I'm trying to use ILMerge to create a single executable that uses Windows Azure SDK 2.0 including the Microsoft.WindowsAzure.ServiceRuntime.dll, which I added manually because I couldn't find any NuGET package that contains it.
I'm using the following command line on a VS2012 post-build event:
/wildcards /targetplatform:"v4,C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0" /log:ILMerge.log /closed Output.exe *.dll /out:Executable.exe
However, I'm getting the following error in ILMerge.log, even though the output window reports no issues at all after building:
The assembly 'Microsoft.WindowsAzure.ServiceRuntime' was not merged in correctly. It is still listed as an external reference in the target assembly.
An exception occurred during merging:
ILMerge.Merge: The assembly 'Microsoft.WindowsAzure.ServiceRuntime' was not merged in correctly. It is still listed as an external reference in the target assembly.
at ILMerging.ILMerge.Merge()
at ILMerging.ILMerge.Main(String[] args)
And then the executable throws the following exception when opened:
System.Reflection.TargetInvocationException: Exception has been thrown by the
target of an invocation. ---> System.IO.FileNotFoundException: Could not load file
or assembly 'msshrtmi, Version=2.0.0.0, Culture=neutral, publicKeyToken=31bf3856ad364e35'
or one of its dependencies.
I have also tested the same output without merging and it works fine.
What am I missing here?
It would seem like this cannot be done, or at least not how I want it done.
Microsoft.WindowsAzure.ServiceRuntime.dll seems to have a dependency on the native library msshrtmi.dll. This means that ILMerge cannot handle it, since unmanaged code cannot be merged with managed code.
According to these two questions there is a way to work around this problem, but it involves packaging the msshrtmi.dllas a resource and unpacking it when it's needed. I feel it's kinda hacky.
So I guess I'll just have to do what I should have done before: remove all references to Microsoft.WindowsAzure.ServiceRuntime.dll from the project that builds the merged, non-Azure version of my WCF service. This might involve using some IoC container and doing some heavy refactoring, which is why I was trying to avoid it at this stage.

Categories