Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Could not load file or assembly" using COM Interop (DLL HELL?)

I'm building a COM Visible Object that needs to get called from a software written in Sybase Powerbuilder 11.5. I'm using C# and .Net Framework 4.7.2. I ususally build this kind of objects with no problem and register them using regasm /codebase because that's the way Powerbuilder likes them.

Now I'm trying to build an object that references the latest version of these nuget packages:

Microsoft.Graph
Microsoft.Graph.Auth
Microsoft.IdentityModel.Clients.ActiveDirectory
Graph.Community

I have my class library project with a com visible class. I built a console application that references that library (it does not use COM server) to test the code and everything works fine on my development machine from the command line. I can also run the console application from my target machin with no issues.

When I try to run the Powerbuilder application that uses the COM object, it throws an error:

Could not load file or assembly 'Microsoft.Graph.Core, Version=1.23.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies.

I have that dll in assembly's folder, but it is version 1.24.0.0. I have two questions:

  1. Why does the console application work while the COM object doesn't, given that they are using the same assemblies?
  2. How I solve this versioning problem in the COM version of the object?
like image 307
Kidservice Avatar asked Apr 28 '26 10:04

Kidservice


1 Answers

I found the solution to the problem but did not fully understand it. It was a cross reference problem, where packages A and B were both dependent on package C, but required different versions. I don't understand why this error shows up only when using COM Interface and not with the console application.

Here is what I did to solve:

// Define the AssemblyResolve event in the constructor of the COM Object.
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

// Get the path where COM Object's dll is
string codeBase = Assembly.GetExecutingAssembly().CodeBase;
UriBuilder uri = new UriBuilder(codeBase);
string path = Uri.UnescapeDataString(uri.Path);
_dllPath = System.IO.Path.GetDirectoryName(path);

Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            // Get the name of the assembly that failed loading
            var name = new AssemblyName(args.Name);

            // Manage the assembly that I know will cause problems
            string bindingAssembly = "Microsoft.Graph.Core";
            if (name.Name == bindingAssembly)
            {
                // Load the assembly from the COM Object's folder, and use whatever version there is
                return Assembly.LoadFrom(System.IO.Path.Combine(_dllPath, bindingAssembly + ".dll"));
            }

            // I should not get here. If I do I need to add another manual assembly load for the dll that failed loading
            return null;
        }
like image 108
Kidservice Avatar answered Apr 29 '26 23:04

Kidservice



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!