Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.53/15: Рейтинг темы: голосов - 15, средняя оценка - 4.53
3 / 3 / 3
Регистрация: 17.07.2017
Сообщений: 91
1

Выгрузка DLL AppDomain.Unload

23.01.2018, 10:34. Показов 2900. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день, уважаемые форумчане! Подскажите пожалуйста, как правильно выгрузить DLL через AppDomain. Не совсем понимаю принцип его работы. Буду очень рад, если поделитесь примитивным примером, как туда загрузить DLL и выгрузить из памяти (в программе должна быть динамическая загрузка/выгрузка). Заранее спасибо!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.01.2018, 10:34
Ответы с готовыми решениями:

Загрузка -выгрузка dll библиотеки
Работаю с оболочкой - надо добавить контекстное меню в системное! Нашёл отличный пример -...

Как отменить Unload формы в самом Unload'е?
По-моему всё ясно из вопроса... Private Sub Form_Unload(Cancel As Integer) Select Case _...

Выгрузка DLL
вот код длл, при инъекции в процесс и нажатии кнопки End должна происходить выгрузка, но процесс...

Выгрузка dll из процесса
Здраствуйте. DLL подключается к процессу при его старте, и мне нужно чтобы при определенном условии...

8
168 / 187 / 35
Регистрация: 21.01.2018
Сообщений: 230
23.01.2018, 11:46 2
Держи
Вложения
Тип файла: rar DomainDLL.rar (113.0 Кб, 12 просмотров)
2
3 / 3 / 3
Регистрация: 17.07.2017
Сообщений: 91
23.01.2018, 15:31  [ТС] 3
Кузнец кода,
Спасибо огромное!!!

Добавлено через 2 часа 47 минут
Увы, не выходит пока ничего Суть проблемы следующая. У меня динамически собирается библиотека из файла-скрипта:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
        private string ScriptsDirectory = System.Environment.CurrentDirectory+"\\Scripts";
        private const string CompiledScriptsAssemblyName = "Scripts.dll";
        public static bool SeconButtonClick = false;
 
        private void StartButton_Click(object sender, EventArgs e)
        {
            IScriptableComponent component = new DummyComponent();
 
            var compiledAssemblyPath = Path.Combine(Environment.CurrentDirectory, ScriptsDirectory, CompiledScriptsAssemblyName);
            var scriptFiles = Directory.EnumerateFiles(ScriptsDirectory, "*.cs", SearchOption.AllDirectories).ToArray();
 
            var scriptAssembly = Helper.CompileAssembly(scriptFiles, compiledAssemblyPath);
 
            var scriptTypes = Helper.GetTypesImplementingInterface(scriptAssembly, typeof(IScript));
 
            foreach (var scriptType in scriptTypes)
            {
                var script = (IScript)Activator.CreateInstance(scriptType);
                script.Run(component);
            }
        }
Класс Helper:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 public static Assembly CompileAssembly(string[] sourceFiles, string outputAssemblyPath)
        {
 
            var codeProvider = new CSharpCodeProvider();
 
            var compilerParameters = new CompilerParameters
            {
                GenerateExecutable = false,    
                GenerateInMemory = false,      
                IncludeDebugInformation = false, 
                OutputAssembly = outputAssemblyPath
            };
 
            compilerParameters.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
 
            var result = codeProvider.CompileAssemblyFromFile(compilerParameters, sourceFiles);
 
            if (result.Errors.HasErrors) throw new Exception("Assembly compilation failed.");
            
            return result.CompiledAssembly;
        }
 
 
        public static List<Type> GetTypesImplementingInterface(Assembly assembly, Type interfaceType)
        {
            if (!interfaceType.IsInterface) throw new ArgumentException("Not an interface.", "interfaceType");
 
            return assembly.GetTypes()
                           .Where(t => interfaceType.IsAssignableFrom(t))
                           .ToList();
        }
Не получается выгрузить никак(при повторном нажатии на кнопку) Буду очень рад помощи
0
168 / 187 / 35
Регистрация: 21.01.2018
Сообщений: 230
23.01.2018, 15:51 4
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
string source = System.IO.File.ReadAllText("Program.cs");
 
            var provider_options = new Dictionary<string, string>
                         {
                             {"CompilerVersion","v3.5"}
                         };
 
            var provider = new Microsoft.CSharp.CSharpCodeProvider(provider_options);
            var compiler_params = new System.CodeDom.Compiler.CompilerParameters();
            string outfile = "E:\\Matrix.EXE";
            compiler_params.OutputAssembly = outfile;
            compiler_params.GenerateExecutable = true;
            var results = provider.CompileAssemblyFromSource(compiler_params, source);
            Console.WriteLine("Output file: {0}", outfile);
            Console.WriteLine("Number of Errors: {0}", results.Errors.Count);
            foreach (System.CodeDom.Compiler.CompilerError err in results.Errors)
            {
                Console.WriteLine("ERROR {0}", err.ErrorText);
            }
            Console.ReadKey();
Добавлено через 1 минуту
В том числе и .dll компилирует, проверил))
2
3 / 3 / 3
Регистрация: 17.07.2017
Сообщений: 91
23.01.2018, 16:02  [ТС] 5
Кузнец кода, большое спасибо! Сейчас попробую!

Добавлено через 10 минут
Не все так просто, попробую подробнее описать

программа сначала собирает все cs файлы:

C#
1
2
var compiledAssemblyPath = Path.Combine(Environment.CurrentDirectory, ScriptsDirectory, CompiledScriptsAssemblyName);
var scriptFiles = Directory.EnumerateFiles(ScriptsDirectory, "*.cs", SearchOption.AllDirectories).ToArray();
затем делает сборку в Script.dll:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 public static Assembly CompileAssembly(string[] sourceFiles, string outputAssemblyPath)
        {
 
            var codeProvider = new CSharpCodeProvider();
 
            var compilerParameters = new CompilerParameters
            {
                GenerateExecutable = false,     // Make a DLL
                GenerateInMemory = false,       // Explicitly save it to path specified by compilerParameters.OutputAssembly
                IncludeDebugInformation = false, // Enable debugging - generate .pdb
                OutputAssembly = outputAssemblyPath
            };
 
            // !! This is important: It adds the THIS project as a reference to the compiled dll to expose the public interfaces (as you would add it in the visual studio)
            compilerParameters.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
 
            var result = codeProvider.CompileAssemblyFromFile(compilerParameters, sourceFiles); // Compile
 
            if (result.Errors.HasErrors)
                throw new Exception("Assembly compilation failed.");
            
            return result.CompiledAssembly;
        }
далее получает тип

C#
1
2
3
4
5
6
7
8
        public static List<Type> GetTypesImplementingInterface(Assembly assembly, Type interfaceType)
        {
            if (!interfaceType.IsInterface) throw new ArgumentException("Not an interface.", "interfaceType");
 
            return assembly.GetTypes()
                           .Where(t => interfaceType.IsAssignableFrom(t))
                           .ToList();
        }
и выводит результат

C#
1
2
3
4
5
6
7
8
9
10
11
 var scriptAssembly = Helper.CompileAssembly(scriptFiles, compiledAssemblyPath);
 
            // Find all types that implement the IScript interface in the compiled assembly
            var scriptTypes = Helper.GetTypesImplementingInterface(scriptAssembly, typeof(IScript));
 
            foreach (var scriptType in scriptTypes)
            {
                // Creates instances of type and pass component to the constructor
                var script = (IScript)Activator.CreateInstance(scriptType);
                script.Run(component);
            }
вот не могу понять, в какое место положить выгрузку и каким образом ее сделать. Я нагуглил что это делается через AppDomain.Unload, но при попытке выгрузки возникает эксепшн что Script.DLL занят...
0
168 / 187 / 35
Регистрация: 21.01.2018
Сообщений: 230
23.01.2018, 16:12 6
Скорее всего он занят процессом, посмотри в сторону закрытие файла.
0
3 / 3 / 3
Регистрация: 17.07.2017
Сообщений: 91
23.01.2018, 16:17  [ТС] 7
Цитата Сообщение от Кузнец кода Посмотреть сообщение
Скорее всего он занят процессом, посмотри в сторону закрытие файла.
Точно нет, он динамически загружает эту dll, которая слушает команды и получает данные из другой программы. Нужно как-то ее грузить после сборки в новый AppDomain, а потом выгружать... Непонятно только, как это сделать правильно...
0
168 / 187 / 35
Регистрация: 21.01.2018
Сообщений: 230
23.01.2018, 16:23 8
https://stackoverflow.com/ques... ing-memory

C#
1
2
3
4
5
6
7
8
9
public static object Call(string dll, string typename, string method, params object[] parameters)
    {
        AppDomain dom = AppDomain.CreateDomain("Volatile");
        Loader ld = (Loader)dom.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(Loader).FullName);
        object result = ld.CallInternal(dll, typename, method, parameters);
        AppDomain.Unload(dom);
        File.Delete(dll);
        return result;
    }
1
3 / 3 / 3
Регистрация: 17.07.2017
Сообщений: 91
23.01.2018, 19:30  [ТС] 9
Кузнец кода,

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

Добавлено через 2 часа 44 минуты
Итак, покопавшись по просторам Интернетов, наметился прогресс:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 public class RemoteLoader : MarshalByRefObject
        {
            public void LoadAndExecute(string assemblyName)
            {
                Assembly pluginAassembly = AppDomain.CurrentDomain.Load(assemblyName);
 
                foreach (Type type in pluginAassembly.GetTypes())
                {
                    if (type.GetInterface("IScript") != null)
                    {
                        IScriptableComponent component = new DummyComponent();
                        var instance = (IScript)Activator.CreateInstance(type, null, null);
                        instance.Run(component);
                    }
                }
            }
        }
Сам запуск через объявление данного класса вызывает исключение "Тип сборки не помечен как сериализуемый".Буду благодарен за помощь, если скажете, где косякнул!

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 private void StartButton_Click(object sender, EventArgs e)
        {
            
            // This is exposed to the scripts
           // IScriptableComponent component = new DummyComponent();
            
            var compiledAssemblyPath = Path.Combine(Environment.CurrentDirectory, ScriptsDirectory, CompiledScriptsAssemblyName);
           
            var scriptFiles = Directory.EnumerateFiles(ScriptsDirectory, "*.cs", SearchOption.AllDirectories).ToArray();
 
            var scriptAssembly = Helper.CompileAssembly(scriptFiles, compiledAssemblyPath);
            
            AppDomain appDomainPluginB = AppDomain.CreateDomain("appDomainPluginB");
 
            RemoteLoader loader = (RemoteLoader)appDomainPluginB.CreateInstanceAndUnwrap(
               scriptAssembly.FullName,
                "Scripts.MyCustomScript");
 
            loader.LoadAndExecute(CompiledScriptsAssemblyName);
            AppDomain.Unload(appDomainPluginB);
 
        }
0
23.01.2018, 19:30
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.01.2018, 19:30
Помогаю со студенческими работами здесь

Подгрузка и выгрузка dll
Возник у меня такой вопрос: возможно ли обновлять свою программу, не выключая ее. Т.е. там у меня...

Выгрузка DLL из памяти
Такая беда, есть две библиотеки, в каждой есть функция выгрузки её из памяти. И тут дело с D3D,...

Выгрузка заинжекченной dll
Уважаемые, имею следующую проблему: В приложение инжектится dll через загрузчик, моя задача -...

Выгрузка функции из Dll
Добрый день) сижу не могу понять в чем проблема, может кто-нибудь подскажет Добавлено через 7...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru