- Вызов функций Windows API
- Вызов функций Windows API, имеющих выходной строковый параметр char*
- Изменение типа, применяемого для маршалинга по умолчанию
- Вызов функций, требующих struct
- Работа с функциями обратного вызова в C#
- Создание собственной управляемой библиотеки
- Примеры использования функций API
- Заключение
- Как включить или отключить дополнительные функции Windows
- Обновление за апрель 2021 года:
- Изучите функции Windows с помощью командной строки.
- Просмотр, добавление или удаление функций Windows из PowerShell
- Использование внешнего источника установки
Вызов функций Windows API
Из книги C#. Советы программистам (в сокращении)
Программный код, который выполняется под управлением CLR (Common Language Runtime, т. е. общая среда выполнения языков), называется управляемым (managed) кодом. Программный код, выполняющийся вне среды выполнения CLR, называется неуправляемым (unmanaged) кодом. Примером неуправляемого программного кода служат функции Win32 API, компоненты COM, интерфейсы ActiveX. Несмотря на большое количество классов .NET Framework, содержащих множество методов, программисту все равно приходится иногда прибегать к неуправляемому коду. Надо сказать, что число вызовов неуправляемого кода уменьшается с выходом каждой новой версии .NET Framework. Microsoft надеется, что наступит такое время, когда весь код можно будет сделать управляемым и безопасным. Но пока реальность такова, что без вызовов функций Windows API нам пока не обойтись. Но сначала немного теории.
Управляемый код .NET Framework может вызывать неуправляемую функцию из DLL (функцию Windows API) при помощи специального механизма Platform Invoke (сокр. P/Invoke). Для того чтобы обратиться к какой-нибудь неуправлямойнеуправляемой библиотеке DLL, вы должны преобразовать .NET-объекты в наборы struct, char* и указателей на функции, как того требует язык C. Как сказали бы программисты на своем жаргоне — вам нужно маршалировать параметры. Более подробно о маршалинге (Marshalling) вам следует почитать в документации. Чтобы вызвать DLL-функцию из C#, сначала ее необходимо объявить (программисты, имеющие опыт работы с Visual Basic 6.0, уже знакомы с этим способом). Для этого используется атрибут DllImport:
Иногда в примерах вы можете также встретить такой способ (длинный и неудобный): [System.Runtime.InteropServices.DllImport(«User32.Dll»)]. , но это на любителя.
Атрибут DllImport сообщает компилятору, где находится точка входа, что позволяет далее вызывать функцию из нужного места. Вы должны всегда использовать тип IntPtr для HWND, HMENU и любых других описателей. Для LPCTSTR используйте String, а сервисы взаимодействия (interop services) выполнят автоматический маршаллинг System.String в LPCTSTR до передачи в Windows. Компилятор ищет указанную выше функцию SetWindowText в файле User32.dll и перед ее вызовом автоматически преобразует вашу строку в LPTSTR (TCHAR*). Почему это происходит? Для каждого типа в C# определен свой тип, используемый при маршалинге по умолчанию (default marshaling type) . Для строк это LPTSTR.
Вызов функций Windows API, имеющих выходной строковый параметр char*
Предположим, нам необходимо вызвать функцию GetWindowText, у которой имеется строковый выходной параметр char*. По умолчанию, для строк используется LPTSTR, но если мы будем использовать System.String, как было сказано выше, то ничего не произойдет, так как класс System.String не позволяет модифицировать строку. Вам необходимо использовать класс StringBuilder, который позволяет изменять строки.
Тип, используемый для маршашлинга StringBuilder по умолчанию, — тоже LPTSTR, зато теперь GetWindowText может модифицировать саму вашу строку:
Таким образом, ответом на вопрос, как вызывать функцию, у которой есть выходной строковый параметр, будет — используйте класс StringBuilder.
Изменение типа, применяемого для маршалинга по умолчанию
Например, мы хотим вызвать функцию GetClassName, который принимает параметр LPSTR (char*) даже в Unicode-версиях. Если вы передадите строку, общеязыковая исполняющая среда (CLR) преобразует ее в серию TCHAR. Но с помощью атрибута MarshalAs можно переопределить то, что предлагается по умолчанию:
Теперь, когда вы вызовете GetClassName, .NET передаст вашу строку в виде символов ANSI, а не «широких символов».
Вызов функций, требующих struct
Возьмем для примера функцию GetWindowRect, которая записывает в структуру RECT экранные координаты окна. Чтобы вызвать функцию GetWindowRect и передать ей структуру RECT нужно использовать тип struct в сочетании с атрибутом StructLayout:
Важно использовать ref, чтобы CLR передала параметр типа RECT как ссылку. В этом случае функция сможет модифицировать ваш объект, а не его безымянную копию в стеке. После такого объявления функции можно ее вызвать в коде:
Обратите внимание, что ref используется и в объявлении, и при вызове функции. Тип, по умолчанию применяемый для маршалинга типов struct — по умолчанию LPStruct, поэтому необходимости в атрибуте MarshalAs нет. Но если вы хотите использовать RECT в виде класса, а не struct, вам необходимо реализовать оболочку:
Работа с функциями обратного вызова в C#
Для использования функций, написанных на C#, в качестве функций обратного вызова Windows, нужно использовать делегаты (delegate).
Объявив свой тип делегата, можно написать оболочку для функции Windows API:
Так как в строке с delegate просто объявляется тип делегата (delegate type), сам делегат нужно предоставить в классе:
а затем передать оболочке:
Проницательные читатели заметят, что я умолчал о проблеме с lparam.
В языке C, если в EnumWindows дается LPARAM, Windows будет уведомлять вашу функцию обратного вызова этим LPARAM. Обычно lparam — указатель на некую структуру или класс, который содержит контекстную информацию, нужную вам для выполнения своих операций. Но запомните: в .NET слово «указатель» произносить нельзя! Так что же делать? Можно объявить ваш lparam как IntPtr и использовать GCHandle в качестве его оболочки:
Не забудьте вызвать Free, когда закончите свои дела! Иногда в C# приходится самому освобождать память. Чтобы получить доступ к «указателю» lparam внутри перечислителя, используйте GCHandle.Target.
Ниже показан написанный мной класс, который инкапсулирует EnumWindows в массив. Вместо того чтобы возиться со всеми этими делегатами и обратными вызовами, вы пишете:
Небольшая программа ListWin (Приложение ListWin.cs), которую я написал для перечисления окон верхнего уровня, позволяет просматривать списки HWND, имен классов, заголовков и/или прямоугольников окон, используя RECT или Rectangle. Исходный код ListWin показан не полностью; весь исходный код можно скачать по ссылке, приведенной в конце статьи.
Создание собственной управляемой библиотеки
Можно создать собственную управляемую библиотеку, из которой можно будет вызывать функции Windows API. Для этого в Visual Studio предусмотрены специальные опции. Новый проект создается как библиотека классов (Class Library). Сборка при этом автоматически получает расширение dll. Использовать управляемую библиотеку в управляемом коде просто. Для этого надо добавить ссылку (используя меню Project | Add Reference…) на библиотечную сборку, указав месторасположение сборки в соответствующем диалоговом окне. После этого Visual Studio копирует сборку в директорию, в которой располагается разрабатываемый код. Далее в коде программы используется либо оператор using, либо полное имя библиотечного модуля с точечной нотацией. Все библиотечные классы и методы готовы к использованию в коде программы.
Также можно воспользоваться командной строкой. Чтобы скомпилировать класс Win32API.cs, введите:
В результате у вас будет создан файл Win32API.dll, доступный для любого проекта на C#.
Пример создания библиотеки и использования функций Windows API находится в папке Win32 на прилагаемом к книге диске.
Примеры использования функций API
Вкратце ознакомившись с теорией, перейдем к конкретным примерам. В предыдущих главах я уже неоднократно приводил пример использования функций Windows API для решения различных проблем. Рассмотрим еще несколько полезных советов, которые не вошли в другие главы.
- Блокировка компьютера — Если вам необходимо блокировать компьютер, то вызовите функцию LockWorkStation. Результат работы примера будет аналогичен нажатию комбинации клавиш Win+L или клавиш Ctrl+Alt+Del с последующим выбором кнопки (или команды меню) Блокировка.
- Является ли текущий пользователь администратором? — Если необходимо удостовериться, что текущий пользователь имеет права администратора, то можно вызвать функцию IsUserAnAdmin.
- Мигание заголовка формы — Наверное, вам приходилось видеть, что заголовок окна вдруг начинал мигать, привлекая ваше внимание. Подобный эффект реализуется вызовом функций FlashWindow или FlashWindowsEx.
- Форматирование дисков — Чтобы вызвать стандартное диалоговое окно форматирования дисков нужно воспользоваться функцией SHFormatDrive
- Открытие и закрытие лотка привода компакт-дисков — Наверное, при работе с утилитами, прожигающими компакт-диски CD-R и CD-RW, вы замечали, что у них имеется возможность извлекать компакт-диск из привода программным путем. Неплохо бы научиться делать то же самое при помощи C#. Для этого используем функцию mciSendString в связке с специальными командами, которые и позволят нам открывать и закрывать лоток привода компакт-дисков
- Создание собственного пункта в системном меню — У большинства окон в Windows имеется так называемое системное меню. Внешний вид, как правило, у всех меню одинаков, но иногда попадаются программы, у которых в системном меню имеются свои собственные пункты. Естественно, любого программиста разбирает любопытство — а как реализовать эту функциональность в своей программе. На данный момент .NET Framework не предоставляет такого полезного свойства как Form.SystemMenu или что-то в этом роде. Поэтому придется прибегать к помощи механизма P/Invoke для вызовов функций Windows API. Опытные программисты (особенно имеющие опыт работы с языком С++) знают, что для модификации системного меню используется функция GetSystemMenu, а также вспомогательная функция AppendMenu, которая позволяет добавлять в меню разделители, картинки, галочки и сам текст.
- Извлечение значков из файлов — Функция ExtractIcon позволяет извлекать значки из ресурсов, которые зашиты в файлах EXE, DLL, CPL и др. Кроме того, функция позволяет подсчитать количество значков, находящихся в файле. В качестве испытуемого файла возьмем динамическую библиотеку shell32.dll, которая имеется в любой версии Windows.
- Вызов диалогового окна Смена значка — Существует такая функция Windows API как PickIconDlg. Долгое время она была официально не документирована, но, начиная, с Windows 2000 компания Microsoft все-таки выложила описание этой функции на сайте MSDN. Функция PickIconDlg вызывает стандартное диалоговое окно «Смена значка», позволяющее выбрать значок из модуля. Тем самым, мы можем предоставить пользователю возможность самому выбирать нужный значок, после чего и вывести его на форму (или произвести другие операции).
- Панель задач, кнопка Пуск и часы в области уведомлений — Очень часто программисты хотят получить доступ к стандартным элементам интерфейса Рабочего стола Windows. Например, разработчики хотят получить координаты панели задач, программно нажать на кнопку Пуск, спрятать и показать эту кнопку Пуск и многое другое.
- Смена обоев Рабочего стола — Если вы хотите периодически менять картинку на своем Рабочем столе, то можете это сделать программным способом прямо из своего приложения. Для смены обоев Рабочего стола вызывается одна функция Windows API SystemParametersInfo.
Заключение
Несмотря на огромное число имеющихся классов .NET Framework, программисту по-прежнему приходится прибегать к вызовам системных функций Windows API. В папке Win32Help на прилагаемом к книге компакт-диске вы найдете демо-версию справочника по функциям Windows API для .NET Framework. Если вам понравится этот справочник, то вы можете приобрести его полную версию на моем сайте.
Как включить или отключить дополнительные функции Windows
Операционная система Windows поставляется с множеством надстроек и компонентов, которые могут расширять функциональность Windows без использования стороннего программного обеспечения. Некоторые из этих компонентов включены или установлены по умолчанию. Но не все из них должны быть включены, потому что они влияют на производительность вашего компьютера. Кроме того, не всем пользователям необходимо включить все эти функции. Некоторые компоненты также требуются сторонним программным обеспечением для правильной работы, например: .NET Framework 3.5.
Итак, что мы должны включать и выключать? Мы собрали список некоторых функций, доступных в Windows 10 Professional, поскольку для большинства наиболее интересных функций, таких как сервер виртуализации Hyper-V, требуется Windows 10 Professional. Если вы используете Windows 10 Home Edition, у вас есть только некоторые из этих функций. Если вы используете Windows 10 Enterprise или Education, у вас будет еще больше возможностей. Это лишь некоторые из наиболее распространенных характеристик, с которыми вы можете столкнуться.
- NET Framework 3.5 (включает в себя .NET 2.0 и 3.0): вам понадобится эта установка для запуска приложений, написанных для этих версий .NET. Windows автоматически устанавливает их, когда они нужны приложению.
- NET Framework 4.6 Advanced Services: Эти функции также устанавливаются автоматически при необходимости. Они нужны только для запуска приложений, которые в них нуждаются.
- Службы Active Directory облегченного доступа к каталогам: это обеспечивает сервер LDAP (облегченный протокол доступа к каталогам). Он работает как служба Windows и предоставляет каталог для аутентификации пользователей в сети. Это легкая альтернатива полноценному серверу Active Directory и будет полезна только в некоторых корпоративных сетях.
- Embedded Shell Launcher: эта функция необходима, если вы хотите заменить оболочку Windows 10 Explorer.exe пользовательской оболочкой. Документация Microsoft рекомендует использовать эту функцию для настройки традиционного приложения Windows в режиме киоска.
Обновление за апрель 2021 года:
Теперь мы рекомендуем использовать этот инструмент для вашей ошибки. Кроме того, этот инструмент исправляет распространенные компьютерные ошибки, защищает вас от потери файлов, вредоносных программ, сбоев оборудования и оптимизирует ваш компьютер для максимальной производительности. Вы можете быстро исправить проблемы с вашим ПК и предотвратить появление других программ с этим программным обеспечением:
- Шаг 1: Скачать PC Repair & Optimizer Tool (Windows 10, 8, 7, XP, Vista — Microsoft Gold Certified).
- Шаг 2: Нажмите «Начать сканирование”, Чтобы найти проблемы реестра Windows, которые могут вызывать проблемы с ПК.
- Шаг 3: Нажмите «Починить все», Чтобы исправить все проблемы.
Для просмотра, включения и отключения дополнительных функций Windows
Изучите функции Windows с помощью командной строки.
Чтобы получить список функций Windows в командной строке, выполните следующие действия:
Откройте командную строку в режиме администратора.
Введите следующую команду
DISM / онлайн / получить-особенности / формат: таблица | Больше
Он отображает все включенные или отключенные функции на вашем компьютере. Здесь формат: таблица и другие не являются обязательными и используются для улучшения читаемости функций.
Просмотр, добавление или удаление функций Windows из PowerShell
PowerShell — это язык сценариев Microsoft, основанный на платформе .NET. Он в основном используется для управления и настройки локальных и удаленных систем, и вы также можете использовать его для той же задачи просмотра, добавления или удаления дополнительных функций Windows. Инструмент DISM можно использовать непосредственно в Powershell, но есть также набор интегрированных команд, которые работают аналогичным образом.
Использование внешнего источника установки
Вы также можете получить новейшие функции из обновленного автономного источника.
Этот источник может быть ISO или другим типом изображения, или просто папкой.
Все, что вам нужно сделать, это решить, хотите ли вы использовать командную строку или Windows Powershell.
Если вы используете командную строку, введите эту команду,
Dism.exe / online / enable-feature / enable-feature / enable-feature / featurename: Управление дополнительными функциями с панели управления
Хотя Windows 10 включает приложение «Настройки», вам все равно нужно использовать панель управления для управления дополнительными функциями на вашем компьютере. Если вы хотите создать виртуальные машины Hyper-V, используйте Internet Information Services (IIS) для настройки FTP-сервера или добавьте инструмент командной строки Linux Bash.
Далее описывается, как включать и отключать дополнительные функции в Windows 10 из панели управления:
- Откройте панель управления.
- Нажмите на Программы.
- Нажмите на ссылку Включить или отключить функции Windows.
- В Windows Functions отметьте или отмените выбор нужной функции.
- Нажмите OK, чтобы включить или отключить функцию.
- Перезагрузите компьютер, как указано в мастере.
CCNA, веб-разработчик, ПК для устранения неполадок
Я компьютерный энтузиаст и практикующий ИТ-специалист. У меня за плечами многолетний опыт работы в области компьютерного программирования, устранения неисправностей и ремонта оборудования. Я специализируюсь на веб-разработке и дизайне баз данных. У меня также есть сертификат CCNA для проектирования сетей и устранения неполадок.