Dynamic library loading windows

Dynamic-Link Library Redirection

Applications can depend on a specific version of a shared DLL and start to fail if another application is installed with a newer or older version of the same DLL. There are two ways to ensure that your application uses the correct DLL: DLL redirection and side-by-side components. Developers and administrators should use DLL redirection for existing applications, because it does not require any changes to the application. If you are creating a new application or updating an application and want to isolate your application from potential problems, create a side-by-side component.

To enable DLL redirection machine-wide, you must create a new registry key. Create a new DWORD key called DevOverrideEnable at HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options and set it to 1. After this, you must restart your computer to see the effects.

To use DLL redirection, create a redirection file for your application. The redirection file must be named as follows: App_name.local. For example, if the application name is Editor.exe, the redirection file should be named Editor.exe.local. You must install the .local file in the application directory. You must also install the DLLs in the application directory.

The contents of a redirection file are ignored, but its presence causes Windows to check the application directory first whenever it loads a DLL, regardless of the path specified to LoadLibrary or LoadLibraryEx. If the DLL is not found in the application directory, then these functions use their usual search order. For example, if the application c:\myapp\myapp.exe calls LoadLibrary using the following path:

c:\program files\common files\system\mydll.dll

And, if both c:\myapp\myapp.exe.local and c:\myapp\mydll.dll exist, LoadLibrary loads c:\myapp\mydll.dll. Otherwise, LoadLibrary loads c:\programВ files\commonВ files\system\mydll.dll.

Alternatively, if a directory named c:\myapp\myapp.exe.local exists and contains mydll.dll, LoadLibrary loads c:\myapp\myapp.exe.local\mydll.dll.

If the application has a manifest, then any .local files are ignored.

If you are using DLL redirection and the application does not have access to all drives and directories in the search order, LoadLibrary stops searching as soon as access is denied. (If you are not using DLL redirection, LoadLibrary skips directories that it cannot access and then continues searching.)

It is good practice to install application DLLs in the same directory that contains the application, even if you are not using DLL redirection. This ensures that installing the application does not overwrite other copies of the DLL and cause other applications to fail. Also, if you follow this good practice, other applications do not overwrite your copy of the DLL and cause your application to fail.

Dynamic-Link Library Best Practices

Important APIs

Creating DLLs presents a number of challenges for developers. DLLs do not have system-enforced versioning. When multiple versions of a DLL exist on a system, the ease of being overwritten coupled with the lack of a versioning schema creates dependency and API conflicts. Complexity in the development environment, the loader implementation, and the DLL dependencies has created fragility in load order and application behavior. Lastly, many applications rely on DLLs and have complex sets of dependencies that must be honored for the applications to function properly. This document provides guidelines for DLL developers to help in building more robust, portable, and extensible DLLs.

Improper synchronization within DllMain can cause an application to deadlock or access data or code in an uninitialized DLL. Calling certain functions from within DllMain causes such problems.

General Best Practices

DllMain is called while the loader-lock is held. Therefore, significant restrictions are imposed on the functions that can be called within DllMain. As such, DllMain is designed to perform minimal initialization tasks, by using a small subset of the MicrosoftВ® WindowsВ® API. You cannot call any function in DllMain that directly or indirectly tries to acquire the loader lock. Otherwise, you will introduce the possibility that your application deadlocks or crashes. An error in a DllMain implementation can jeopardize the entire process and all of its threads.

The ideal DllMain would be just an empty stub. However, given the complexity of many applications, this is generally too restrictive. A good rule of thumb for DllMain is to postpone as much initialization as possible. Lazy initialization increases robustness of the application because this initialization is not performed while the loader lock is held. Also, lazy initialization enables you to safely use much more of the Windows API.

Some initialization tasks cannot be postponed. For example, a DLL that depends on a configuration file should fail to load if the file is malformed or contains garbage. For this type of initialization, the DLL should attempt the action and fail quickly rather than waste resources by completing other work.

You should never perform the following tasks from within DllMain:

  • Call LoadLibrary or LoadLibraryEx (either directly or indirectly). This can cause a deadlock or a crash.
  • Call GetStringTypeA, GetStringTypeEx, or GetStringTypeW (either directly or indirectly). This can cause a deadlock or a crash.
  • Synchronize with other threads. This can cause a deadlock.
  • Acquire a synchronization object that is owned by code that is waiting to acquire the loader lock. This can cause a deadlock.
  • Initialize COM threads by using CoInitializeEx. Under certain conditions, this function can call LoadLibraryEx.
  • Call the registry functions. These functions are implemented in Advapi32.dll. If Advapi32.dll is not initialized before your DLL, the DLL can access uninitialized memory and cause the process to crash.
  • Call CreateProcess. Creating a process can load another DLL.
  • Call ExitThread. Exiting a thread during DLL detach can cause the loader lock to be acquired again, causing a deadlock or a crash.
  • Call CreateThread. Creating a thread can work if you do not synchronize with other threads, but it is risky.
  • Create a named pipe or other named object (Windows 2000 only). In Windows 2000, named objects are provided by the Terminal Services DLL. If this DLL is not initialized, calls to the DLL can cause the process to crash.
  • Use the memory management function from the dynamic C Run-Time (CRT). If the CRT DLL is not initialized, calls to these functions can cause the process to crash.
  • Call functions in User32.dll or Gdi32.dll. Some functions load another DLL, which may not be initialized.
  • Use managed code.
Читайте также:  Egistec es603 драйвер windows 10

The following tasks are safe to perform within DllMain:

  • Initialize static data structures and members at compile time.
  • Create and initialize synchronization objects.
  • Allocate memory and initialize dynamic data structures (avoiding the functions listed above.)
  • Set up thread local storage (TLS).
  • Open, read from, and write to files.
  • Call functions in Kernel32.dll (except the functions that are listed above).
  • Set global pointers to NULL, putting off the initialization of dynamic members. In Microsoft Windows Vistaв„ў, you can use the one-time initialization functions to ensure that a block of code is executed only once in a multithreaded environment.

Deadlocks Caused by Lock Order Inversion

When you are implementing code that uses multiple synchronization objects such as locks, it is vital to respect lock order. When it is necessary to acquire more than one lock at a time, you must define an explicit precedence that is called a lock hierarchy or lock order. For example, if lock A is acquired before lock B somewhere in the code, and lock B is acquired before lock C elsewhere in the code, then the lock order is A, B, C and this order should be followed throughout the code. Lock order inversion occurs when the locking order is not followed—for example, if lock B is acquired before lock A. Lock order inversion can cause deadlocks that are difficult to debug. To avoid such problems, all threads must acquire locks in the same order.

It is important to note that the loader calls DllMain with the loader lock already acquired, so the loader lock should have the highest precedence in the locking hierarchy. Also note that code only has to acquire the locks it requires for proper synchronization; it does not have to acquire every single lock that is defined in the hierarchy. For example, if a section of code requires only locks A and C for proper synchronization, then the code should acquire lock A before it acquires lock C; it is not necessary for the code to also acquire lock B. Furthermore, DLL code cannot explicitly acquire the loader lock. If the code must call an API such as GetModuleFileName that can indirectly acquire the loader lock and the code must also acquire a private lock, then the code should call GetModuleFileName before it acquires lock P, thus ensuring that load order is respected.

Figure 2 is an example that illustrates lock order inversion. Consider a DLL whose main thread contains DllMain. The library loader acquires the loader lock L and then calls into DllMain. The main thread creates synchronization objects A, B, and G to serialize access to its data structures and then tries to acquire lock G. A worker thread that has already successfully acquired lock G then calls a function such as GetModuleHandle that attempts to acquire the loader lock L. Thus, the worker thread is blocked on L and the main thread is blocked on G, resulting in a deadlock.

To prevent deadlocks that are caused by lock order inversion, all threads should attempt to acquire synchronization objects in the defined load order at all times.

Best Practices for Synchronization

Consider a DLL that creates worker threads as part of its initialization. Upon DLL cleanup, it is necessary to synchronize with all the worker threads to ensure that the data structures are in a consistent state and then terminate the worker threads. Today, there is no straightforward way to completely solve the problem of cleanly synchronizing and shutting down DLLs in a multithreaded environment. This section describes the current best practices for thread synchronizing during DLL shutdown.

Thread Synchronization in DllMain during Process Exit

  • By the time DllMain is called at process exit, all the process’s threads have been forcibly cleaned up and there is a chance that the address space is inconsistent. Synchronization is not required in this case. In other words, the ideal DLL_PROCESS_DETACH handler is empty.
  • Windows Vista ensures that core data structures (environment variables, current directory, process heap, and so on) are in a consistent state. However, other data structures can be corrupted, so cleaning memory is not safe.
  • Persistent state that needs to be saved must be flushed to permanent storage.

Thread Synchronization in DllMain for DLL_THREAD_DETACH during DLL Unload

  • When the DLL is unloaded, the address space is not thrown away. Therefore, the DLL is expected to perform a clean shutdown. This includes thread synchronization, open handles, persistent state, and allocated resources.
  • Thread synchronization is tricky because waiting on threads to exit in DllMain can cause a deadlock. For example, DLL A holds the loader lock. It signals thread T to exit and waits for the thread to exit. Thread T exits and the loader tries to acquire the loader lock to call into DLL A’s DllMain with DLL_THREAD_DETACH. This causes a deadlock. To minimize the risk of a deadlock:
    • DLL A gets a DLL_THREAD_DETACH message in its DllMain and sets an event for thread T, signaling it to exit.
    • Thread T finishes its current task, brings itself to a consistent state, signals DLL A, and waits infinitely. Note that the consistency-checking routines should follow the same restrictions as DllMain to avoid deadlocking.
    • DLL A terminates T, knowing that it is in a consistent state.

If a DLL is unloaded after all its threads have been created, but before they begin executing, the threads may crash. If the DLL created threads in its DllMain as part of its initialization, some threads may not have finished initialization and their DLL_THREAD_ATTACH message is still waiting to be delivered to the DLL. In this situation, if the DLL is unloaded, it will begin terminating threads. However, some threads may be blocked behind the loader lock. Their DLL_THREAD_ATTACH messages are processed after the DLL has been unmapped, causing the process to crash.

Recommendations

The following are recommended guidelines:

  • Use Application Verifier to catch the most common errors in DllMain.
  • If using a private lock inside DllMain, define a locking hierarchy and use it consistently. The loader lock must be at the bottom of this hierarchy.
  • Verify that no calls depend on another DLL that may not have been fully loaded yet.
  • Perform simple initializations statically at compile time, rather than in DllMain.
  • Defer any calls in DllMain that can wait until later.
  • Defer initialization tasks that can wait until later. Certain error conditions must be detected early so that the application can handle errors gracefully. However, there are tradeoffs between this early detection and the loss of robustness that can result from it. Deferring initialization is often best.
Читайте также:  Для установки необходимо использовать параметр включение или отключение компонентов windows

Что такое DLL

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

Исходная версия продукта: Windows 10 — все выпуски
Исходный номер КБ: 815065

Аннотация

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

В этой статье сравнивались библиотеки DLL с сборками Microsoft .NET Framework.

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

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

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

С появлением .NET Framework большинство проблем с зависимостями были устранены с помощью сборок.

Дополнительные сведения

Библиотека DLL — это библиотека, которая содержит код и данные, которые могут использоваться одновременно более чем одной программой. Например, в операционных системах Windows DLL Comdlg32 выполняет общие функции, связанные с диалогом. Каждая программа может использовать функции, содержащиеся в этой DLL, для реализации диалоговых окна «Открыть». Это помогает повысить повторное использование кода и эффективное использование памяти.

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

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

В следующем списке описаны некоторые файлы, реализованные в операционных системах Windows в качестве DLL.

ActiveX элементов управления (OCX)

Примером ActiveX является календарь, позволяющий выбрать дату из календаря.

Файлы панели управления (CPL)

Примером CPL-файла является элемент, расположенный на панели управления. Каждый элемент является специализированной DLL.

Файлы драйвера устройства (DRV)

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

Преимущества DLL

В следующем списке описываются некоторые преимущества, которые предоставляются, когда программа использует DLL:

Использует меньше ресурсов

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

Повышает модульную архитектуру

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

Упростит развертывание и установку

Если функции в DLL требуется обновление или исправление, развертывание и установка DLL не требуют повторной связи программы с DLL. Кроме того, если несколько программ используют один и тот же DLL- и другие программы, все они получают преимущества от обновления или исправления. Эта проблема может возникать чаще при использовании регулярно обновляемой или исправленной стороной DLL.

Зависимости DLL

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

  • Зависимая DLL-версия обновляется до новой версии.
  • Зависимый DLL-фиксирован.
  • Зависимая DLL-версия перезаписывается более ранней версией.
  • Зависимая DLL-система удаляется с компьютера.

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

В следующем списке описываются изменения, внесенные в Windows 2000 и более поздних операционных системах Windows, чтобы свести к минимуму проблемы зависимостей:

Защита файлов Windows

В Windows File Protection операционная система предотвращает обновление или удаление DLL системы несанкционированным агентом. Когда программа пытается удалить или обновить DLL-файл, определенный как системная DLL, Windows File Protection будет искать допустимую цифровую подпись.

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

Средства устранения неполадок DLL

Для устранения неполадок с DLL доступно несколько средств. Следующие средства являются некоторыми из этих средств.

DependencyМайл

Средство «Ветвь зависимостей» может рекурсивно проверять все зависимые DLL, используемые программой. Когда вы открываете программу в «Подмайловой зависимости», она проверяет следующее:

  • В этой проверке проверяется наличие отсутствующих DLL.
  • В этой папке проверяется наличие не допустимых программных файлов или DLL.
  • В этой функции проверяется соответствие функций импорта и экспорта.
  • Dependency При этом проверяется наличие циклической ошибки зависимостей.
  • Компания Dependency При этом проверяет допустимые модули, так как они находятся в другой операционной системе.

С помощью DependencyМайл можно документировать все DLL, которые использует программа. Это может помочь предотвратить и устранить проблемы с DLL, которые могут возникнуть в будущем. При установке Visual Studio 6.0 он находится в следующем каталоге:

drive\Program Files\Microsoft Visual Studio\Common\Tools

Универсальное решение проблем DLL

Средство DLL Universal Problem Solver (DUPS) используется для аудита, сравнения, документировать и отображать данные DLL. В следующем списке описаны средства, которые составляют средство DUPS:

Эта совработка содержит все DLL на компьютере и записи данных в текстовый файл или в файл базы данных.

Эта программа сравнивает DLL, перечисленные в двух текстовых файлах, и создает третий текстовый файл, содержащий различия.

Эта программа загружает текстовые файлы, созданные с помощью Dlister.exe и Dcomp.exe в базу данных dllHell.

Эта с помощью этой программы предоставляет версию графического пользовательского интерфейса (GUI) Dtxt2DB.exe.

База данных справки DLL

База данных справки DLL помогает находить определенные версии DLL, установленные программным продуктом Майкрософт.

Разработка DLL

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

Читайте также:  Драйвер для принтера canon l10891e для windows 10

Типы DLL

При загрузке DLL в приложении два метода связывания могут вызывать экспортные функции DLL. Два метода связывания — динамическое связывание во время загрузки и динамическое связывание во время работы.

Динамическое связывание во время загрузки

При динамическом связывание во время загрузки приложение выполняет явные вызовы экспортных функций DLL, таких как локальные функции. Чтобы использовать динамическое связывание во время загрузки, при компиляции и связывания приложения укажете файл загона (H) и файл библиотеки импорта (LIB). В этом случае linker предоставит системе сведения, необходимые для загрузки DLL и разрешения экспортируемой функции DLL во время загрузки.

Динамическое связывание во время запуска

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

В следующем списке описываются критерии приложения, в соответствии с которыми следует использовать динамическое связывание во время загрузки, а когда — динамическое связывание во время запуска:

Производительность при запуске

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

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

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

Точка входа DLL

При создании DLL можно дополнительно указать функцию точки входа. Функция точки входа вызвана, когда процессы или потоки присоединяются к DLL или отсоединяются от DLL. Функцию точки входа можно использовать для инициализации структур данных или для уничтожения структур данных, как того требует DLL. Кроме того, если приложение многопоточная, можно использовать локальное хранилище потоков (TLS) для выделения памяти, которая является частной для каждого потока в функции точки входа. Следующий код является примером функции точки входа DLL.

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

Функция точки входа должна выполнять только простые задачи инициализации и не должна вызывать любые другие функции загрузки или завершения DLL. Например, в функции точки входа не следует напрямую или косвенно вызывать LoadLibrary функцию или LoadLibraryEx функцию. Кроме того, не следует вызывать FreeLibrary функцию, когда процесс завершается.

В многопотоковых приложениях убедитесь, что доступ к глобальным данным DLL синхронизирован (потокобезопасн), чтобы избежать возможного повреждения данных. Для этого используйте TLS для предоставления уникальных данных для каждого потока.

Экспорт функций DLL

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

Чтобы использовать ключевое слово функции, необходимо объявить каждую функцию, которую нужно экспортировать, с помощью следующего ключевого слова:
__declspec(dllexport)

Чтобы использовать экспортируемые функции DLL в приложении, необходимо объявить каждую функцию, которую необходимо импортировать, с помощью следующего ключевого слова: __declspec(dllimport)

Как правило, один файл загона, который имеет определенный и другой, используется для различения выписки по ifdef экспорту и этой import выписки.

Вы также можете использовать файл определения модуля для объявления экспортных функций DLL. При использовании файла определения модуля не нужно добавлять ключевое слово функции в экспортные функции DLL. В файле определения модуля объявляется заявление и LIBRARY EXPORTS утверждение для DLL. Ниже приводится пример файла определения.

Пример DLL и приложения

В Visual C++ 6.0 можно создать библиотеку DLL, выбрав тип проекта библиотеки Dynamic-Link Win32 или тип проекта MFC AppWizard (dll).

Следующий код является примером библиотеки DLL, созданной в Visual C++ с помощью типа проекта win32 Dynamic-Link Library.

Следующий код является примером проекта приложения Win32, который вызывает экспортируемую функцию DLL в DLL SampleDLL.

При динамическом связывание во время загрузки необходимо связать библиотеку импорта SampleDLL.lib, которая создается при сборке проекта SampleDLL.

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

При компиляции и привязке приложения SampleDLL операционная система Windows выполняет поиск DLL SampleDLL в следующих расположениях в следующем порядке:

Системная папка Windows

Функция GetSystemDirectory возвращает путь к системной папке Windows.

Функция GetWindowsDirectory возвращает путь к папке Windows.

Сборка .NET Framework

С появлением .NET и .NET Framework большинство проблем, связанных с DLL, были устранены с помощью сборок. Сборка — это логическая единица функциональности, которая выполняется под управлением clR.NET. Сборка физически существует как DLL-файл или exe-файл. Однако сборка внутри не отличается от DLL Microsoft Win32.

Файл сборки содержит манифест сборки, метаданные типа, код промежуточного языка Майкрософт (MSIL) и другие ресурсы. Манифест сборки содержит метаданные сборки, которые предоставляют все сведения, необходимые для самостоятельного описания сборки. В манифест сборки включены следующие сведения:

  • Имя сборки
  • Сведения о версии
  • Сведения о культуре
  • Сведения о сильном имени
  • Список сборок файлов
  • Справочные сведения о типе
  • Справочные и зависимые сведения о сборке

Код MSIL, содержащийся в сборке, не может выполняться напрямую. Вместо этого управление выполнением кода MSIL управляется с помощью CLR. По умолчанию при создании сборки сборка является частной для приложения. Чтобы создать общую сборку, необходимо назначить сборке сильное имя, а затем опубликовать сборку в глобальном кэше сборок.

В следующем списке описываются некоторые функции сборок по сравнению с функциями библиотек DLL Win32:

При создании сборки все сведения, необходимые clR для запуска сборки, содержатся в манифесте сборки. Манифест сборки содержит список зависимых сборок. Таким образом, CLR может поддерживать согласованный набор сборок, используемых в приложении. В DLL Win32 невозможно поддерживать согласованность между набором DLL, используемых в приложении при использовании общих DLL.

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

Развертывание с использованием одной стороны

Сборки поддерживают развертывание на стороне. Одно приложение может использовать одну версию сборки, а другое приложение может использовать другую версию сборки. Начиная с Windows 2000, при развертывании поддерживается поиск DLL в папке приложения. Кроме того, Windows File Protection предотвращает перезаписи или замену системных DLL несанкционированным агентом.

Самодостатоление и изоляция

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

Сборка запускается с разрешениями безопасности, предоставленными в манифесте сборки и контролируемыми CLR.

Независимый от языка язык

Сборку можно разработать с помощью любого из поддерживаемых языков .NET. Например, можно разработать сборку в Microsoft Visual C#, а затем использовать ее в Visual Basic .NET.

Оцените статью