Событие AppDomain.AssemblyResolve не сработало на COM-сервере - PullRequest
0 голосов
/ 07 мая 2018

Кажется, что событие AppDomain.AssemblyResolve не запускается, если приложение, регистрирующее его, запускается через COM. Напротив, обработчик событий регулярно вызывается, если приложение запускается самостоятельно, без COM.

В документации по событию указано, что в случае, если зарегистрировано более одного обработчика, они вызываются по порядку, пока один из них не вернет значение не null. У меня нет контроля над COM-клиентом, поэтому я не знаю, является ли это причиной пропущенного вызова, но я удалил указанную сборку после компиляции, поэтому никакой другой обработчик не сможет вернуть ненулевое значение.

Знаете ли вы, может ли это быть причиной того, что обработчик событий не запущен или, может быть, я что-то упускаю?

Ниже приведен пример COM-сервера:

public class cPlugin {

    public void Main(object obj1, object obj2) {
        Initialize();
        RealMain();
    }

    private void Initialize() {
        AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
    }

    private void RealMain() {
        ClassLibraryHelloWorld.Class1 cl = new ClassLibraryHelloWorld.Class1();
        cl.SayHello();
    }

    private Assembly MyResolveEventHandler(object sender, ResolveEventArgs args) {
        //This handler is called only when the common language runtime tries to bind to the assembly and fails.

        //Retrieve the list of referenced assemblies in an array of AssemblyName.
        Assembly MyAssembly, objExecutingAssemblies;
        string strTempAssmbPath = "";

        objExecutingAssemblies = Assembly.GetExecutingAssembly();
        AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies();

        //Loop through the array of referenced assembly names.
        foreach (AssemblyName strAssmbName in arrReferencedAssmbNames) {
            //Check for the assembly names that have raised the "AssemblyResolve" event.
            if (strAssmbName.FullName.Substring(0, strAssmbName.FullName.IndexOf(",")) == args.Name.Substring(0, args.Name.IndexOf(","))) {
                //Build the path of the assembly from where it has to be loaded.
                strTempAssmbPath = "C:\\Myassemblies\\" + args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll";
                break;
            }

        }
        //Load the assembly from the specified path. 
        MyAssembly = Assembly.LoadFrom(strTempAssmbPath);

        //Return the loaded assembly.
        return MyAssembly;
    }
}

Класс ClassLibraryHelloWorld - это класс, который должен быть загружен во время выполнения и включен в сервер в качестве ссылки, чтобы не копироваться локально.

Edit:

Я обнаружил, что проблема не связана с COM. Фактически я создал тестовый COM-клиент и обнаружил, что событие правильно сработало. Так что проблема в реальном COM-клиенте, который является сторонней программой, которая не находится под моим контролем.
С помощью отладчика я обнаружил, что обработчик событий уже определен в реальном COM-клиенте, и я почти уверен, что он не возвращает null, когда пытается найти сборку. По этой причине мой обработчик не вызывается и выдается исключение.

Новый вопрос: какова лучшая альтернатива в этом сценарии для динамической загрузки сборки без события AppDomain.AssemblyResolve? Должен ли я создать новый AppDomain?

...