2010-08-31 3 views
5

Я пишу приложение для API Peachtree и ему нужно работать с любой версией API. К сожалению, dll от Peachtree 2011 не может взаимодействовать с Peachtree 2010 и наоборот, хотя две библиотеки DLL хранятся в одном месте и работают с точно таким же кодом.Загрузите COM-dll во время выполнения?

Я думал, что должен иметь возможность обратиться к DLL по пути к файлу, оставить конкретную версию в false, встроить типы interop в false и скопировать локальную на false, и она просто будет использовать любую версию, которая была у машины, но я получить ошибку, когда я это сделаю - «Исключение было выбрано целью вызова».

Есть ли способ связать dll с поздним связыванием, даже если это COM?

Я могу предоставить образцы кода из того, что вы считаете полезным, но это скорее проблема с настройкой проекта, чем что-либо.

EDIT: Большое вам спасибо за помощь. Я нашел свое решение по другому вопросу и разместил его здесь.

+0

Обычно вы связываете DLL между собой во время компиляции, и если она присутствует в системе, она будет загружать DLL COM во время выполнения. Есть ли больше информации об ошибке или внутреннем исключении? Есть ли код ошибки (0xZZZZZZZZ)? Можете ли вы связать трассировку стека, или это слишком много информации о вашем приложении? API Peachtree, это COM, или это DLL, которая ссылается на COM? –

ответ

7

Для позднего связывания с объектами COM вы НЕ добавляете ссылку на библиотеку COM в свой проект .NET. Вместо этого, вы должны использовать что-то вроде этого, чтобы создать COM-объекты:

Type type = Type.GetTypeFromProgID("Excel.Application") 
    object app = Activator.CreateInstance(type); 

Затем он будет связываться с любой версией библиотеки COM во время выполнения.

Для получения более подробной информации см. this article.

+1

и с .net 4.0 вы можете использовать новый тип 'dynamic' и связать связь с поздним методом, исключая необходимость добавления ссылки на тип http://msdn.microsoft.com/en-us/library/dd264736.aspx –

+0

Единственное, что я хотел бы добавить, это то, что, когда вы получаете объект из экземпляра create, вы можете применить его к правильному типу интерфейса, так что у вас все еще есть статическая привязка, хотя хотя создание связано с поздними. – zumalifeguard

+0

Спасибо за помощь. Ваши идеи привели меня на правильный путь. – Yoenhofen

0

Это решение

Compile a version agnostic DLL in .NET

В том случае, когда ссылка умирает, ключ для обработки события AppDomain.CurrentDomain.AssemblyResolve, как показано ниже. Событие срабатывает в любое время, когда привязка сборки завершается неудачно, поэтому вы можете решить ее самостоятельно, исправляя конфликты версий.

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; 
     } 
    } 
} 
Смежные вопросы