External component has thrown an exception from third party assembly - c#

We use a 3rd party mixed mode assembly that interfaces with a printer device.
In one of our applications, the assembly functions correctly.
In another application, it was generating the following exception:
Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information.
After doing some research, I discovered that I could add the following to the app.config file to resolve this problem:
<startup useLegacyV2RuntimeActivationPolicy="true">
(The application that works already had this setting in its app.config)
Although this did resolve the "Mixed mode assembly" issue, now I'm seeing a somewhat different problem:
External component has thrown an exception
The strange thing is that I have one application which works correctly and another application which does not. They both call the third party assembly via the same code (which is another one of our assemblies).
I tried creating a very simple test app which calls the third party assembly using the same code path, and it also fails with the "External component has thrown an exception" error.
I've compared the app.config files for all of the applications and they are essentially the same, and I've double checked that all of the build settings are the same for each. Both projects target .NET 4.0 and X86.
There is obviously something different about the two applications but I'm at a loss to identify what it is.
Development environment is Visual Studio 2010.
Does anyone have any suggestions on what other areas I could investigate?

#tsells was right: there was a missing dependency
The third party assembly in question depended on another DLL that was present in the first applications bin folder.
I copied all of the files from the working application's bin folder to the non-working application's bin folder, and it resolved the problem.
From there it was just a matter of deducing which DLL was missing and including it in the second applications project.

When there are dependencies missing, you can use tools like CheckAsm for managed and Dependency Walker for unmanaged libraries to check for dependencies.

Related

Identifying problematic dependencies in C++/CLI project

My application compiles fine, but I get the following runtime error:
System.IO.FileNotFoundException was unhandled
HResult=-2147024770
Message=Could not load file or assembly {Wrapper} or one of its dependencies. The specified module could not be found.
The reference to Wrapper in the calling Application looks correct. The Wrapper dll exists in the correct location.
This project used to build and run on someone else's system, I saw it demonstrated several times. That person/computer is no longer available. Some paths of some dependencies have changed since the last time it was successfully built and run, I have fixed all compile errors related to this.
Just to clarify my project structure:
Digraph G
{
App [ label = "My C# Application"]
Wrapper [ label = "C++/CLI Wrapper"]
Lib [ label = "C++ Library"]
Dll [ label = "My helper C# DLL"]
CDep [ label = "Series of deep C++ dependencies managed \n by CMake for Lib, hard coded relative paths for Wrapper."]
App->Wrapper->Lib->CDep;
App->Dll->Wrapper->CDep;
}
Wrapper is a C++/CLI wrapper around a C++ library. The error is triggered when we try to load a class in the Application that has a using statement for the Wrapper.
Wrapper does have a lot of dependencies, but the error message does not indicate which dependency is problematic. This is a large, complicated system, most of which is built by other teams. The C++ components use CMake to get all the dependencies correct, but CMake does not natively support C#.
I tried using fuslogvw to find the binding error, but it showed me absolutely nothing until I changed settings to include all binds, and then it only showed successful binds.
http://msdn.microsoft.com/en-us/library/e74a18c4(v=vs.100).aspx
The paths are long, but not over 256 characters.
I had a warning in the compile for Dll (see graph above):
Warning 1 There was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "{cli_wrapper.dll}", "AMD64". This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project.
In Configuration Manager, the Dll is building for Platform "Any CPU" and Wrapper is building for "x64". I changed the dll to x64. I still get the runtime error.
Could not load file or assembly or one of its dependencies
Performed a clean, deleted build directory contents. No change.
Re-opened Visual Studio. No change.
Tried changing assembly name, default namespace, and project name to match. No change.
Could not load file or assembly 'xxx' or one of its dependencies. An attempt was made to load a program with an incorrect format
I believe we have to compile for 64 bit. We are dependant on a 64 bit C++ library.
Could not load file or assembly ... The parameter is incorrect
I am local administrator.
How to enable assembly bind failure logging (Fusion) in .NET
Tried the registry settings, but they appear to just be fuslogvw settings. No improvement in available log data.
Many other similar questions had ASP or service install specific answers.
I found the problem. There was more than one version of the library available to me, and I was using the include files from one version and the compiled library of the other. Dependancy Walker was key to finding which library had the problem, and if Aschratt had posted that as an answer rather than as a comment I would have accepted his answer.
I had the same error with a similar project earlier this week. First, when using C++/CLI, "Any CPU" doesn't exist. I had to build both for x86 to get through things.
Also, though my wrapper's dependencies were satisfied, it's the wrapper's exception that is caught by the CLR so it claims that the wrapper is missing a dependency. I was actually missing a dependency for the C++ DLL my wrapper wrapped (in my case, it was just a matter of forgetting to drop SDL2.dll and OpenAL32.dll in my new "Release" configuration output folder... I'd previously only worked with the Debug configuration where I'd already dropped those DLLs.
If you're positive you've got your wrapper's dependencies worked out, I'd recommend using Dependency Walker to check out the native DLL's dependencies. You could use Assembly.GetReferencedAssemblies with an outside script/program to double-check your wrapper as well (or ILSpy: http://ilspy.net/).
Last but not least, take a look at this: http://www.codeproject.com/Articles/442784/Best-gotchas-of-Cplusplus-CLI. He details the first two recommendations I made as well as some others.
Good luck!
One alternate root cause I've been running into quite a bit later, is that the application I'm working on uses impersonation, and the impersonated user does not have permissions to the GAC or to the folder that some dlls are in. You need to either give that user permissions, or change the way you do impersonation to load the dependencies before impersonation starts.

Visual Studio 2010 Setup Project Settings

I have a solution that contains three projects; UI (winforms), Business Layer and Data Access Layer, and I have created a setup project. I have added UI project as a primary output, and other two projects (actually dlls) automatically added to application folder and these two projects appears under the Detected Dependencies folder in the solution.
After building the solution, I have installed the program. When I run the program, I get the following error:
"Could not load file or assembly 'xxxBL', Version = 1.0.0.0 Culture = neutral, PublicKey Token = null or one of its dependencies." What am I doing wrong?
First make sure the dll that failed to load is actually in the search path of your Application. If it is, run the Dependency Walker on the dll that failed to load to see why it failed to load. Like the error message says it is possible that one of the dll's dependencies failed to load. For instance, a common mistake occurs if you deploy a debug version of your dll. It would work on your development machine since it most likely would have whaterver SDK you used already installed, but on a fresh machine it would fail to load because the debug dlls are not installed. The Dependency Walker will allow you to find this sort of problem.

c# app can't find dll in its working directory

I just switched from C++ to C# and I am a bit confused about referencing DLLs.
I have a third party DLL and a simple testing application that uses some of its methods. When I compile the project, everything goes well, but when I run the compiled app on another computer, I've got an error that says that the DLL is missing even though the DLL is in the app's working directory. What's even more strange is that I have access to the source code of another app that is dependent on an older version of this DLL and this app works well.
I've gone through the code and all the solution settings without finding anything really different.
Can you tell me how to reference a .dll from a working dir (Visual Studio 2010)?
Below is the exception:
System.IO.FileNotFoundException was unhandled
Message=Could not load file or assembly 'TIS.Imaging.ICImagingControl32, Version=3.2.4.1146, Culture=neutral, PublicKeyToken=257805929e8b7928' or one of its dependencies. The system cannot find the file specified.
Source=ICtestapp
FileName=TIS.Imaging.ICImagingControl32, Version=3.2.4.1146, Culture=neutral, PublicKeyToken=257805929e8b7928
FusionLog=WRN: Assembly binding logging is turned OFF.
To enable assembly bind failure logging, set the registry value [HKLM\Software\Microsoft\Fusion!EnableLog] (DWORD) to 1.
Note: There is some performance penalty associated with assembly bind failure logging.
To turn this feature off, remove the registry value [HKLM\Software\Microsoft\Fusion!EnableLog].
StackTrace:
at ICtestapp.Form1.InitializeComponent()
at ICtestapp.Form1..ctor()
at ICtestapp.Program.Main()
InnerException:
Here's a good blog post from Suzanne Cook from the .net team on debugging .net loader issues.
http://blogs.msdn.com/b/suzcook/archive/2003/05/29/57120.aspx
and here's the details on how it loads:
http://msdn.microsoft.com/en-us/library/yx7xezcf(v=vs.71).aspx
You have to add the dll as reference in your project references, once you added the library in the reference, when you compile the program the dll will be automatically copied to the compilation output folder unless otherwise specified in the reference properties ...
Then if you copy all items that you will find in the compilation output folder in the new location in the other PC, you should not have any problems.
Check also that the .NET framework installed on the other machine is at least as the same level of the project target ..
This also happens when you copy the debug executables over to another machine. Try compiling in release and moving over.

Referencing external assemblies from PowerShell snap-in

I'm developing a custom PowerShell snap-in, which references another project in the solution.
When I try to debug the snap-in (following [these instructions][1]), the assembly fails to load and my cmdlet fails with the message "Could not load file or Assembly..."
How do you instruct PowerShell on how to locate assemblies, or how do you specify where are located the assemblies needed by the snap-in?
I'd prefer to avoid registering the assemblies in the GAC, at least during development.
Not sure of the exact behaviour, but I would try and make use of fuslogvw to see exactly where the runtime is looking for the problematic assemblies. That would give you a clue as to how to get them to be copied into the correct place on build. This post by Scott Hanselman is quite useful, and this is the official documentation.
If you find the solution, please add an answer, as this must be a common scenario.
SOLUTION (Posting it here as suggested by one of the comments to my question)
My problem was rather specific, as I'm developing on a 64 bits server machine, but I'm posting the solution in case it could help someone else as well.
Using fuslogvw as suggested, I saw that the dependent assembly was being searched using the machine.config file under C:\Windows\Microsoft.NET\Framework64 and then the binding failed; launching the project with "start without debugging", instead, the machine.config file under C:\Windows\Microsoft.NET\Framework was taken (notice the missing 64 at the end).
I thought that the problem could be due to the image format, and infact the dependent assembly was being compiled with x86 as CPU target; I changed it to "Any CPU" and now the assembly is loaded correctly.

Assembly references won't resolve properly on our build server

We code in C# using VS2008 SP1. We have a server that runs Team System Server 2008 which we use for source control, tasks etc. The server is also our build machine for Team Build. This has been working just fine for a long time. Untill now. We get these error messages when trying to build one of our projects that has a reference to one external assembly (this happens both via Team Build, and when logging on physically and doing a regular build via Visual Studio):
C:\WINDOWS\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets
: warning MSB3246: Resolved file has a
bad image, no metadata, or is
otherwise inaccessible. Could not load
file or assembly 'C:\Program
Files\Syncfusion\Essential
Studio\7.1.0.21\Assemblies\3.5\Syncfusion.XlsIO.Base.dll'
or one of its dependencies. The module
was expected to contain an assembly
manifest.
C:\Program
Files\MSBuild\Microsoft\VisualStudio\v9.0\ReportingServices\Microsoft.ReportingServices.targets(24,2):
error MSB4062: The
"Microsoft.Reporting.RdlCompile" task
could not be loaded from the assembly
Microsoft.ReportViewer.Common,
Version=9.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a. Could
not load file or assembly
'Microsoft.ReportViewer.Common,
Version=9.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a' or
one of its dependencies. The module
was expected to contain an assembly
manifest. Confirm that the
declaration is correct, and that the
assembly and all its dependencies are
available.
The referenced component
'Syncfusion.XlsIO.Base' could not be
found.
These errors are for one project with one problematic assembly reference. When I try to build the entire solution there are of course many more errors because of this one. And there are two other projects that has the same problem with other assembly references. I have a list of the referenced assemblies that VS can't seem to resolve:
Microsoft.ReportViewer.Common
Microsoft.ReportViewer.WinForms
Syncfusion.Compression.Base
Syncfusion.Core
Syncfusion.XlsIO.Base
The Syncfusion assemblies are from a 3rd-party component package. The other two are related to the Microsoft ReportViewer component.
The references has been added via the Add Reference window, in the .NET tab, so I don't think there is anything suspicious about that. In the properties window for the assembly reference, there is no value in Culture, Description, Path, Runtime Version or Strong Name. Version says 0.0.0.0 and Resolved is False. I guess it is pretty obvious that VS cant resolve the reference. My question is why??? I've scratched my head a lot over this one. This only occurs on the server, the solution builds just fine on both my machine, and my coworkers machine. The assembly reference properties are fine on our machines.
I have tried uninstalling the 3rd-party component (on the server of course), and then reinstalling it again. Didn't help. I tried to repair the VS2008 installation. Didn't help. Tried to retrieve an earlier version from source control (that I know has buildt on the server before), and I got the same error messages. I have checked file permissions, and everything appears to be in order. I am running out of ideas...
How do I solve this?
Update 16.02.2009:
I have tried to compare ildasm output of the dll on my pc and on the server (see the comment I wrote about that), and there is one small difference in a line that to me appears to be a comment. I must admit that I don't understand why there is a difference at all, so maybe someone could explain that to me?
I also tried running a virus scan on the server. Didn't help. Tried to remove the reference and then readd it by browsing to the dll on disk. Didn't work.
Update 17.03.2009:
I've found the solution! The culprit was the TruPrevent module of Panda Antivirus. After disabling the module, everything works! =)
I discovered this with the help of fuslogvw.exe and the log it generated. Googled the result, and stumbled upon this blog entry.. Hope this can help somebody else to.
Almost certainly the problem is environmental - not source related.
Some ideas ...
(i) Try disabling your anti-virus/anti-malware tools - I've seen cases where these tools (particularly Trend Micro Antivirus, for some reason) can keep a DLL file locked after (during?) scanning, interfering with compilers.
(ii) Check your PATH environment variable. Even in these modern days, the PATH variable is used to resolve some things - if this is messed up (too long, maximum length is 2048 characters IIRC) then things can be odd.
(iii) You've checked File permissions - have you checked permissions in the registry? For example, SyncFusion installs its license key in both the User and Machine hives - if the build server can't read one or the other, could cause issues.
Good luck!
It could also be that the referenced assemblies are in the GAC on the dev machine, but not on the build machine. Get it out of the GAC, into your source repository, and reference it by path.
We've had the same problem, turns out the C drive was full (only had 28MB).
Freeing space resolved the issue, even though the build happens on D.
Do you see any differences between ildasm of this file
'C:\Program Files\Syncfusion\Essential Studio\7.1.0.21\Assemblies\3.5\Syncfusion.XlsIO.Base.dll'
on your machine versus on the server?
My suspicion is that the user that the build process is under does not have access to the folder that your 3rd party control is in. Since this functions properly on your machines, it is almost certainly user/permission specific.
Your 3rd party dll may depend on unmanaged dlls. Often it's because a specific version of the VC++ Runtime Dlls are missing.
Open the Dll with the Dependency Walker http://www.dependencywalker.com/ on your server and check for missing references.
Not sure if this'll help in your case, but I did have something similar before where a dll apparently got unregistered somehow, and running regsvr32 on the dll did the trick.

Categories

Resources