Сценарії застосунків, за нашим C# кодом, динамічно генерують EXE, його сценаріїв застосування можуть бути дуже багатьма, наприклад, авторизація програмного забезпечення, ви можете ввести інформацію про авторизацію, згенерувати авторизовану DLL тощо, тож як досягти цієї функції, ми повинні згадати технічний Emit.
1. Огляд Emit
Випромінювання — це можна назвати випромінювачем або генеруючим. У Framework класи, пов'язані з Emit, фактично існують у просторі імен System.Reflection.Emit. Видно, що Еміт існує як елемент рефлексії. Говорячи про рефлексію, кожен має бути знайомий з ним, адже воно дозволяє нам бачити елементи збірки, щоб отримати велику кількість інформації, наприклад, які типи містить збірка, які методи містить тип тощо. Але відображення можна лише «бачити», тоді як Emit може динамічно генерувати код під час виконання. Давайте розглянемо, як генерувати код за допомогою Emit.
2. Модуль збірки та керований модуль
Асемблер — це логічна група одного або кількох модулів, файлів ресурсів, а по-друге, асемблер — це найменша одиниця повторного використання, безпеки та версійного забезпечення. DLL та EXE, які ми бачимо, можна назвати асемблером, асемблер містить кілька модулів, але зазвичай, коли ми компілюємо VS, компілюємо лише один модуль; якщо хочемо скомпілювати кілька модулів у асемблі, потрібно використовувати csc.exe реалізацію.
3. Динамічно генерувати операції з кодом
По-перше, нам потрібно зрозуміти, яким типом представлений кожен динамічний тип у .NET.
Асемблер: System.Reflection.Emit.AssemblyBuilder (визначає та представляє динамічні збірки)
Конструктор: System.Reflection.Emit.ConstructorBuilder (конструктор, який визначає та представляє динамічні класи)
Користувацький атрибут: System.Reflection.Emit.CustomAttributeBuilder (допомагає генерувати власні атрибути, використовуючи параметри, передані конструктором, для генерації атрибутів для класів)
Enum: System.Reflection.Emit.EnumBuilder (пояснює та вказує тип enum)
Подія: System.Reflection.Emit.EventBuilder (подія, що визначає клас)
Поле: System.Reflection.Emit.FieldBuilder (Визначає та представляє поля.) не може успадкувати такий клас)
Локальні змінні: System.Reflection.Emit.LocalBuilder (представляє локальні змінні всередині методу або конструктора)
Метод: System.Reflection.Emit.MethodBuilder (метод (або конструктор), який визначає та представляє динамічний клас)
Модуль: System.Reflection.Emit.ModuleBuilder (визначає та представляє модулі в динамічних збірках)
Параметр: System.Reflection.Emit.ParameterBuilder (створення або асоціювання інформації про параметри, таку як параметри методу, параметри подій тощо)
Властивість: System.Reflection.Emit.PropertyBuilder (Визначити тип властивості)
Клас: System.Reflection.Emit.TypeBuilder (визначити та створити новий екземпляр класу під час виконання)
OpCode — це опис директиви проміжної мови (IL). Є багато інструкцій для цього, ви можете переглянути офіційний сайт Microsoft:Вхід за гіперпосиланням видно.
Обмеження доступу до AssemblyBuilderAccess
AssemblyBuilderAccess.Run; Означає, що асембл можна виконати, але не зберігати. AssemblyBuilderAccess.Save; Вказує, що збірку можна зберегти, але не виконати. AssemblyBuilderAccess.RunAndSave; Позначає, що асембл можна зберегти та виконати. AssemblyBuilderAccess.ReflectionOnly; Вказує, що збірки можна використовувати лише у рефлексивному контексті і не можуть виконуватися. AssemblyBuilderAccess.RunAndCollect; Позначає, що збірку можна розвантажити, а пам'ять відновлювати.
Код виглядає так:
Спочатку використовуйте emit для генерації коду IL, потім динамічно генеруйте асемблер, а потім завантажте асемблер і викликайте її методи, як показано на рисунку нижче:
Використовуйте ILSpy, щоб переглянути згенерований код, як показано на зображенні нижче:
(Кінець)
|