← На главную

Автозапуск программы на чистом Windows API

Конечно же, вы видели множество программ, запускающихся автоматически во время загрузки системы. В Windows есть немало способов добавить программу в автозагрузку. Сегодня мы рассмотрим наиболее простой и популярный способ, который заключается в добавлении специальной записи в реестр. Разумеется, как и ранее, мы будем писать программу на Си и Windows API.

Для решения задачи нам понадобятся следующие процедуры.

GetModuleFileName(hModule, szFileName, dwChars);

GetModuleFileName записывает в буфер szFileName полный путь до файла, содержащего заданный модуль, загруженный текущим процессом. Если hModule == NULL, возвращается полный путь до исполняемого файла текущего процесса. Аргумент dwChars должен быть равен размеру буфера в TCHAR’ах. В случае ошибки процедура возвращает ноль, в случае успеха – значение, отличное от нуля.

GetWindowsDirectory(szWinPath, dwChars);

GetWindowsDirectory записывает в буфер szWinPath путь до каталога Windows, который «C:\WINDOWS», «Z:\WINNT» и так далее. Аргумент dwChars должен быть равен размеру буфера в TCHAR’ах. В случае ошибки процедура возвращает ноль, в случае успеха – значение, отличное от нуля.

CopyFile(szFrom, szTo, bFailIfExists);

Процедура CopyFile копирует файл szFrom в szTo. Если файл с именем szTo уже существует, то процедура перезаписывает его в случае, если bFailIfExists == FALSE, и завершается с ошибкой иначе. В случае ошибки возвращается ноль, в случае успеха – значение, отличное от нуля.

RegOpenKey(HKEY_LOCAL_MACHINE, szSubKey, &hKey);

RegOpenKey открывает заданный ключ реестра и записывает хэндл открытого ключа в hKey. Первый аргумент – это либо хэндл открытого или созданного ранее ключа, либо одно из предопределенных значений, например, HKEY_USERS, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE и так далее. В аргументе szSubKey передается имя ключа, который требуется открыть. Это должен быть подключ ключа, переданного первым аргументом. В случае успеха процедура возвращает ERROR_SUCCESS. В случае ошибки возвращается одно из значений, определенных в Winerror.h. В отличие от процедур, с которыми мы работали до этого момента, RegOpenKey никак не связана с GetLastError.

RegSetValueEx(hKey, szName, 0, REG_SZ, (PBYTE)szValue, dwSizeInBytes);

Процедура RegSetValueEx устанавливает значение, а также тип, заданного ключа реестра и принимает следующие аргументы. Слева направо – хэндл ключа реестра, имя устанавливаемого значения, зарезервированный аргумент, тип устанавливаемого значения, указатель на значение, размер значения в байтах, включая завершающий ноль для строк. С возвращаемыми значениями все обстоит так же, как и в случае с RegOpenKey.

RegCloseKey(hKey);

RegCloseKey закрывает хэндл, соотвествующий ключу реестра. Возвращаемые значения – как у RegOpenKey и RegSetValueEx. Помимо названных процедур для работы с реестром существует великое множество других, но они устроены аналогично и в рамках данной заметки нам не понадобятся.

А теперь – решение:

#include <windows.h> #define STRLEN(x) (sizeof(x)/sizeof(TCHAR) - 1) BOOL SelfAutorun() { HKEY hKey = NULL; LONG lResult = 0; TCHAR szExeName[MAX_PATH+1]; TCHAR szWinPath[MAX_PATH+1]; GetModuleFileName(NULL, szExeName, STRLEN(szExeName)); GetWindowsDirectory(szWinPath, STRLEN(szWinPath)); lstrcat(szWinPath, L"\\Autorun.exe"); if(0 == CopyFile(szExeName, szWinPath, FALSE)) { return FALSE; } lResult = RegOpenKey( HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\Windows\\CurrentVersion\\Run", &hKey); if(ERROR_SUCCESS != lResult) { return FALSE; } RegSetValueEx(hKey, L"Autorun", 0, REG_SZ, (PBYTE)szWinPath, lstrlen(szWinPath)*sizeof(TCHAR) + 1); RegCloseKey(hKey); return TRUE; } INT main() { SelfAutorun(); MessageBox(NULL, L"Hello!", L"Autorun", 0); ExitProcess(0); }

Если теперь скомпилировать и запустить программу, она будет запускаться при каждой загрузке Windows. При этом в каталоге C:\WINDOWS появится файл Autorun.exe, а через regedit.exe будет видна соответствующая запись в реестре. Разумеется, все это будет работать, только если вы сидите под админом. Простой пользователь не имеет прав на запись в C:\WINDOWS, а также в ветвь реестра HKLM. Однако ничто не мешает положить программу в любой другой каталог и воспользоваться ветвью реестра HKCU.

В качестве домашнего задания можете погуглить на предмет существования других способов добавления программ в автозагрузку, желательно, через реестр, и автоматизировать один из этих способов.

Дополнение: Пример простейшей многопоточной программы на WinAPI