Что нового

Как зарегистрировать функцию не используя GUIRegisterMsg

Статус
Закрыто для дальнейших ответов.

---Zak---

Скриптер
Сообщения
445
Репутация
116
Добрый день.

Вопрос скорее литорический...

В общем есть небольшая программа, которая висит в диспетчере и если не запущен некий файл, то запускает его (сделано специально, чтобы через диспетчер задач не завершали).

Обзовем это так:
1. сервер - файл, который следит за запуском другого файла
2. клиент - файл, который должен постоянно быть запущенным

Но есть небольшая проблема - при завершении работы Windows сначало завершается "клиент", ну и соответственно "сервер" проявляет весь свой функционал и запускает "клиента"... Все пишется в лог файл. Как итог за секунду "клиент" не один раз был запущен.

Почитал тему - http://autoit-script.ru/index.php?topic=4304.0

Но суть в том, что пусть даже и невидимый GUI создается, чтобы зарегистрировать функцию... НО (!) возможно ли обойтись без него ?

Код:
OnAutoItExitRegister()

Данная функция не подойдет, т.к. по сути должно отловится именно завершение работы ОС.
PS: идея в том, чтобы при завершении ОС "клиент" останавливал "сервер". А если остановить вручную клиент - значит остановится и сервер.

Пример:
Код:
#Include <GUIConstantsEx.au3>

_WinAPI_SetProcessShutdownParameters(0x03FF)

GUIRegisterMsg(0x0011, 'WM_QUERYENDSESSION')

While 1
	Sleep(100)
WEnd

Func WM_QUERYENDSESSION($hWnd, $Msg, $wParam, $lParam)
	IniWrite(@ScriptDir & "/myfile.ini", "section2", "key", "this is a new value")
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_QUERYENDSESSION

Func _WinAPI_SetProcessShutdownParameters($iLevel, $iFlag = 0)
    Local $Ret = DllCall('kernel32.dll', 'int', 'SetProcessShutdownParameters', 'dword', $iLevel, 'dword', $iFlag)
    If (@error) Or (Not $Ret[0]) Then
        Return SetError(1, 0, 0)
    EndIf
    Return 1
EndFunc   ;==>_WinAPI_SetProcessShutdownParameters


Код:
IniWrite(@ScriptDir & "/myfile.ini", "section2", "key", "this is a new value")

Данная строка не отработает, т.к. ГУИ то не было...
 

MnM

Post-Hardcore
Сообщения
679
Репутация
90
---Zak--- сказал(а):
Данная строка не отработает, т.к. ГУИ то не было...
Так может быть создать пустое окно которое вы не будете показывать(@sw_show) по принципу элемента "пустышка"
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
---Zak---
В функции OnAutoItExitRegister проверяйте значение макроса @ExitMethod
3 Завершение работы скрипта в связи с выходом пользователя из системы (user logoff).
4 Выход в связи с завершением работы Windows.
 

firex

AutoIT Гуру
Сообщения
943
Репутация
206
---Zak---
Пускай сервер перехватывает завершение работы и "правильно" завершает клиент.

http://autoit-script.ru/index.php?topic=4304.msg31078#msg31078
 

sims

Осваивающий
Сообщения
184
Репутация
24
---Zak--- [?]
сделано специально, чтобы через диспетчер задач не завершали
Не лучше запретить закрывать через диспетчер задач?

Удалено.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,716
---Zak---, любое приложение должно иметь окно (GUI), в противном случае оно является консольным (CUI). Любая программа написанная на AutoIt содержит по крайней мере одно скрытое окно, если при компиляции не выбран режим CUI. Поэтому использование собственных скрытых окон для получения WM-сообщений является нормальной практикой.

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

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

Код:
Func _ScriptProtect()

	If (IsAdmin()) Or (Not @Compiled) Then
		Return 0
	EndIf

	Local $hProcess = _WinAPI_GetCurrentProcess()
	Local $tACL = DllStructCreate('byte AclRevision;byte Sbz1;ushort AclSize;ushort AceCount;ushort Sbz2')
	Local $pACL = DllStructGetPtr($tACL)
	Local $tSD = DllStructCreate('byte[20]')
	Local $pSD = DllStructGetPtr($tSD)
	Local $Ret

	$Ret = DllCall('advapi32.dll', 'int', 'InitializeSecurityDescriptor', 'ptr', $pSD, 'dword', 1)
	If (@Error) Or (Not $Ret[0]) Then
		Return 0
	EndIf
	$Ret = DllCall('advapi32.dll', 'int', 'InitializeAcl', 'ptr', $pACL, 'dword', DllStructGetSize($tACL), 'dword', 2)
	If (@Error) Or (Not $Ret[0]) Then
		Return 0
	EndIf
	$Ret = DllCall('advapi32.dll', 'int', 'SetSecurityDescriptorDacl', 'ptr', $pSD, 'int', 1, 'ptr', $pACL, 'int', 0)
	If (@Error) Or (Not $Ret[0]) Then
		Return 0
	EndIf
	$Ret = DllCall('advapi32.dll', 'int', 'SetKernelObjectSecurity', 'ptr', $hProcess, 'dword', 0x04, 'ptr', $pSD)
	If (@Error) Or (Not $Ret[0]) Then
		Return 0
	EndIf
	Return 1
EndFunc   ;==>_ScriptProtect

sims, у нас на форуме не обсуждаются вопросы, которые потенциально могут способствовать написанию вредоносного ПО.

Тема закрыта.
 
Статус
Закрыто для дальнейших ответов.
Верх