问题
I'm writing an application for the Peachtree API and it needs to work with any version of the API. Unfortunately the dll from Peachtree 2011 can't interact with Peachtree 2010, and vice versa, even though the two dlls are stored in the same location and run with exactly the same code.
I thought I should be able to refer to the dll by it's file path, leave specific version at false, embed interop types at false, and copy local at false and it would just use whatever version the machine had, but I get an error when I do that - "Exception has been thrown by the target of an invocation."
Is there a way to late-bind the dll even though it's COM?
I can provide code samples of whatever you think would be helpful, but it's more of a project setup issue than anything.
EDIT: Thank you all very much for your help. I found my solution on a different person's question and posted it here.
回答1:
Late-binding to COM objects requires that you do NOT add a reference to the COM library to your .NET project. Instead, you should you use something like this to create COM objects:
Type type = Type.GetTypeFromProgID("Excel.Application")
object app = Activator.CreateInstance(type);
Then, it will bind to any version of the COM library at runtime.
See this article for more details.
回答2:
This is the solution
Compile a version agnostic DLL in .NET
In case that link ever dies, the key is to handle the AppDomain.CurrentDomain.AssemblyResolve event like below. The event fires any time an assembly binding fails, so you can resolve it yourself, fixing version conflicts.
using System.Reflection;
static Program()
{
AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs e)
{
AssemblyName requestedName = new AssemblyName(e.Name);
if (requestedName.Name == "Office11Wrapper")
{
// Put code here to load whatever version of the assembly you actually have
return Assembly.LoadFile("Office11Wrapper.DLL");
}
else
{
return null;
}
}
}
来源:https://stackoverflow.com/questions/3611829/load-a-com-dll-at-runtime