2012-04-12 2 views
0

У меня есть проект (называйте его платформой), который ссылается на DLL .net (называйте его инструментом-прокси), ссылаясь на dll C++ dll с помощью DllImport (вызывать его инструмент). Инструмент и его прокси всегда имеют одну и ту же версию и всегда развертываются как один.Ссылка на .net dll + неуправляемая dll

Мне нужно иметь возможность развернуть несколько инструментов (с их прокси) на одной машине и только одну платформу, использующую конкретную версию инструмента.

Похоже, я не могу разместить insturent-proxy для GAC, так как он использует C++ DLL. Я могу установить инструмент (и его прокси) в определенную папку, но как я могу гарантировать, что платформа найдет эту DLL?

Обновление.

Идея, что теоретически я хотел бы видеть, заключается в том, чтобы ссылаться на эту DLL во время разработки как на обычную, но иметь возможность сделать мой поиск приложения для этой DLL в пользовательской папке.

ответ

1

Для .Net сборок вы можете подписаться на AppDomain.AssemblyResolve и загрузить сборку, при необходимости с помощью Assembly.LoadFrom (см https://stackoverflow.com/a/10120664/143503).

+0

Ничего себе! Это именно то, что я искал. На самом деле мне не верили в ваш ответ, прежде чем я это пробовал. Довольно круто. – Archeg

1

Вы можете скопировать неуправляемые файлы DLL в папку, а затем добавить эту папку в переменную System Path Variable или скопировать эти файлы в Windows \ System32, так как эта папка всегда находится в системном пути.

Чтобы изменить системный путь, щелкните правой кнопкой мыши на моем компьютере -> Свойства -> Предварительные настройки системы -> Вкладка «Предварительный просмотр» -> «Переменные среды», вам нужно найти переменную пути, а затем изменить ее, чтобы включить файл.

Копирование файлов в Windows \ System32 или% SystemRoot% (C: \ Windows обычно) проще, хотя, но я бы рекомендовал использовать подход с Path переменной модификации

2

Сохраняя их в отдельных папках, все будет в порядке. Вы сами загрузите правую сборку прокси-сервера, используя Assembly.LoadFrom. Затем с помощью отражения, чтобы создать экземпляр класса из этой сборки и сделать вызов:

Assembly assm = Assembly.LoadFrom("c:\\Versions\\Version01\\instrument-proxy.dll"); 
Type yourClassType = assm.GetType("YourClass"); 
object yourClassObj = Activator.CreateInstance(yourClassType); 
object Result = yourClassType.InvokeMember("DoSomething", 
              BindingFlags.Default | BindingFlags.InvokeMethod, 
              null, 
              yourClassObj, 
              args); 

Чтобы избежать отражения вызова InvokeMember вы можете попробовать с интерфейсом:

Assembly assm = Assembly.LoadFrom("c:\\Versions\\Version01\\instrument-proxy.dll"); 
Type yourClassType = assm.GetType("YourClass"); 
YourInterface interf = (YourInterface)Activator.CreateInstance(yourClassType); 
interf.DoSomething(); 

Интерфейс должен был бы быть в отдельном сборку, о которой вы могли бы обратиться от вас platform. Все instrument-proxies пришлось бы скомпилировать против той же версии сборки интерфейса.

Если ваш инструмент-прокси не может найти неуправляемый Instrument.dll вы можете загрузить его в явном виде перед первым использованием:

[DllImport("kernel32.dll")] 
public static extern IntPtr LoadLibrary(string dllToLoad); 

IntPtr pDll = LoadLibrary(@"PathTo_Instrument.dll"); 

Free/выгружать его после того, как вы закончите:

[DllImport("kernel32.dll")] 
public static extern bool FreeLibrary(IntPtr hModule); 
+0

Да, но я хочу избежать использования отражения. Например, чтобы иметь возможность наложить на ваш класс, мне нужно иметь ссылку на DLL. Используя свой подход, я не могу себе этого позволить, поэтому мне нужно будет использовать рефлексию для всех вызовов, и это очень-очень тяжело, и я определенно должен избегать этого /. – Archeg

+0

Я добавил обновление к вопросу, что идеально и теоретически мне нужно – Archeg

+0

Вы правы. Я изменил код, но все это отражается, как вы знаете. Подумайте о решении, но с динамически загруженными сборками, вот что вы в итоге. Может быть, производительность будет приемлемой? Стоит испытание. –

0

Как Maceij выше, разверните свои инструменты в отдельных папках. Но вместо того, чтобы использовать отражение для загрузки/создания экземпляров инструментов, взгляните на MEF.

Ваши точные потребности может потребоваться еще один способ сделать это, но я позволил бы приборостроение прокси [Export] IInstrument завод интерфейс следующим способом:

IInstrument GetInstrument(string name, int major, int minor); 

Тогда скажите MEF, где найти свои инструменты, и пусть он создает различные фабрики, из которых вы можете запросить требуемый инструмент.

MSDN на MEF: http://msdn.microsoft.com/en-us/library/dd460648.aspx