I been searching this for a long time but haven't seen an answer.
I'm referencing two dlls, which are a C++ library API for .NET, in a wcf service library, it works fine when invoking the wrapped method from wcftestclient. But when self hosting the library in a websercice it says"can't find assembly xxx.dll (it's one of the c++ API dll) or one of its dependency". But I can see the dll it says missing is auto copied to the bin/debug folder for the host webserive project. Also, I can host the library in a simple console project in which calling the wrapper method has no problem at all.
I hope this is a simple config setting that i'm missing to specify in the web config file, anyone has any suggestion? Thanks.
I spent almost three days on this problem and now it's resolved. In case this can help someone else who might have the same situation here is why.
The two c++ library .net api dlls are late binding so it won't look for its dependency until runtime. I even tried to registry the whole external library package in GAC and it didn't help; this was because one of two .net api dlls is a weak assembly hence CLR won't even bother looking for it in GAC. What I did was create a static constructor for the service and within the static constructor load the late binding assembly into AppDomain. I am using Assembly.LoadFrom(string filePath) method (other methods are available on Assembly class to do this). Now I can host the service on IIS and consume it in any client. So if clr is complaining it can't find an assembly but you can see it in the bin/debug folder, it's probably a late bind assembly which needs to be pre-loaded into the AppDomain; the good thing about AppDomain is you only need to load the assembly once and it will never unload an individual assembly.
Related
I have been working on a library which can perform various email actions with either EWS or MS Graph.
I had great success implementing EWS because of the limited amount of dependencies required for the EWS API. However when I implemented MS Graph into the library the amount of external dependencies grew ALOT, I went from (estimated) 2-3 external dependencies to 15-17.
(By external dependencies I am refering to dependencies which does not come standard with .Net framework 4.8)
All these depedencies are installed with the nuget package manager.
While I only had EWS implemented I had no issues to get ILMerge to merge the final DLL with the external dependencies, but as soon as I implemented Graph ILMerge would no longer work.
This is a problem as the library was originally developed for use in an application called Kofax TotalAgility (KTA), but this application would only store the single DLL as a blob in its internal database. This meant that when KTA read the dll for classes and methods (KTA gives an overview of available methods to be executed along with input and return parameters) the application would fail telling me that it could not resolve "Azure.Identity.dll".
After SO MUCH STRUGGELING to get ILMerge to work, but with no luck, I yielded and tried another approach.
I decided to develop an ASP.net Core application which would expose the methods in the DLL as a REST service, this in theory was an okay solution as KTA has excellent REST service support.
This new REST service worked on the premise that controllers would have post mappings for each method, and the controller would call my library.
Having the library external would be preferred as I might need it as standalone later.
Now having developed the REST API I created some Unit tests to test the different endpoints, to make sure everything worked as it should.
These told me that the EWS implementation still works as intended, but the Graph implentation throws an error: System.IO.FileNotFoundException: Could not load file or assembly 'Microsoft.Identity.Client, Version=4.39.0.0, Culture=neutral, PublicKeyToken=0a613f4dd989e8ae'. The system cannot find the file specified. File name: 'Microsoft.Identity.Client, Version=4.39.0.0, Culture=neutral, PublicKeyToken=0a613f4dd989e8ae'
I held my hopes high as the missing dependency was no longer the "Azure.Identity.dll", hoping that copying the missing DLLs to the IIS Application folder (next to the executable) would fix the issue, this however did not help anything.
I have since not been able to find any other solution.
I have thought about an internal assembly resolver which would be a C# event run everytime a dependency should be resolved. I would subscribe to this event in the class contructor, so that it would be ready whenever a method was called.
This probably would fix the issue in ASP.net Core, but it would not be fixed in KTA. If KTA should load classes and methods then the library is never "instantiated", I have tried doing the assembly resolve solution using a static constructor, but this does not help.
To sum up here is a list of things I have tried:
AssemblyResolver in a static contructor
RegAsm all the depedencies needed
Putting all depedencies next to the executable
Uploading all the dependencies to KTA Store
Merging all dependencies using ILMerge and ILMergeGUI
Embedding interop types (long shot, but I am desperate)
Trying to merge only dependencies that could not be resolved
Copying gacutil from my development machine to the target machine to use that instead of RegAsm (also a long shot)
Loading depedencies directly as an embedded resource
The optimal solution I am looking for is a library that is free of external dependencies.
But I can settle for a solution to my dependency problem in ASP.net.
I hope you can help.
I have a wcf service referencing a dll. Only way it works is by placing the dll in %windir%/system32 folder.
Things I have tried
tried switching between iis express, development server and iis (but this is irrelevant)
placing the dll in the bin folder and/or other application folders
trying to use the "regsvr32" util but the dll is not a com dll so it does not work.(no ddl entry point)
It is not a .NET dll so I don't think GAC can be manipulated to work with this
played with the system path variable without any success
What I actually want
A simpler method to access the dlls so I do not have to place the dll in system32 but contain it in an application folder and access it from there.
What am I missing?
EDIT:
I did find this post interesting and similar but again, it also uses the system32 method which is not the way to go.
If this is a win32 native library, you can "preload" it from a known location using pinvoked LoadLibrary passing a full path of your library as a parameter, somewhere early in your processing pipeline.
When any method from the library decorated with DllImport is called, the runtime will try to load the library (and would fall because the dll cannot be found) but since you preloaded it eariler, loading will succeed (loader checks the library file name, doesn't pay any attention to the directory the library is loaded from).
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.
I have a COM+ application that I wrote using C#. I have the assembly strongly named & signed. I want the application to use a library project & a 3rd party dll (log4net) but I don't want to place these in the GAC. The problem is that the COM+ application cannot locate the library dll & the log4net dll because they do not exist in the GAC.
I was reading another stackoverflow post where it was advised to use the "Application Root Directory" along with the application.manifest file. I tried this too, but now I get an error that looks like this:
The COM+ Queued Components Player was unable to create an instance of a Queued Component. CPlayer BindToObject
Any suggestions??
I think I figured out the issue. There was a issue with some of the underlying code in the application, but I was unable to debug it. So, after commenting out the 'ServicedComponent' from the inheritance, I was able to debug my code, found the issue & fixed it.
The answer in this stackoverflow post actually works without registering dlls into GAC.
I have a C# .Net 2.0CF application where I would like to load a .NET 'plug-in' DLL at runtime.
As I understand it, I should be able to use the System.Reflection.Assembly.LoadFrom() to load the DLL to an Assembly. Then use Assembly.GetTypes() to get the list of types within the plugin to match them to my expected interfaces.
The problem is that when I call GetTypes(), I get a System.TypeLoadException(). Based on the exception message, I assume this is because this particular plugin references some other assembly that this program knows nothing about. But, that's part of the point of it being a plugin! I don't want my application to have to know anything about these other assemblies.
How can I load this plug-in DLL without having my application reference every assembly used in the plugin?
Thanks,
PaulH
The situation is not that your app should reference every assembly that a plug-in uses. The plug-in references another DLL, not your app, and the plug-in should be "installed" (maybe simply put in a directory) along with everything it needs. This is unavoidable.