COM Interop, isolation and excluding duplicate references - c#

We are using a COM DLL provided by Microsoft (dsofile.dll) in a C# dll written by us (Assembly A). In order to avoid having to register the COM dll, I have switched the Isolated property on the reference to dsofile.dll to true.
This means that when we compile our dll, visual studio copies dsofile.dll, Interop.DSOfile.dll and Native manifest files to the bin folders of our solution and the application can run without the dsofile.dll being registered.
This approach was successful in a small test application.
However, in the real application, Assembly A is referenced by some of our other dlls (Assembly B and Assembly C) and the application EXE. When the native manifest file and interop dll are copied to the application's bin folder, different copies of each of the files are being used since each dll referencing our first dll creates its own copy.
This results in multiple copies of the files showing up as references in the setup project (ie dsofile.dll from the Assembly A, B and C and EXE folders, Interop.DSOFile.dll from the Assembly A, B and C and EXE folders, Native.Assembly A.manifest from the Assembly A, B and C and EXE folders) and compiler warnings ('Two or more objects have the same target location').
In addition, if the manifest and interop dll which were copied into the final folder did not come directly from the Assembly A folder (since the duplicate files overwrite one another), the application cannot successfully load the COM DLL.
I have been forced to manually exclude the duplicate copes of the files from the setup dependencies but they reappear when the solution is reloaded or rebuilt.
Can anyone help with a better method to achieve isolated deployment of the COM dll? I would also like to embed the manifests if possible but I have not been successful in doing this so far.
As an alternative I have been investigating the automation of the task of excluding the duplicate copies using EnvDTE for Visual Studio Automation but have not been able to discover how to access the Detected Dependencies nodes in a way that allows me to identify and exclude them. Accessing them with the UIHierarchyItem interface shows the name of the setup project as the name property for every file and does not have an exclude option.
Any advice would be appreciated.

I've resolved a similar problem in the past by making reference to projects instead of to the assemblies themselves. The deploy project has some problems with multiple references to assemblies that are being built in the solution.

Related

Assembly or file not found on plugin system C#

I have a project that uses plugins based on an interface, they are coded in other "Class Library" projects in the same main project solution. The main project has a folder that contains all the plugins in dll format. So for example I have a Plugins folder in "Bin/Debug/". All the plugins are compiled on that directory.
Each plugin project has a reference to the main project as it uses the main framework (reference not copied locally).
Each plugin should be able to use methods from other plugins, here I have the problem.
Example:
I have PluginA and PluginB, 2 DLLs, 2 different projects but the DLLs are in the same Plugins folder.
Now I want to instantiate PluginB in PluginA class so I add a reference to PluginB DLL (not copied locally). No errors from the Compiler.
But when I istantiate PluginA on the main project after loading all the plugins assemblies, I get a System.IO.FileNotFoundException Assembly or file not found. (referred to PluginB)
Basically seems that when I call a Plugin, from the main project, that calls another Plugin, I get an error. I've also tried to use the Assembly Resolve event without success.
Maybe I made some mistakes with the entire plugins system, it's the first time I use them.
Sorry for my english, I'm italian.
Thanks for the help.

Reason for unwanted implicit reference to dll in c# project build

I have a solution with quite a few projects in it and several dependencies to external DLLs. While trying to build a x64 version of the solution, I found that when building one project several libraries are copied into the output directory which are not mentioned in the project's references or anywhere else within the solution. I figured out that there is a collection of file names called _CopyFilesMarkedCopyLocal, which contains these DLLs. In the concrete case the copied library was used indeed, but it is a x86 library, which overwrites the existing x64 file in the output folder. How does a DLL, which is not mentioned in any project of the solution, become part of this collection? Can some referenced DLL induce further implicit references? Can I control this behavior?
Update: In the x86 build the set of file names contained in _CopyFilesMarkedCopyLocal is what I expected, namely one reference explicitly mentioned.

DLL reference not copying into project bin

Project A references Project B, and Project B references an external DDL (restored using NuGet). The DLL should get copied into Project A's bin folder (along with Project B's DLL):
In my case, when running Project A, I get the following exception thrown:
Could not load file or assembly 'PostSharp, Version=3.2.18.0,
Culture=neutral, PublicKeyToken=b13fd38b8f9c99d7' or one of its
dependencies. The system cannot find the file specified.
The DLL is not being copied into Project A's bin. All other external references from Project B are being copied across just fine, which is what is confusing for me.
Copy Local is set to true for all references involved. Example:
How do I do this?
Note: Using Visual Studio 2013.
The options that I found were to:
Add a reference to PostSharp in Project A.
Add dummy code in Project B so that the compiler would detect that the reference is being used.
Add a build event to force copy the DLL.
I don't like any of the above solutions. They are hacks in my opinion and will only make for a more unmaintainable solution in the long run.
I have fixed the problem by using a common output directory. This seems to be a recommended solution by many. I have also experienced much faster build times. See this Stackoverflow post.
When I ran into this problem it was because I changed a project's name, but did not change the assembly name - it was identical to the assembly name of another project in the solution.
I've added some dummy (unused) code on Project B, making reference to the DLL needed.
Thus, the compiler will guess that it must copy the DLL into project A output.

Whether or not to include external DLLs in C# project

Our project has a lot of external DLLs, most but not all of which are 3rd party DLLs.
Currently we do not have these DLLs included in our project. They are included in SVN and given a path to our build output directory. So, after building our project the neccessary files are there, because of SVN, but the project itself has no knowledge of them.
My feeling is that we should have a folder under the root of our project named something like Dependancies or ThirdParty with all of the DLLs included there and set their build event to copy to the output directory. They would exist in SVN as well, but in the same structure as the project, not in the build output directory.
The project itself only references one of these DLLs called CommunicationProc.DLL. The CommunicationProc.DLL then references all of the other DLLs. We have numerous DLLs to support different types of radio. So not all DLLs will be used, but any one of them may be used depending on the radio type.
As to whether or not the DLLs should be included in the project we have differing opinions internally, some of the team beleives they should only be in SVN and not part of the project itself.
Of note is that this are not .NET DLLs, most are old C DLLs.
What is the accepted practice? Can someone please provide me with a compelling arguement one way or the other as to whether to include them in the project or just SVN?
Its better to have them in a folder on source control and then copy them over to the debug folder on build event. This way you can manage their versions. If a newer version of some dll comes then you can replace the old one and put some comments with check in. Also if you are working in a team, then instead of copying files from debug folder to each team member, you can let each team member to use the same set of dlls from source control. If you are developing some control and want your customers to use that control then its easier for you to have a set of dependent dlls some where so that you can give those to your customer along with your .Net dlls.
I had the same issue with some un-managed dlls and ended up putting them in a folder so that all the team members have the same version of the dlls. Hope this helps.
I include a project that has no code but contains a folder where all the external assemblies and their dependencies are kepts. For each file set the Build Action to None and Copy to Output as Do Not Copyp. The project then references the binaries from this location. In your other projects, reference this special project. When you build, because the special project is referenced and it references all the needed dependencies, the binaries are copied as needed.
If you do not want a special project, still create the folder in your main project, added the assemblies, set their properties, then reference the assemblies as needed.
This gives you complete control over the versions and output, and more importantly, it is simple.

Referencing an external .NET DLL provided by another application in C#

I have a C# project which references a DLL (call it external DLL) which comes with another application. When I build my project, due to the reference, the external DLL gets automatically added to my project output. And when I run my project it loads the external DLL from my project folder.
The other application, which the external DLL belongs to, is developed by another team and the DLL is regularly updated. I don't want to package their DLL with my project. Instead I would like to have my project load their DLL when executed -- rather than pick the DLL copy from my project's folder.
Now I know that this is possible through reflection. I know that I can do an "Assembly.Load" and pick the DLL. But because I use the types from the external DLL all through my code, I would like the code to be statically type checked.
Here's what I would like:
Be able to compile my project by referencing the external DLL and thus get static type checking.
When the project is run, the external DLL is picked up from the other application's folder and not the copy of the DLL which is in my project's output folder.
Is there any way to solve this problem? Is there some middle ground between adding a reference and using reflection?
The most immediete solution to your problem is to change the properties of the reference. There is a setting called Copy Local. Set that to false and it'll stop copying the DLL to your project's output. You can access the properties of the reference by expanding the references folder in your solution, right-clicking on the reference in question, and clicking properties to open the properties pane.
The fact that Visual Studio copies the DLL to your project's output folder at build time doesn't really matter to the .Net Framework at runtime. All that matters is that the assemblies you reference are available to the framework either in the paths it searches or in the global assembly cache.

Categories