FileLoadException с новой версией dll - PullRequest
0 голосов
/ 12 ноября 2009

У меня есть приложение, которое должно работать с двумя версиями DLL. Я подумал, что просто скомпилирую приложение один раз, скопирую exe-файл в два каталога, а затем скопирую две версии DLL в каждый из этих каталогов. К вашему сведению, я ничего не делаю с GAC. Тем не менее, я получаю FileLoadException для версии с DLL, с которой он не был скомпилирован.

В проекте у меня для "Установленной версии" установлено значение false для ссылки dll. Но, возможно, это неправильная настройка. Как мне заставить это работать с несколькими версиями?

Ответы [ 4 ]

2 голосов
/ 12 ноября 2009

Если сборка, на которую вы ссылаетесь, имеет строгую подпись, CLR не будет загружать ее, если она имеет версию, отличную от той, для которой она была скомпилирована. В этом случае вы можете использовать файл конфигурации, чтобы указать версию, которую вы хотите использовать:

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <dependentAssembly>
            <assemblyIdentity name="YouAssemblyNameWithoutDotDll"
                              publicKeyToken="your-assembly-token"
                              culture="neutral" />
            <bindingRedirect oldVersion="1.0.0.0"
                             newVersion="2.0.0.0" />
        </dependentAssembly>
    </assemblyBinding>
</runtime>

Конечно, это предполагает, что новая версия сборки имеет те же сигнатуры методов, либо вы получите MissingMethodException во время выполнения.

0 голосов
/ 16 ноября 2009

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

Чтобы дать немного больше деталей, мне просто нужно создать экземпляр одного типа в нескольких библиотеках. Оттуда я рассматриваю это как объект интерфейса. Итак, вот мое решение:

Assembly asm = Assembly.LoadFrom("XXX.YYY.ZZZ.Bin.dll");
Type type = asm.GetType("MyType");
IMyType obj = Activator.CreateInstance(type) as IMyType;

Кажется, это работает.

0 голосов
/ 12 ноября 2009

Убедитесь, что две версии сборки имеют одинаковую версию AssemblyVersion, указанную в файле AssemblyInfo.cs.

Ex:

[assembly: AssemblyVersion("1.0.0.0")]

Я полагаю, что по умолчанию для новых проектов, созданных до VS 2008, используется:

[assembly: AssemblyVersion("1.0.0.*")]

, которая будет автоматически увеличивать версию сборки при каждом построении.

Это особенно важно для сборок, которые подписаны , поскольку строгое имя сборки включает его версию.

0 голосов
/ 12 ноября 2009

Это потому, что каждый раз, когда вы перекомпилируете dll, адреса функций меняются. И так как вы связываете свое приложение во время компиляции с вашей dll, эти адреса должны быть зафиксированы в вашем приложении. По сути, вы должны каждый раз перекомпилировать вашу программу с новой версией dll (или, если быть более точным, когда вы связываетесь с структурами данных) или использовать динамическую загрузку и GetProcAddress.

...