Новости
GPU в Serverspace: NVIDIA A16
Serverspace Black Friday
MK
Mihail Kuryatnikov
июля 20, 2026
Обновлено августа 1, 2026

Шпаргалка по Windows API: основные функции Win32, команды и сценарии

Шпаргалка по Windows API: основные функции Win32, команды и сценарии

Windows API (Win32) — это фундамент, на котором строятся все приложения для Windows. Если вы пишете код, который взаимодействует с системой на низком уровне, вам нужен быстрый доступ к ключевым функциям: работа с файлами, процессами, памятью и реестром. Эта статья — не общий обзор, а компактный справочник с конкретными сигнатурами, примерами и типичными сценариями использования. Здесь нет лишней теории — только то, что пригодится в ежедневной разработке.

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

Прежде чем переходить к функциям, разберём четыре важных механизма, без которых невозможно правильно работать с Win32.

Дескрипторы (HANDLE) и их закрытие

Большинство функций Win32, открывающих ресурсы (файлы, процессы, ключи реестра), возвращают значение типа HANDLE — это целочисленный дескриптор (непрозрачный идентификатор), который ядро использует для ссылки на объект. Он не является указателем на память и не должен интерпретироваться как адрес. Дескриптор нужно обязательно закрывать с помощью CloseHandle (или специализированной функции, например RegCloseKey), иначе произойдёт утечка ресурсов. Каждый открытый дескриптор потребляет память и может привести к нестабильности системы при долгой работе.

INVALID_HANDLE_VALUE

При ошибке функция CreateFile возвращает не NULL, а специальное значение INVALID_HANDLE_VALUE (определено как (HANDLE)-1). Это важно помнить: проверяйте именно на это значение, а не на NULL.

Коды ошибок и GetLastError

Каждая функция Win32 возвращает своё специальное значение ошибки: это может быть FALSE (0) для функций с типом BOOL, NULL для функций, возвращающих указатели (например, VirtualAlloc, OpenProcess), INVALID_HANDLE_VALUE для CreateFile, или код, отличный от ERROR_SUCCESS для функций реестра. Чтобы получить детальную причину, сразу после неудачного вызова используйте GetLastError(). Код ошибки можно сопоставить с константами из winerror.h (например, ERROR_FILE_NOT_FOUND).

Версии функций: A и W

Многие строковые функции существуют в двух вариантах: с суффиксом A (ANSI, однобайтовая кодировка) и W (широкие символы, UTF-16). В современных проектах рекомендуется использовать W-версии, так как Windows внутренне работает с UTF-16. При использовании A-версий происходит преобразование в кодовую страницу системы (например, Windows-1251), что может исказить нелатинские символы. Убедитесь, что в проекте определены макросы UNICODE и _UNICODE, чтобы по умолчанию вызывались широкие версии.

Ключевые функции Win32: сводная таблица

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

Работа с файлами и каталогами

Функция Детали
CreateFile
Назначение: Открывает или создаёт файл, устройство, канал
Параметры:
lpFileName
dwDesiredAccess
dwShareMode
lpSecurityAttributes
dwCreationDisposition
dwFlagsAndAttributes
hTemplateFile
Возвращает: HANDLE или INVALID_HANDLE_VALUE
Сценарий: Открыть файл для чтения/записи
ReadFile
Назначение: Читает данные из файла или устройства
Параметры:
hFile
lpBuffer
nNumberOfBytesToRead
lpNumberOfBytesRead
lpOverlapped
Возвращает: BOOL (ненулевое при успехе)
Сценарий: Прочитать содержимое файла в буфер
WriteFile
Назначение: Записывает данные в файл или устройство
Параметры:
hFile
lpBuffer
nNumberOfBytesToWrite
lpNumberOfBytesWritten
lpOverlapped
Возвращает: BOOL
Сценарий: Сохранить данные в файл
CloseHandle
Назначение: Закрывает любой дескриптор
Параметры:
hObject
Возвращает: BOOL
Сценарий: Освободить ресурс после работы

Управление процессами

Функция Детали
CreateProcess
Назначение: Запускает новый процесс
Параметры:
lpApplicationName
lpCommandLine
lpProcessAttributes
lpThreadAttributes
bInheritHandles
dwCreationFlags
lpEnvironment
lpCurrentDirectory
lpStartupInfo
lpProcessInformation
Возвращает: BOOL
Сценарий: Запустить внешнее приложение (например, калькулятор)
OpenProcess
Назначение: Открывает существующий процесс по PID
Параметры:
dwDesiredAccess
bInheritHandle
dwProcessId
Возвращает: HANDLE или NULL
Сценарий: Получить доступ к памяти другого процесса
TerminateProcess
Назначение: Принудительно завершает процесс
Параметры:
hProcess
uExitCode
Возвращает: BOOL
Сценарий: Аварийно остановить процесс (используйте с осторожностью)

Управление памятью

Функция Детали
VirtualAlloc
Назначение: Резервирует или фиксирует память в виртуальном адресном пространстве
Параметры:
lpAddress
dwSize
flAllocationType
flProtect
Возвращает: LPVOID или NULL
Сценарий: Выделить буфер для чтения больших файлов
VirtualFree
Назначение: Освобождает память
Параметры:
lpAddress
dwSize
dwFreeType
Возвращает: BOOL
Сценарий: Освободить выделенный участок
ReadProcessMemory
Назначение: Читает память другого процесса
Параметры:
hProcess
lpBaseAddress
lpBuffer
nSize
lpNumberOfBytesRead
Возвращает: BOOL
Сценарий: Отладка или мониторинг

Работа с реестром

Функция Детали
RegOpenKeyEx
Назначение: Открывает существующий раздел реестра
Параметры:
hKey
lpSubKey
ulOptions
samDesired
phkResult
Возвращает: LONG (ERROR_SUCCESS при успехе)
Сценарий: Открыть ключ для чтения настроек
RegQueryValueEx
Назначение: Получает значение из открытого раздела
Параметры:
hKey
lpValueName
lpReserved
lpType
lpData
lpcbData
Возвращает: LONG
Сценарий: Прочитать строковое или DWORD-значение
RegSetValueEx
Назначение: Записывает значение в раздел
Параметры:
hKey
lpValueName
Reserved
dwType
lpData
cbData
Возвращает: LONG
Сценарий: Сохранить настройки приложения
RegCloseKey
Назначение: Закрывает дескриптор раздела
Параметры:
hKey
Возвращает: LONG
Сценарий: Закрыть ключ после работы

Примитивы синхронизации

Функция Детали
CreateMutex
Назначение: Создаёт или открывает именованный мьютекс
Параметры:
lpMutexAttributes
bInitialOwner
lpName
Возвращает: HANDLE или NULL
Сценарий: Обеспечить одиночный запуск приложения
WaitForSingleObject
Назначение: Ожидает сигнального состояния объекта
Параметры:
hHandle
dwMilliseconds
Возвращает: DWORD (WAIT_OBJECT_0 и др.)
Сценарий: Ожидать завершения потока или освобождения мьютекса

Практические примеры кода

Чтение файла с обработкой ошибок

#include <windows.h>
#include <stdio.h>

int main() {
    HANDLE hFile = CreateFileW(
        L"example.txt",
        GENERIC_READ,
        FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    );

    if (hFile == INVALID_HANDLE_VALUE) {
        DWORD err = GetLastError();
        printf("Не удалось открыть файл, ошибка: %lu\n", err);
        return 1;
    }

    char buffer[1024];
    DWORD bytesRead;
    if (!ReadFile(hFile, buffer, sizeof(buffer) - 1, &bytesRead, NULL)) {
        DWORD err = GetLastError();
        printf("Ошибка чтения: %lu\n", err);
        CloseHandle(hFile);
        return 1;
    }

    buffer[bytesRead] = '\0';
    printf("Содержимое: %s\n", buffer);

    CloseHandle(hFile);
    return 0;
}

Запуск процесса (калькулятор) и ожидание его завершения

STARTUPINFOW si = { sizeof(si) };
PROCESS_INFORMATION pi;
if (CreateProcessW(
        L"C:\\Windows\\System32\\calc.exe",
        NULL, NULL, NULL, FALSE,
        0, NULL, NULL, &si, &pi)) {
    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
} else {
    printf("Ошибка запуска: %lu\n", GetLastError());
}

Чтение значения из реестра

HKEY hKey;
LONG result = RegOpenKeyExW(
    HKEY_LOCAL_MACHINE,
    L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion",
    0, KEY_READ, &hKey);

if (result == ERROR_SUCCESS) {
    WCHAR buffer[256];
    // Внимание: размер буфера передаётся в байтах, а не в символах.
    // Для WCHAR-массива sizeof(buffer) даёт общий размер в байтах,
    // что корректно для RegQueryValueExW.
    DWORD bufferSize = sizeof(buffer);
    DWORD type;
    if (RegQueryValueExW(hKey, L"ProductName", NULL, &type,
                         (LPBYTE)buffer, &bufferSize) == ERROR_SUCCESS) {
        wprintf(L"Имя продукта: %s\n", buffer);
    }
    RegCloseKey(hKey);
} else {
    printf("Не удалось открыть ключ, код: %ld\n", result);
}

Частые ошибки и как их избежать (кратко)

  • Забыли закрыть дескриптор — всегда используйте CloseHandle или RegCloseKey в паре с открытием.
  • Проверка на NULL вместо INVALID_HANDLE_VALUE — для CreateFile проверяйте именно на INVALID_HANDLE_VALUE.
  • Игнорирование кодов ошибок — вызывайте GetLastError() сразу после неудачного вызова.
  • Смешивание ANSI и Unicode — используйте W-версии функций и определите UNICODE.
  • Неправильный размер буфера — всегда передавайте актуальный размер и проверяйте, сколько байт записано.

Часто задаваемые вопросы (FAQ)

Что такое Windows API (Win32)?

Windows API (Win32) — это набор системных функций, с помощью которых приложения взаимодействуют с операционной системой Windows. Он предоставляет доступ к работе с файлами, памятью, процессами, потоками, реестром, окнами и другими возможностями ОС.

Когда стоит использовать Win32 API вместо готовых библиотек?

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

Почему важно закрывать дескрипторы после работы?

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

В чем разница между ANSI- и Unicode-функциями Win32?

Большинство функций Win32 существуют в двух версиях: ANSI (A) и Unicode (W). Современные приложения рекомендуется разрабатывать с использованием Unicode-версий, поскольку Windows внутренне работает с кодировкой UTF-16, что обеспечивает корректную обработку символов любых языков.

Как правильно обрабатывать ошибки функций Win32?

После неудачного вызова функции необходимо сразу проверить её возвращаемое значение и получить код ошибки с помощью GetLastError(). Это позволяет определить точную причину сбоя и корректно обработать исключительную ситуацию в приложении.

Для каких задач чаще всего используют Win32 API?

Win32 API применяется для работы с файловой системой, запуска и управления процессами, выделения памяти, взаимодействия с реестром Windows, синхронизации потоков, создания системных утилит, служб Windows и других приложений, которым необходим прямой доступ к возможностям операционной системы.

Заключение

Этот справочник покрывает основные функции Win32, которые понадобятся в большинстве прикладных задач. Освоив чтение файлов, запуск процессов, работу с реестром и базовую синхронизацию, вы сможете создавать надёжные системные утилиты и тонко настраивать поведение приложений. Для углублённого изучения обращайтесь к официальной документации Microsoft Learn — там вы найдёте полные списки параметров и дополнительные примеры.

Если вы тестируете Win32-приложения, которые требуют изолированного окружения, удобно использовать выделенный сервер — например, VPS от Serverspace. На нём можно развернуть чистую Windows, проводить эксперименты с дескрипторами и памятью, не боясь нарушить стабильность основной рабочей станции.

Вам также может быть интересно...