Unable to compile .NET application with referenced TLB when library is not registered - visual-studio-2010

I have a C# 4.0 application that is referencing a type library from a C++ application. This is used for some secure COM interop, a question I originally had asked here.
On my development machine this second application is installed so I can compile without any issues. If I attempt to compile on our automated build server, or any machine with Visual Studio installed but without this second program, I receive the following errors and compilation fails:
Text for google:
The type or namespace name could not be found (are you missing a using directive or an assembly reference?)
Cannot get the file path for type library "guid...." version 1.0. Library not registered. (Exception from HRESULT: 0x8002801D (TYPE_E_LIBNOTREGISTERED))
The referenced component 'SecurityAgentLib' could not be found
Picture for readability:
I'm not sure how to get around this other than by installing the application that registers the actual dll that implements these types, but I don't want to do that on our build server. The code that uses these types are wrapped in a class that is never instantiated unless prerequisite checks are run to verify the app is actually installed, so there is no chance of a runtime error. In fact I can run my app just fine on a machine without the second app installed - I just can't compile it there.
In visual studio the reference points to the .tlb file which is included in the solution directory, so the tlb file itself is present.
I can't imagine it should work this way, and I've searched around, but I'm apparently not searching for the right terms.
EDIT:
Running tlbimp.exe generates a dll but the type library should be sufficient for compilation, I thought at least. There is also an issue of broken references. I was reading this article Troubleshooting Broken References and it says that if the reference was to a COM component that is not installed than installing the component corrects the error, which is true.
Installing it on the build server really isn't an option. Opening visual studio and re-adding a reference if the path was broken doesn't work either.
I was able to use tlbimp to create a dll and used visual studio add a reference to that dll. That let me compile, but how would this work in an unattended build server?
EDIT
Okay I came up with two solutions that worked given my requirement of this all being unattended
Ran tlbimp to create a dll from the type library. I removed the reference to the tlb from my project and added a reference to the dll itself. When the source code was copied over to a new computer it compiled without issues.
In this scenario ideally we would checkout from SVN on the build server and copy the latest DLL from the second project, then compile this project.
I also removed the tlb and added the dll in visual studio and did a diff on the .csproj file. I don't see any downside to just having a reference to the dll instead of the tlb but if needed the build server could make modifications directly to this file to remove the tlb section and add a reference to the dll following a build of the second product.

Here are a couple options that each worked.
Ran tlbimp to create a dll from the type library. I removed the reference to the tlb from my project and added a reference to the dll itself. When the source code was copied over to a new computer it compiled without issues.
In this scenario ideally we would checkout from SVN on the build server and copy the latest DLL from the second project, then compile this project.
I also removed the tlb and added the dll and did a diff on the .csproj file. I don't see any downside to just having a reference to the dll instead of the tlb but the build server could make modifications directly to this file to remove the tlb

Related

How to create a managed plugin for Unity with Visual Studio Community for Mac

I'm going to create my first managed plugin for Unity (2018.2) using Visual Studio Community for Mac (7.6.11 build 9).
I've read the documentation but I think that the step-by-step instructions are not meant to be followed on Visual Studio Community for Mac.
As you can see in the screenshot below, I've created several projects using each and every library template available.
All of them compiled successfully to a DLL targeting versions of .NET framework that are incompatible with Unity.
The only project I could change the .NET framework version to match Unity's 3.5 is the one based on the Other > .NET > Library.
Everything works fine but I'd like to know if the assumptions, the process and the final result are correct. Can you tell me, please?
I don't know the difference between the "Class" and the "Class Library" option but you're supposed to use the "Class Library" option. This is not the main point of this answer.
Two future issues you haven't solved yet:
1. Referencing Unity's API.
If you ever have to use any Unity library or API in youir plugin such as Vector3, you need to add Unity's UnityEngine.dll to your library settings. If you don't, you will run-time exceptions.
Go to Project --> Add Reference ---> Browse ---> Browse Button
then select <UnityInstallationDirecory>\Editor\Data\Managed\UnityEngine.dll. You can now build your managed plugin. Since you're using Mac, this path is different on your OS. On Mac, this could be /Applications/Unity/Unity.app/Contents/Frameworks/Managed/UnityEngine.dll. You just have to find where UnityEngine.dll is located.
2. Invisible stack trace
With your current setup, if you run into error with your managed plugin, the stack trace won't be there. You won't have the file names and line numbers and this makes is very hard to debug your plugin code.
When you build the project, Visual Studio generates a PDB file instead of an MDB file. Unity can't use this directly. You have to convert the PDB files into MDB files.
From command line, run this:
<UnityInstallationDirecory>\Data\MonoBleedingEdge\lib\mono\4.5\pdb2mdb.exe UnmanagedPlugin.dll
Again, the path might be different on Mac, you just need to find "pdb2mdb.exe" that converts the PDB files into MDB files.
After that, copy the MDB and dll file into the "Assets" folder in your Unity project.

COM References and TFS build definition

I have a C# project in which I have a COM Reference. It compiles fine when opened in VS 2013. But, it fails as part of TFS build definition.
TFS version : 2013
TFS Build Controller & Agent : 2013
VS version : 2013
The failure message says that it could not find the Interop dll. I cannot manually create the Interop dll and check-in into TFS because it would keep changing and I want my C# project to always take the udpated COM reference.
I tried the COMFileReference suggestion but it did not solve my issue. I even manually registered the COM dll using regsvr32 but still I am facing the issue.
Any help is highly appreciated.
Regards,
kvk1985
A COM reference is the safest way to ensure that your program matches the actual installed component when you test your code. The compiler will read the type library of the component, a very similar mechanism that's used for normal .NET assembly references. Except that the type definitions come from the type library instead of .NET metadata.
But has a disadvantage in your case, it can only work when the component is actually installed on the machine. That probably did not happen on that build server. That's fairly normal, the people that maintain build servers don't particularly like anybody messing with it. And it is a maintenance headache, the build breaks when the devs update their machine with the latest version but forget to update the build server as well. And old builds get to be hard to reproduce.
So installing the component on the build server is the Quick Fix. If that's an insurmountable obstacle then somebody needs to run Tlbimp.exe on their machine. That generates the interop assembly, it needs to be checked-in to source control. And the project must be modified, remove the COM reference and add the reference to the generated interop library. It will now build the same way on the build server and the dev machines.
That's of course brittle the other way, if a dev updates the component on his machine then there will be a mismatch with the interop assembly. That can be a very ugly one, an E_NOINTERFACE runtime error if the COM vendor did it right, something excessively nasty like calling the wrong method, a stack imbalance or an AVE if he didn't. Otherwise the exact same kind of failures that can occur if the user's machine doesn't have the right version of the component installed. Standard DLL Hell.
You'll have to make the call yourself, there's no One Right Answer.

Oracle.DataAccess 2.112.1.0 reference issues in .NET4.0 VS2010

I have an Oracle.DataAccess 2.112.1.0 version referenced in my project. Whenever I run the project I get an error Could not load the assembly. I checked the entries made in the .csproj file for the referenced dll, and found that the referenced dll was Oracle.DataAccess 2.111.7.0. I am pretty sure the referenced dll is Oracle.DataAccess2.112.1.0 but not sure why the entry made in the project file is different. Any pointers to this would be helpful as this issue has been holding me up for a long time.
I found the same issue when a client use 2.112.1.0 in their references, but it kept referencing a machine local 2.112.3.0.
The reason is that when installed in the GAC, it inserts a policy file - a GAC level config entry to redirect your DLL to their newer version. Even if you have the file in the same dir, .NET 2+ will check the GAC for any policies before allowing your application to resolve the assembly itself.
Something I tried was a manual redirection in your App/Web.config file, but I found this didn't work for me, which is detailed under Redirecting Assembly Versions.
Once this is done, you may encounter this issue:
BadImageFormatException - Image is not of correct format (or something similar)
and/or
Version mismatch - The major/minor version does not match (or something similar)
These errors indicate that although your older assembly is now in use, the COM assemblies it reference are not expected. My investigation found Oracle ODP.NET assemblies stores its COM DLL versions hard-coded within.
The only solution that did for me, was to
Un-GAC the 2.112.X.0 that your app was auto-referencing.
Copy the version specific COM DLLs to a different directory (like \LIB)
Copy them into the build, as you build
If this all fails, I would recommend completely uninstalling the Oracle ODP.NET, deleting the Oracle directory manually and then after rebooting, installing the old DLL from the MSI directly. Oracle seem to have stored the whole history of drivers online at Oracle's website.
Good luck!

System.IO.FileNotFoundException when trying to load DLL

I'm not a a very experienced Windows developer, so I hope this all makes sense.
I created a Managed Assembly DLL using Visual Studio 2010. The DLL (Plip.dll) contains a C++ class that is using System.IO.SerialPort class to do some simple communication over a serial port.
In a second Visual Studio project I created a simple GUI that uses the class found in Plip.dll. In my GUI project I have the line : #using "Plip.dll" . In the Project Properties I set the 'Resolve #using References' value to the correct location of Plip.dll. The GUI builds just fine. If I copy the GUI.exe and Plip.dll to the same folder, the GUI runs just fine on my computer.
The problem I am having is that when I copy both files to a second computer, I cannot get the GUI executable to run. I get the following error : "System.IO.FileNotFoundException. Could not load file or assembly "Plip.dll" Vesion=.... ". I get this error even though both the exe and dll are located in the same folder.
Any suggestions on how to resolve this issue? Is there some option I need to set in my GUI project to load the DLL correctly at run time?
I suppose the problem is not the Plip.dll, but it's dependencies.
Use Dependency Walker on the second computer to see if it needs any other dll's (they might be installed in System folder or in %PATH% on your development computer, but not on the other).
If this second computer doesn't have Visual Studio installed, you are probably missing Microsoft Visual C++ 2010 Redistributable Package (you need to install it on the other computer)
Also make sure that you compile in Release because debug builds need debug dependencies.
I found the answer to this problem to be much simpler than Dependency Walker (but admittedly, that was fun to look at).
In my case, the issue was a mis-match between the .DotNet versions in the DLL and with the application's .net version. This was caused by building the "class library" using .DotNet 6.0 (dot net core?).
Instead, the entire class needed to be re-built using "Class Library (.NET Framework)"
enter image description here
I wrote an article on this problem.
https://keyliner.blogspot.com/2022/09/visual-studio-c-linked-dll-exception.html

Cannot reference dll in windows service

I've created a windows service in VS 2010 which references the model conveniently placed in a separate project which compiles to a dll. I have no problem referencing this dll in other parts of my solution (web apps), but in my windows services the following symptoms display:
Compiler error: The type or namespace %%% cannot be found (are you missing....
I add a reference to %%% (directly to a dll copy or to the project, makes no difference).
The compile error dissapears.
I build.
The compile error reappears.
Using fw4.
What's up with that?
Edit: I can add and use other dlls ofcourse. Third party and microsoft's.
Clear out your Debug & Release folders that are created and try doing a full "Rebuild"
Always check your warning messages.
System.Web.Extensions Assembly cannot be resolved

Resources